日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【本人秃顶程序员】技巧分享丨spring的RestTemplate的妙用,你知道吗?

發布時間:2023/12/6 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【本人秃顶程序员】技巧分享丨spring的RestTemplate的妙用,你知道吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

←←←←←←←←←←←← 快!點關注

為什么要使用RestTemplate?

隨著微服務的廣泛使用,在實際的開發中,客戶端代碼中調用RESTful接口也越來越常見。在系統的遺留代碼中,你可能會看見有一些代碼是使用HttpURLConnection來調用RESTful接口的,類似于下面這樣:

URL url = ... // 打開連接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); try {conn.setRequestMethod("POST");conn.setDoInput(true);conn.setDoOutput(true);conn.connect();// 發送數據...BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));bw.write(str);// 接收數據 ...BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));String line = null;while ((line = br.readLine()) != null) {...} } finally {conn.disconnect(); } 復制代碼

從上面的代碼可以看出,使用HttpURLConnection調用RESTful接口是比較麻煩的,假如要調用30個接口,每個接口都使用類似于上面的代碼 進行調用,那簡直是一場災難(寫這么多無聊的樣板代碼,內心絕對是崩潰的)。有人可能會想,將常用的RESTful操作(例如GET、POST、DELETE)封裝成工具類,再調用不是也可以嗎!這樣做確實可行,但是要封裝成通用的工具類不是那么簡單的(需要一定的經驗)。調用RESTful接口,還有另外一種選擇:Apache HttpComponents。雖然使用它發送HTTP請求確實挺方便的,但是使用它調用RESTful接口好像也挺麻煩的!

直到我遇到了RestTemplate,世界頓時都明亮了,腰也不酸了,腿也不疼了,一下子就對接好了10個RESTful接口。寫的代碼可能變成是這樣子的:

RestTemplate template = ... // 請求地址 String url = ... // 請求參數 UserParams request = ... // 執行POST請求 User u = template.postForObject(url, request, User.class); ... 復制代碼

上面的調用代碼變的簡潔了很多,是不是很爽啊!RestTemplate是spring提供用來調用RESTful接口的類,里面提供了大量便捷的方法,如下:

執行不同的請求,只需找到這種請求方式所對應的方法就行,上例中的postForObject就是發送的POST請求。如果上面的請求沒有找到對應的方法,可以使用更加通用的exchange和execute方法。

