實際集成
獲取restTemplate實例,封裝方法
package com.quant.api.utils.restTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.converter.FormHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.util.concurrent.ListenableFutureCallback; import org.springframework.web.client.AsyncRestTemplate; import org.springframework.web.client.RestTemplate; import java.util.List; import java.util.Map; /** * @program: api * @description: * @author: TheEternity Zhang * @create: 2019-06-04 18:00 */ public class RestTemplateUtil { /** * 發送表單參數的post請求 * * @param url 請求url * @param param 參數 * @param respType 返回類型 * @return T */ public static <T> T postForm(String url, Map<String, List<Object>> param, Class<T> respType) { return getRestInstance().postForEntity(url, getHttpEntity(param, false), respType).getBody(); } /** * 發送表單參數的異步post請求 * * @param url 請求url * @param callback 回調接口 * @param respType 返回類型 */ public static <T> void asyncPostForm(String url, Map<String, List<Object>> param, Class<T> respType, ListenableFutureCallback<ResponseEntity<T>> callback) { getAsyncRestInstance().postForEntity(url, getHttpEntity(param, false), respType).addCallback(callback); } /** * 發送表單有參數get請求 * * @param url 請求url * @param param 參數對象 * @param respType 返回類型 * @return T */ public static <T> T getForm(String url, Class<T> respType, Map<String,String> param) { return getRestInstance().getForEntity(url, respType, param).getBody(); } /** * @Description: 發送表單無參數的get請求 * @Param: [url, param, respType] * @return: T * @Author: tonyzhang * @Date: 2019-01-18 17:23 */ public static <T> T getForm(String url, Class<T> respType) { return getRestInstance().getForObject(url, respType); } /** * 獲取HttpEntity實例對象 * * @param param 參數對象 * @param isJson true 發送json請求,false發送表單請求 * @return HttpEntity */ private static <P> HttpEntity<P> getHttpEntity(P param, boolean isJson) { HttpHeaders headers = new HttpHeaders(); if (isJson) { headers.setContentType(MediaType.APPLICATION_JSON_UTF8); } else { headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); } return new HttpEntity<>(param, headers); } /*-----------------生產單例對象,方便自定義如何構造對象------------------*/ private static RestTemplate restInit() { //設置連接超時和讀取超時時間 SimpleClientHttpRequestFactory factory=new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(5000); factory.setReadTimeout(5000); RestTemplate restTemplate = new RestTemplate(factory); FormHttpMessageConverter fastConverter = new FormHttpMessageConverter(); WxMappingJackson2HttpMessageConverter wmc=new WxMappingJackson2HttpMessageConverter(); restTemplate.getMessageConverters().add(fastConverter); restTemplate.getMessageConverters().add(wmc); return restTemplate; } private static AsyncRestTemplate asyncRestInit() { return new AsyncRestTemplate(); } private static RestTemplate getRestInstance() { return RestSingle.INSTANCE; } private static AsyncRestTemplate getAsyncRestInstance() { return AsyncRestSingle.INSTANCE; } private static class RestSingle { private static final RestTemplate INSTANCE = restInit(); } private static class AsyncRestSingle { private static final AsyncRestTemplate INSTANCE = asyncRestInit(); } }
增加一個MessageConverter
package com.quant.api.utils.restTemplate; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.util.ArrayList; import java.util.List; /** * @program: api * @description: 封裝轉換器, 添加更多類型的支持 * @author: TheEternity Zhang * @create: 2019-06-05 11:13 */ public class WxMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter { public WxMappingJackson2HttpMessageConverter(){ List<MediaType> mediaTypes=new ArrayList<>(); //添加text/html類型的支持 mediaTypes.add(MediaType.TEXT_HTML); //添加text/plain類型的支持.微信接口會用到 mediaTypes.add(MediaType.TEXT_PLAIN); setSupportedMediaTypes(mediaTypes); } }
參考
簡介:
spring框架提供的RestTemplate類可用於在應用中調用rest服務,它簡化了與http服務的通信方式,統一了RESTful的標准,封裝了http鏈接,我們只需要傳入url及返回值類型即可。相較於之前常用的HttpClient,RestTemplate是一種更優雅的調用RESTful服務的方式。
RestTemplate默認依賴JDK提供http連接的能力(HttpURLConnection),如果有需要的話也可以通過setRequestFactory方法替換為例如Apache HttpComponents、Netty或OkHttp等其它HTTP library。
其實spring並沒有真正的去實現底層的http請求(3次握手),而是集成了別的http請求,spring只是在原有的各種http請求進行了規范標准,讓開發者更加簡單易用,底層默認用的是jdk的http請求。
RestTemplate的優缺點:
優點:
連接池、超時時間設置、支持異步、請求和響應的編解碼
缺點:
依賴別的spring版塊、參數傳遞不靈活
springboot集成RestTemplate:
導入依賴:(其實他是spring集成好的,這個一般的springboot項目已經由此包了)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
在啟動類同包下創建RestTemplate.java類
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory){ return new RestTemplate(factory); } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory(){ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(15000); factory.setReadTimeout(5000); return factory; } }
然后在Service類中注入使用即可
@Service public class demoService { @Autowired private RestTemplate restTemplate; public String get(Integer id){ return restTemplate.getForObject("http://localhost:8080/user?userId=id",String.class); } }
RestTemplate定義了36個與REST資源交互的方法,其中的大多數都對應於HTTP的方法。
其實,這里面只有11個獨立的方法,其中有十個有三種重載形式,而第十一個則重載了六次,這樣一共形成了36個方法。
delete() 在特定的URL上對資源執行HTTP DELETE操作 exchange() 在URL上執行特定的HTTP方法,返回包含對象的ResponseEntity,這個對象是從響應體中映射得到的 execute() 在URL上執行特定的HTTP方法,返回一個從響應體映射得到的對象 getForEntity() 發送一個HTTP GET請求,返回的ResponseEntity包含了響應體所映射成的對象 getForObject() 發送一個HTTP GET請求,返回的請求體將映射為一個對象 postForEntity() POST 數據到一個URL,返回包含一個對象的ResponseEntity,這個對象是從響應體中映射得到的 postForObject() POST 數據到一個URL,返回根據響應體匹配形成的對象 headForHeaders() 發送HTTP HEAD請求,返回包含特定資源URL的HTTP頭 optionsForAllow() 發送HTTP OPTIONS請求,返回對特定URL的Allow頭信息 postForLocation() POST 數據到一個URL,返回新創建資源的URL put() PUT 資源到特定的URL
getForEntity
get請求就和正常在瀏覽器url上發送請求一樣
下面是有參數的get請求
@GetMapping("getForEntity/{id}") public User getById(@PathVariable(name = "id") String id) { ResponseEntity<User> response = restTemplate.getForEntity("http://localhost/get/{id}", User.class, id); User user = response.getBody(); return user; }
getForObject
getForObject 和 getForEntity 用法幾乎相同,指示返回值返回的是 響應體,省去了我們 再去 getBody()
@GetMapping("getForObject/{id}") public User getById(@PathVariable(name = "id") String id) { User user = restTemplate.getForObject("http://localhost/get/{id}", User.class, id); return user; }
postForEntity
@RequestMapping("saveUser") public String save(User user) { ResponseEntity<String> response = restTemplate.postForEntity("http://localhost/save", user, String.class); String body = response.getBody(); return body; }
postForObject
用法與 getForObject 一樣
如果遇到 postForObject 方法在 Controller 接受不到參數問題 請參考的的另一篇博客 :
https://blog.csdn.net/weixin_40461281/article/details/83472648
exchange
@PostMapping("demo") public void demo(Integer id, String name){ HttpHeaders headers = new HttpHeaders();//header參數 headers.add("authorization",Auth); headers.setContentType(MediaType.APPLICATION_JSON); JSONObject obj = new JSONObject();//放入body中的json參數 obj.put("userId", id); obj.put("name", name); HttpEntity<JSONObject> request = new HttpEntity<>(content,headers); //組裝 ResponseEntity<String> response = template.exchange("http://localhost:8080/demo",HttpMethod.POST,request,String.class); }
其余的方法用法也都差不多 , 在此就不細說了
參考
原文:https://blog.csdn.net/weixin_40461281/article/details/83540604
原文:https://blog.csdn.net/QiaoRui_/article/details/80453799
至此就可以直接調用API使用了,具體的調用及原理,連接池配置等可以參考如下收集的幾個很棒的文章
需要注意的是參數一定要用map否則接受的時候會有“null”這種情況而不是null
RestTemplate官方網站:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html
很好的介紹文章: https://www.xncoding.com/2017/07/06/spring/sb-restclient.html
http://ju.outofmemory.cn/entry/341530
https://my.oschina.net/lifany/blog/688889
關於配置http連接池原理的文章: