乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      真不是吹,Spring 里這款牛逼的網(wǎng)絡(luò)工具庫你可能沒用過!

       昵稱10087950 2022-06-16 發(fā)布于江蘇

      一、簡介

      現(xiàn)如今的 IT 項(xiàng)目,由服務(wù)端向外發(fā)起網(wǎng)絡(luò)請(qǐng)求的場景,基本上處處可見!

      傳統(tǒng)情況下,在服務(wù)端代碼里訪問 http 服務(wù)時(shí),我們一般會(huì)使用 JDK 的 HttpURLConnection 或者 Apache 的 HttpClient,不過這種方法使用起來太過繁瑣,而且 api 使用起來非常的復(fù)雜,還得操心資源回收。

      以下載文件為例,通過 Apache 的 HttpClient方式進(jìn)行下載文件,下面這個(gè)是我之前封裝的代碼邏輯,看看有多復(fù)雜!

      圖片

      其實(shí)Spring已經(jīng)為我們提供了一種簡單便捷的模板類來進(jìn)行操作,它就是RestTemplate。

      RestTemplate是一個(gè)執(zhí)行HTTP請(qǐng)求的同步阻塞式工具類,它僅僅只是在 HTTP 客戶端庫(例如 JDK HttpURLConnection,Apache HttpComponents,okHttp 等)基礎(chǔ)上,封裝了更加簡單易用的模板方法 API,方便程序員利用已提供的模板方法發(fā)起網(wǎng)絡(luò)請(qǐng)求和處理,能很大程度上提升我們的開發(fā)效率。

      好了,不多 BB 了,代碼擼起來!

      二、環(huán)境配置

      2.1、非 Spring 環(huán)境下使用 RestTemplate

      如果當(dāng)前項(xiàng)目不是Spring項(xiàng)目,加入spring-web包,即可引入RestTemplate

      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.2.6.RELEASE</version>
      </dependency>

      編寫一個(gè)單元測試類,使用RestTemplate發(fā)送一個(gè)GET請(qǐng)求,看看程序運(yùn)行是否正常

      @Test
      public void simpleTest() {
          RestTemplate restTemplate = new RestTemplate();
          String url = "http://jsonplaceholder./posts/1";
          String str = restTemplate.getForObject(url, String.class);
          System.out.println(str);
      }

      2.2、Spring 環(huán)境下使用 RestTemplate

      如果當(dāng)前項(xiàng)目是SpringBoot,添加如下依賴接口!

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>

      同時(shí),將RestTemplate配置初始化為一個(gè)Bean。

      @Configuration
      public class RestTemplateConfig {

          /**
           * 沒有實(shí)例化RestTemplate時(shí),初始化RestTemplate
           * @return
           */

          @ConditionalOnMissingBean(RestTemplate.class)
          @Bean
          public RestTemplate restTemplate()
      {
              RestTemplate restTemplate = new RestTemplate();
              return restTemplate;
          }
      }

      注意,這種初始化方法,是使用了JDK自帶的HttpURLConnection作為底層HTTP客戶端實(shí)現(xiàn)。

      當(dāng)然,我們還可以修改RestTemplate默認(rèn)的客戶端,例如將其改成HttpClient客戶端,方式如下:

      @Configuration
      public class RestTemplateConfig {


          /**
           * 沒有實(shí)例化RestTemplate時(shí),初始化RestTemplate
           * @return
           */

          @ConditionalOnMissingBean(RestTemplate.class)
          @Bean
          public RestTemplate restTemplate()
      {
              RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
              return restTemplate;
          }

          /**
           * 使用HttpClient作為底層客戶端
           * @return
           */

          private ClientHttpRequestFactory getClientHttpRequestFactory() {
              int timeout = 5000;
              RequestConfig config = RequestConfig.custom()
                      .setConnectTimeout(timeout)
                      .setConnectionRequestTimeout(timeout)
                      .setSocketTimeout(timeout)
                      .build();
              CloseableHttpClient client = HttpClientBuilder
                      .create()
                      .setDefaultRequestConfig(config)
                      .build();
              return new HttpComponentsClientHttpRequestFactory(client);
          }

      }

      在需要使用RestTemplate的位置,注入并使用即可!

      @Autowired
      private RestTemplate restTemplate;

      從開發(fā)人員的反饋,和網(wǎng)上的各種HTTP客戶端性能以及易用程度評(píng)測來看,OkHttp 優(yōu)于 ApacheHttpClientApacheHttpClient優(yōu)于HttpURLConnection。

      因此,我們還可以通過如下方式,將底層的http客戶端換成OkHttp!

      /**
       * 使用OkHttpClient作為底層客戶端
       * @return
       */

      private ClientHttpRequestFactory getClientHttpRequestFactory(){
          OkHttpClient okHttpClient = new OkHttpClient.Builder()
                  .connectTimeout(5, TimeUnit.SECONDS)
                  .writeTimeout(5, TimeUnit.SECONDS)
                  .readTimeout(5, TimeUnit.SECONDS)
                  .build();
          return new OkHttp3ClientHttpRequestFactory(okHttpClient);
      }

      三、API 實(shí)踐

      RestTemplate最大的特色就是對(duì)各種網(wǎng)絡(luò)請(qǐng)求方式做了包裝,能極大的簡化開發(fā)人員的工作量,下面我們以GET、POSTPUT、DELETE文件上傳與下載為例,分別介紹各個(gè)API的使用方式!

      3.1、GET 請(qǐng)求

      通過RestTemplate發(fā)送HTTP GET協(xié)議請(qǐng)求,經(jīng)常使用到的方法有兩個(gè):

      • getForObject()
      • getForEntity()

      二者的主要區(qū)別在于,getForObject()返回值是HTTP協(xié)議的響應(yīng)體。

      getForEntity()返回的是ResponseEntity,ResponseEntity是對(duì)HTTP響應(yīng)的封裝,除了包含響應(yīng)體,還包含HTTP狀態(tài)碼、contentType、contentLengthHeader等信息。

      Spring Boot環(huán)境下寫一個(gè)單元測試用例,首先創(chuàng)建一個(gè)Api接口,然后編寫單元測試進(jìn)行服務(wù)測試。

      • 不帶參的get請(qǐng)求
      @RestController
      public class TestController {

          /**
           * 不帶參的get請(qǐng)求
           * @return
           */

          @RequestMapping(value = "testGet", method = RequestMethod.GET)
          public ResponseBean testGet(){
              ResponseBean result = new ResponseBean();
              result.setCode("200");
              result.setMsg("請(qǐng)求成功,方法:testGet");
              return result;
          }
      }
      public class ResponseBean {

          private String code;

          private String msg;

          public String getCode() {
              return code;
          }

          public void setCode(String code) {
              this.code = code;
          }

          public String getMsg() {
              return msg;
          }

          public void setMsg(String msg) {
              this.msg = msg;
          }

          @Override
          public String toString() {
              return "ResponseBean{" +
                      "code='" + code + '\'' +
                      ", msg='" + msg + '\'' +
                      '}';
          }
      }
      @Autowired
      private RestTemplate restTemplate;

      /**
       * 單元測試(不帶參的get請(qǐng)求)
       */

      @Test
      public void testGet(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testGet";

          //發(fā)起請(qǐng)求,直接返回對(duì)象
          ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.class);
          System.out.println(responseBean.toString());
      }
      • 帶參的get請(qǐng)求(restful風(fēng)格)
      @RestController
      public class TestController {

          /**
           * 帶參的get請(qǐng)求(restful風(fēng)格)
           * @return
           */

          @RequestMapping(value = "testGetByRestFul/{id}/{name}", method = RequestMethod.GET)
          public ResponseBean testGetByRestFul(@PathVariable(value = "id") String id, @PathVariable(value = "name") String name){
              ResponseBean result = new ResponseBean();
              result.setCode("200");
              result.setMsg("請(qǐng)求成功,方法:testGetByRestFul,請(qǐng)求參數(shù)id:" +  id + "請(qǐng)求參數(shù)name:" + name);
              return result;
          }
      }
      @Autowired
      private RestTemplate restTemplate;


       /**
       * 單元測試(帶參的get請(qǐng)求)
       */

      @Test
      public void testGetByRestFul(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testGetByRestFul/{1}/{2}";

          //發(fā)起請(qǐng)求,直接返回對(duì)象(restful風(fēng)格)
          ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.class, "001", "張三");
          System.out.println(responseBean.toString());
      }
      • 帶參的get請(qǐng)求(使用占位符號(hào)傳參)
      @RestController
      public class TestController {

          /**
           * 帶參的get請(qǐng)求(使用占位符號(hào)傳參)
           * @return
           */

          @RequestMapping(value = "testGetByParam", method = RequestMethod.GET)
          public ResponseBean testGetByParam(@RequestParam("userName") String userName,
                                                   @RequestParam("userPwd") String userPwd)
      {
              ResponseBean result = new ResponseBean();
              result.setCode("200");
              result.setMsg("請(qǐng)求成功,方法:testGetByParam,請(qǐng)求參數(shù)userName:" +  userName + ",userPwd:" + userPwd);
              return result;
          }
      }
      @Autowired
      private RestTemplate restTemplate;

       /**
       * 單元測試(帶參的get請(qǐng)求)
       */

      @Test
      public void testGetByParam(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testGetByParam?userName={userName}&userPwd={userPwd}";

          //請(qǐng)求參數(shù)
          Map<String, String> uriVariables = new HashMap<>();
          uriVariables.put("userName""唐三藏");
          uriVariables.put("userPwd""123456");

          //發(fā)起請(qǐng)求,直接返回對(duì)象(帶參數(shù)請(qǐng)求)
          ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.classuriVariables);
          System.out.println(responseBean.toString());
      }

      上面的所有的getForObject請(qǐng)求傳參方法,getForEntity都可以使用,使用方法上也幾乎是一致的,只是在返回結(jié)果接收的時(shí)候略有差別。

      使用ResponseEntity<T> responseEntity來接收響應(yīng)結(jié)果。用responseEntity.getBody()獲取響應(yīng)體。

       /**
       * 單元測試
       */

      @Test
      public void testAllGet(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testGet";

          //發(fā)起請(qǐng)求,返回全部信息
          ResponseEntity<ResponseBean> response = restTemplate.getForEntity(url, ResponseBean.class);

          // 獲取響應(yīng)體
          System.out.println("HTTP 響應(yīng)body:" + response.getBody().toString());

          // 以下是getForEntity比getForObject多出來的內(nèi)容
          HttpStatus statusCode = response.getStatusCode();
          int statusCodeValue = response.getStatusCodeValue();
          HttpHeaders headers = response.getHeaders();

          System.out.println("HTTP 響應(yīng)狀態(tài):" + statusCode);
          System.out.println("HTTP 響應(yīng)狀態(tài)碼:" + statusCodeValue);
          System.out.println("HTTP Headers信息:" + headers);
      }

      3.2、POST 請(qǐng)求

      其實(shí)POST請(qǐng)求方法和GET請(qǐng)求方法上大同小異,RestTemplatePOST請(qǐng)求也包含兩個(gè)主要方法:

      • postForObject()
      • postForEntity()

      postForEntity()返回全部的信息,postForObject()方法返回body對(duì)象,具體使用方法如下!

      • 模擬表單請(qǐng)求,post方法測試
      @RestController
      public class TestController {

          /**
           * 模擬表單請(qǐng)求,post方法測試
           * @return
           */

          @RequestMapping(value = "testPostByForm", method = RequestMethod.POST)
          public ResponseBean testPostByForm(@RequestParam("userName") String userName,
                                              @RequestParam("userPwd") String userPwd)
      {
              ResponseBean result = new ResponseBean();
              result.setCode("200");
              result.setMsg("請(qǐng)求成功,方法:testPostByForm,請(qǐng)求參數(shù)userName:" + userName + ",userPwd:" + userPwd);
              return result;
          }
      }
      @Autowired
      private RestTemplate restTemplate;

      /**
       * 模擬表單提交,post請(qǐng)求
       */

      @Test
      public void testPostByForm(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testPostByForm";

          // 請(qǐng)求頭設(shè)置,x-www-form-urlencoded格式的數(shù)據(jù)
          HttpHeaders headers = new HttpHeaders();
          headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

          //提交參數(shù)設(shè)置
          MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
          map.add("userName""唐三藏");
          map.add("userPwd""123456");

          // 組裝請(qǐng)求體
          HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

          //發(fā)起請(qǐng)求
          ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
          System.out.println(responseBean.toString());
      }
      • 模擬表單請(qǐng)求,post方法測試(對(duì)象接受)
      @RestController
      public class TestController {

          /**
           * 模擬表單請(qǐng)求,post方法測試
           * @param request
           * @return
           */

          @RequestMapping(value = "testPostByFormAndObj", method = RequestMethod.POST)
          public ResponseBean testPostByForm(RequestBean request){
              ResponseBean result = new ResponseBean();
              result.setCode("200");
              result.setMsg("請(qǐng)求成功,方法:testPostByFormAndObj,請(qǐng)求參數(shù):" + JSON.toJSONString(request));
              return result;
          }
      }
      public class RequestBean {


          private String userName;


          private String userPwd;


          public String getUserName() {
              return userName;
          }

          public void setUserName(String userName) {
              this.userName = userName;
          }

          public String getUserPwd() {
              return userPwd;
          }

          public void setUserPwd(String userPwd) {
              this.userPwd = userPwd;
          }
      }
      @Autowired
      private RestTemplate restTemplate;

      /**
       * 模擬表單提交,post請(qǐng)求
       */

      @Test
      public void testPostByForm(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testPostByFormAndObj";

          // 請(qǐng)求頭設(shè)置,x-www-form-urlencoded格式的數(shù)據(jù)
          HttpHeaders headers = new HttpHeaders();
          headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

          //提交參數(shù)設(shè)置
          MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
          map.add("userName""唐三藏");
          map.add("userPwd""123456");

          // 組裝請(qǐng)求體
          HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

          //發(fā)起請(qǐng)求
          ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
          System.out.println(responseBean.toString());
      }
      • 模擬 JSON 請(qǐng)求,post 方法測試
      @RestController
      public class TestController {

          /**
           * 模擬JSON請(qǐng)求,post方法測試
           * @param request
           * @return
           */

          @RequestMapping(value = "testPostByJson", method = RequestMethod.POST)
          public ResponseBean testPostByJson(@RequestBody RequestBean request){
              ResponseBean result = new ResponseBean();
              result.setCode("200");
              result.setMsg("請(qǐng)求成功,方法:testPostByJson,請(qǐng)求參數(shù):" + JSON.toJSONString(request));
              return result;
          }
      }
      @Autowired
      private RestTemplate restTemplate;

      /**
       * 模擬JSON提交,post請(qǐng)求
       */

      @Test
      public void testPostByJson(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testPostByJson";

          //入?yún)?/span>
          RequestBean request = new RequestBean();
          request.setUserName("唐三藏");
          request.setUserPwd("123456789");

          //發(fā)送post請(qǐng)求,并打印結(jié)果,以String類型接收響應(yīng)結(jié)果JSON字符串
          ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
          System.out.println(responseBean.toString());
      }
      • 模擬頁面重定向,post請(qǐng)求
      @Controller
      public class LoginController {

          /**
           * 重定向
           * @param request
           * @return
           */

          @RequestMapping(value = "testPostByLocation", method = RequestMethod.POST)
          public String testPostByLocation(@RequestBody RequestBean request){
              return "redirect:index.html";
          }
      }

      @Autowired
      private RestTemplate restTemplate;

      /**
       * 重定向,post請(qǐng)求
       */

      @Test
      public void testPostByLocation(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testPostByLocation";

          //入?yún)?/span>
          RequestBean request = new RequestBean();
          request.setUserName("唐三藏");
          request.setUserPwd("123456789");

          //用于提交完成數(shù)據(jù)之后的頁面跳轉(zhuǎn),返回跳轉(zhuǎn)url
          URI uri = restTemplate.postForLocation(url, request);
          System.out.println(uri.toString());
      }

      輸出結(jié)果如下:

      http://localhost:8080/index.html

      3.3、PUT 請(qǐng)求

      put請(qǐng)求方法,可能很多人都沒用過,它指的是修改一個(gè)已經(jīng)存在的資源或者插入資源,該方法會(huì)向URL代表的資源發(fā)送一個(gè)HTTP PUT方法請(qǐng)求,示例如下!

      @RestController
      public class TestController {

          /**
           * 模擬JSON請(qǐng)求,put方法測試
           * @param request
           * @return
           */

          @RequestMapping(value = "testPutByJson", method = RequestMethod.PUT)
          public void testPutByJson(@RequestBody RequestBean request){
              System.out.println("請(qǐng)求成功,方法:testPutByJson,請(qǐng)求參數(shù):" + JSON.toJSONString(request));
          }
      }
      @Autowired
      private RestTemplate restTemplate;

      /**
       * 模擬JSON提交,put請(qǐng)求
       */

      @Test
      public void testPutByJson(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testPutByJson";

          //入?yún)?/span>
          RequestBean request = new RequestBean();
          request.setUserName("唐三藏");
          request.setUserPwd("123456789");

          //模擬JSON提交,put請(qǐng)求
          restTemplate.put(url, request);
      }

      3.4、DELETE 請(qǐng)求

      與之對(duì)應(yīng)的還有delete方法協(xié)議,表示刪除一個(gè)已經(jīng)存在的資源,該方法會(huì)向URL代表的資源發(fā)送一個(gè)HTTP DELETE方法請(qǐng)求。

      @RestController
      public class TestController {

          /**
           * 模擬JSON請(qǐng)求,delete方法測試
           * @return
           */

          @RequestMapping(value = "testDeleteByJson", method = RequestMethod.DELETE)
          public void testDeleteByJson(){
              System.out.println("請(qǐng)求成功,方法:testDeleteByJson");
          }
      }
      @Autowired
      private RestTemplate restTemplate;

      /**
       * 模擬JSON提交,delete請(qǐng)求
       */

      @Test
      public void testDeleteByJson(){
          //請(qǐng)求地址
          String url = "http://localhost:8080/testDeleteByJson";

          //模擬JSON提交,delete請(qǐng)求
          restTemplate.delete(url);
      }

      3.5、通用請(qǐng)求方法 exchange 方法

      如果以上方法還不滿足你的要求。在RestTemplate工具類里面,還有一個(gè)exchange通用協(xié)議請(qǐng)求方法,它可以發(fā)送GET、POSTDELETE、PUTOPTIONS、PATCH等等HTTP方法請(qǐng)求。

      打開源碼,我們可以很清晰的看到這一點(diǎn)。

      圖片
      圖片

      采用exchange方法,可以滿足各種場景下的請(qǐng)求操作!

      3.6、文件上傳與下載

      除了經(jīng)常用到的getpost請(qǐng)求以外,還有一個(gè)我們經(jīng)常會(huì)碰到的場景,那就是文件的上傳與下載,如果采用RestTemplate,該怎么使用呢?

      案例如下,具體實(shí)現(xiàn)細(xì)節(jié)參考代碼注釋!

      • 文件上傳
      @RestController
      public class FileUploadController {


          private static final String UPLOAD_PATH = "/springboot-frame-example/springboot-example-resttemplate/";

          /**
           * 文件上傳
           * @param uploadFile
           * @return
           */

          @RequestMapping(value = "upload", method = RequestMethod.POST)
          public ResponseBean upload(@RequestParam("uploadFile") MultipartFile uploadFile,
                                     @RequestParam("userName") String userName) 
      {
              // 在 uploadPath 文件夾中通過用戶名對(duì)上傳的文件歸類保存
              File folder = new File(UPLOAD_PATH + userName);
              if (!folder.isDirectory()) {
                  folder.mkdirs();
              }

              // 對(duì)上傳的文件重命名,避免文件重名
              String oldName = uploadFile.getOriginalFilename();
              String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));

              //定義返回視圖
              ResponseBean result = new ResponseBean();
              try {
                  // 文件保存
                  uploadFile.transferTo(new File(folder, newName));
                  result.setCode("200");
                  result.setMsg("文件上傳成功,方法:upload,文件名:" + newName);
              } catch (IOException e) {
                  e.printStackTrace();
                  result.setCode("500");
                  result.setMsg("文件上傳失敗,方法:upload,請(qǐng)求文件:" + oldName);
              }
              return result;
          }
      }

      @Autowired
      private RestTemplate restTemplate;

      /**
       * 文件上傳,post請(qǐng)求
       */

      @Test
      public void upload(){
          //需要上傳的文件
          String filePath = "/Users/panzhi/Desktop/Jietu20220205-194655.jpg";

          //請(qǐng)求地址
          String url = "http://localhost:8080/upload";

          // 請(qǐng)求頭設(shè)置,multipart/form-data格式的數(shù)據(jù)
          HttpHeaders headers = new HttpHeaders();
          headers.setContentType(MediaType.MULTIPART_FORM_DATA);

          //提交參數(shù)設(shè)置
          MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
          param.add("uploadFile"new FileSystemResource(new File(filePath)));
          //服務(wù)端如果接受額外參數(shù),可以傳遞
          param.add("userName""張三");

          // 組裝請(qǐng)求體
          HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(param, headers);

          //發(fā)起請(qǐng)求
          ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
          System.out.println(responseBean.toString());
      }
      • 文件下載
      @RestController
      public class FileUploadController {


          private static final String UPLOAD_PATH = "springboot-frame-example/springboot-example-resttemplate/";


          /**
           * 帶參的get請(qǐng)求(restful風(fēng)格)
           * @return
           */

          @RequestMapping(value = "downloadFile/{userName}/{fileName}", method = RequestMethod.GET)
          public void downloadFile(@PathVariable(value = "userName") String userName,
                                   @PathVariable(value = "fileName") String fileName,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception 
      {

              File file = new File(UPLOAD_PATH + userName + File.separator + fileName);
              if (file.exists()) {
                  //獲取文件流
                  FileInputStream fis = new FileInputStream(file);
                  //獲取文件后綴(.png)
                  String extendFileName = fileName.substring(fileName.lastIndexOf('.'));
                  //動(dòng)態(tài)設(shè)置響應(yīng)類型,根據(jù)前臺(tái)傳遞文件類型設(shè)置響應(yīng)類型
                  response.setContentType(request.getSession().getServletContext().getMimeType(extendFileName));
                  //設(shè)置響應(yīng)頭,attachment表示以附件的形式下載,inline表示在線打開
                  response.setHeader("content-disposition","attachment;fileName=" + URLEncoder.encode(fileName,"UTF-8"));
                  //獲取輸出流對(duì)象(用于寫文件)
                  OutputStream os = response.getOutputStream();
                  //下載文件,使用spring框架中的FileCopyUtils工具
                  FileCopyUtils.copy(fis,os);
              }
          }
      }

      @Autowired
      private RestTemplate restTemplate;

      /**
       * 小文件下載
       * @throws IOException
       */

      @Test
      public void downloadFile() throws IOException {
          String userName = "張三";
          String fileName = "c98b677c-0948-46ef-84d2-3742a2b821b0.jpg";
          //請(qǐng)求地址
          String url = "http://localhost:8080/downloadFile/{1}/{2}";

          //發(fā)起請(qǐng)求,直接返回對(duì)象(restful風(fēng)格)
          ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].classuserName,fileName);
          System.out.println("文件下載請(qǐng)求結(jié)果狀態(tài)碼:" + rsp.getStatusCode());

          // 將下載下來的文件內(nèi)容保存到本地
          String targetPath = "/Users/panzhi/Desktop/"  + fileName;
          Files.write(Paths.get(targetPath), Objects.requireNonNull(rsp.getBody(), "未獲取到下載文件"));
      }

      這種下載方法實(shí)際上是將下載文件一次性加載到客戶端本地內(nèi)存,然后從內(nèi)存將文件寫入磁盤。這種方式對(duì)于小文件的下載還比較適合,如果文件比較大或者文件下載并發(fā)量比較大,容易造成內(nèi)存的大量占用,從而降低應(yīng)用的運(yùn)行效率。

      • 大文件下載
      @Autowired
      private RestTemplate restTemplate;

      /**
       * 大文件下載
       * @throws IOException
       */

      @Test
      public void downloadBigFile() throws IOException {
          String userName = "張三";
          String fileName = "c98b677c-0948-46ef-84d2-3742a2b821b0.jpg";
          //請(qǐng)求地址
          String url = "http://localhost:8080/downloadFile/{1}/{2}";

          //定義請(qǐng)求頭的接收類型
          RequestCallback requestCallback = request -> request.getHeaders()
                  .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));

          //對(duì)響應(yīng)進(jìn)行流式處理而不是將其全部加載到內(nèi)存中
          String targetPath = "/Users/panzhi/Desktop/"  + fileName;
          restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
              Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
              return null;
          }, userName, fileName);
      }

      這種下載方式的區(qū)別在于:

      • 設(shè)置了請(qǐng)求頭APPLICATION_OCTET_STREAM,表示以流的形式進(jìn)行數(shù)據(jù)加載

      • RequestCallback結(jié)合File.copy保證了接收到一部分文件內(nèi)容,就向磁盤寫入一部分內(nèi)容。而不是全部加載到內(nèi)存,最后再寫入磁盤文件。

      在下載大文件時(shí),例如excel、pdfzip等等文件,特別管用,

      四、小結(jié)

      通過本章的講解,想必讀者初步的了解了如何使用RestTemplate方便快捷的訪問restful接口。其實(shí)RestTemplate的功能非常強(qiáng)大,作者也僅僅學(xué)了點(diǎn)皮毛。


      微信8.0將好友放開到了一萬,小伙伴可以加我大號(hào)了,先到先得,再滿就真沒了

      掃描下方二維碼即可加我微信啦,2022,抱團(tuán)取暖,一起牛逼。

      推薦閱讀


      圖片

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多