RestTemplate的可擴展性也很強(下面列出比較常用的幾種方式):

  • RestTemplate默認使用的是JDK中的HttpURLConnection實現的,如果你想要切換到其他的HTTP庫,例如,Apache HttpComponents, Netty和OkHttp,只需要調用setRequestFactory方法來進行設置,甚至可以使用自己實現的類型,只需要繼承自ClientHttpRequestFactory。(一般情況下,使用默認的實現就好)
  • RestTemplate默認使用的是DefaultResponseErrorHandler響應錯誤處理器,你可以調用setErrorHandler來定制自己的響應錯誤處理器。
  • 客戶端請求攔截器:ClientHttpRequestInterceptor,實現這個接口,并在org.springframework.web.client.RestTemplate#setInterceptors(java.util.List)中進行注冊,能對請求頭和請求體的內容進行修改,并能對響應的內容進行修改。(下面將會講解)
  • RestTemplate中的doExecute方法,所有請求方式最終都會執行這個方法,重寫此方法能完成一些必要的操作。
  • RestTemplate的妙用

    考慮這樣一個場景:假如說A部門開發的用戶相關的微服務接口,提供給B部門來使用,在使用時需要在請求頭中加入基本的認證頭信息,認證頭的格式如下:

    Authorization=Basic {token} 復制代碼

    token的格式是:base64(username:password)。假如username是zfx,密碼是123,結果是先拼接用戶名和密碼:zfx:123,再用utf-8格式獲取其字節碼,進行base64編碼的結果為:emZ4OjEyMw==

    假如要調用A部門的接口,根據id來獲取用戶的信息,代碼如下:

    String userId = "11"; String url = "http://127.0.0.1:8080/v1/users/{id}";RestTemplate restTemplate = new RestTemplate();// 基本的認證頭信息 String username = "zfx"; String password = "123"; String token = Base64Utils.encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Basic " + token); HttpEntity<Void> requestEntity = new HttpEntity<>(headers);ResponseEntity<User> exchange = restTemplate.exchange(url, HttpMethod.GET, requestEntity, User.class, userId); User result = exchange.getBody(); 復制代碼

    首先先創建RestTemplate的實例,在實際的開發中,最好不要每次都創建RestTemplate的實例,最好在spring中以單例的方式來配置,要使用的地方直接注入。用base64來編碼了用戶名和密碼,然后在請求頭中進行設置。restTemplate.exchange執行請求,并獲取返回的結果。上面的代碼其實并不難,但是這樣寫會不會有啥問題呢!假如說,叫你對接A部門的根據機構id來獲取機構信息的接口,你豈不是又要把上面的代碼再重新復制一下嗎?這樣不是很麻煩,代碼會很臃腫。

    spring提供了ClientHttpRequestInterceptor這個類,適合用來處理這種情況,加入基本的認證頭信息,可以使用spring提供的這個類:BasicAuthorizationInterceptor。使用配置的方式來配置RestTemplate:

    @Configuration public class RestTemplateConfig {@Value("${zfx.username}")private String username;@Value("${zfx.password}")private String password;@Bean("basicAuthRestTemplate")public RestTemplate createBasicAuthRestTemplate() {RestTemplate restTemplate = new RestTemplate();List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();interceptors.add(new BasicAuthorizationInterceptor(username, password));restTemplate.setInterceptors(interceptors);return restTemplate;}} 復制代碼

    上面的代碼在創建basicAuthRestTemplate時,會加入基本的認證頭信息的攔截器,來設置基本認證頭信息。

    再次調用上面的接口時,代碼可以這樣寫:

    @Autowired RestTemplate basicAuthRestTemplate; ... String userId = "11"; String url = "http://127.0.0.1:8080/v1/users/{id}"; User result = basicAuthRestTemplate.getForObject(url, User.class, userId); 復制代碼

    代碼一下子簡潔了這么多,假如說要調用根據機構id來獲取機構信息的接口呢?如下:

    @Autowired RestTemplate basicAuthRestTemplate; ... String orgId = "11"; String url = "http://127.0.0.1:8080/v1/orgs/{id}"; Org result = basicAuthRestTemplate.getForObject(url, Org.class, orgId); 復制代碼

    代碼一下子簡潔了很多,對接這些接口的程序員不用再關心認證是怎么一回事,認證這件事對于他們完全是透明的,他們只需要專注于編寫他們自己的邏輯代碼就可以了。ClientHttpRequestInterceptor的實現也很簡單,代碼如下:

    @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body,ClientHttpRequestExecution execution) throws IOException {String token = Base64Utils.encodeToString((this.username + ":" + this.password).getBytes(StandardCharsets.UTF_8));request.getHeaders().add("Authorization", "Basic " + token);return execution.execute(request, body); } 復制代碼

    在intercept方法中加入了基本的認證頭信息。

    假如說,有一天認證方式變了,改成OAuth2.0了,那么我們只需要實現自己的請求攔截器就行了,如下:

    public class BearerAuthorizationInterceptimplements ClientHttpRequestInterceptor {@Overridepublic ClientHttpResponse intercept(HttpRequest request, byte[] body,ClientHttpRequestExecution execution) throws IOException {String token = 這些寫獲取token的邏輯;request.getHeaders().add("Authorization", "Bearer " + token);return execution.execute(request, body);}} 復制代碼

    然后配置restTemplate:

    @Bean("bearerAuthRestTemplate")public RestTemplate createBearerAuthRestTemplate() {RestTemplate restTemplate = new RestTemplate();List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();interceptors.add(new BearerAuthorizationIntercept());restTemplate.setInterceptors(interceptors);return restTemplate;} 復制代碼

    那么只需要注入bearerAuthRestTemplate,就能使用他了:

    @Autowired RestTemplate bearerAuthRestTemplate; ... String userId = "11"; String url = "http://127.0.0.1:8080/v1/users/{id}"; User result = bearerAuthRestTemplate.getForObject(url, User.class, userId); 復制代碼

    轉載于:https://juejin.im/post/5c8cba09e51d453e2762de2f

    總結

    以上是生活随笔為你收集整理的【本人秃顶程序员】技巧分享丨spring的RestTemplate的妙用,你知道吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。