RestTemplate 是一个执行HTTP请求的同步阻塞式工具类,它仅仅只是在 HTTP 客户端库(例如 JDK HttpURLConnection,Apache HttpComponents,okHttp 等)基础上,封装了更加简单易用的模板方法 API,方便程序员利用已提供的模板方法发起网络请求和处理,能很大程度上提升我们的开发效率。
是Spring用于同步client端的核心类,简化了与http服务的通信,并满足RestFul原则,程序代码可以给它提供URL,并提取结果。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具。当然你也可以 通过setRequestFactory属性切换到不同的HTTP源,比如Apache HttpComponents、Netty和OkHttp。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.6.RELEASE</version></dependency>
@Testpublic void simpleTest() { RestTemplate restTemplate = new RestTemplate(); String url = "http://jsonplaceholder.typicode.com/posts/1"; String str = restTemplate.getForObject(url, String.class); System.out.println(str); }
RestTemplate 使用 转换器(HttpMessageConverter) 来处理请求数据和返回数据, 非 Spring 环境下有些包不全,会导致某些转换器不可用,例如将 javabean转换为json的 MappingJackson2XmlHttpMessageConverter 转换器, 所以要使用所有转换器的话需要额外添加这些转换器依赖的包,Spring环境的依赖包是包含这些缺失包的,不用额外添加
<!-- HttpMessageConverter : MappingJackson2HttpMessageConverter--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.13.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.13.1</version> </dependency> <!-- HttpMessageConverter : MappingJackson2XmlHttpMessageConverter --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.13.1</version> </dependency>
// 文件: RestTemplate.java// 行数: 137行 package org.springframework.web.client; public RestTemplate() { this.messageConverters.add(new ByteArrayHttpMessageConverter()); this.messageConverters.add(new StringHttpMessageConverter()); this.messageConverters.add(new ResourceHttpMessageConverter(false)); try { this.messageConverters.add(new SourceHttpMessageConverter<>()); } catch (Error err) { // Ignore when no TransformerFactory implementation is available } this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); if (romePresent) { this.messageConverters.add(new AtomFeedHttpMessageConverter()); this.messageConverters.add(new RssChannelHttpMessageConverter()); } if (jackson2XmlPresent) { this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); } else if (jaxb2Present) { this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { this.messageConverters.add(new MappingJackson2HttpMessageConverter()); } else if (gsonPresent) { this.messageConverters.add(new GsonHttpMessageConverter()); } else if (jsonbPresent) { this.messageConverters.add(new JsonbHttpMessageConverter()); } if (jackson2SmilePresent) { this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter()); } if (jackson2CborPresent) { this.messageConverters.add(new MappingJackson2CborHttpMessageConverter()); } this.uriTemplateHandler = initUriTemplateHandler(); }
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>
@Configurationpublic class RestTemplateConfig { /** * 没有实例化RestTemplate时,初始化RestTemplate * @return */ @ConditionalOnMissingBean(RestTemplate.class) @Bean public RestTemplate restTemplate(){ RestTemplate restTemplate = new RestTemplate(); return restTemplate; } }
@Configurationpublic class RestTemplateConfig { /** * 没有实例化RestTemplate时,初始化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); } }
@Autowiredprivate RestTemplate restTemplate;
/** * 使用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); }
@RestControllerpublic class TestController { /** * 不带参的get请求 * @return */ @RequestMapping(value = "testGet", method = RequestMethod.GET) public ResponseBean testGet(){ ResponseBean result = new ResponseBean(); result.setCode("200"); result.setMsg("请求成功,方法: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 + ''' + '}'; } }
@Autowiredprivate RestTemplate restTemplate; /** * 单元测试(不带参的get请求) */@Testpublic void testGet(){ //请求地址 String url = "http://localhost:8080/testGet"; //发起请求,直接返回对象 ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.class); System.out.println(responseBean.toString()); }
@RestControllerpublic class TestController { /** * 带参的get请求(restful风格) * @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("请求成功,方法:testGetByRestFul,请求参数id:" + id + "请求参数name:" + name); return result; } }
@Autowiredprivate RestTemplate restTemplate; /** * 单元测试(带参的get请求) */@Testpublic void testGetByRestFul(){ //请求地址 String url = "http://localhost:8080/testGetByRestFul/{1}/{2}"; //发起请求,直接返回对象(restful风格) ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.class, "001", "张三"); System.out.println(responseBean.toString()); }
@RestControllerpublic class TestController { /** * 带参的get请求(使用占位符号传参) * @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("请求成功,方法:testGetByParam,请求参数userName:" + userName + ",userPwd:" + userPwd); return result; } }
@Autowiredprivate RestTemplate restTemplate; /** * 单元测试(带参的get请求) */@Testpublic void testGetByParam(){ //请求地址 String url = "http://localhost:8080/testGetByParam?userName={userName}&userPwd={userPwd}"; //请求参数 Map<String, String> uriVariables = new HashMap<>(); uriVariables.put("userName", "唐三藏"); uriVariables.put("userPwd", "123456"); //发起请求,直接返回对象(带参数请求) ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.class, uriVariables); System.out.println(responseBean.toString()); }
/** * 单元测试 */@Testpublic void testAllGet(){ //请求地址 String url = "http://localhost:8080/testGet"; //发起请求,返回全部信息 ResponseEntity<ResponseBean> response = restTemplate.getForEntity(url, ResponseBean.class); // 获取响应体 System.out.println("HTTP 响应div:" + response.getBody().toString()); // 以下是getForEntity比getForObject多出来的内容 HttpStatus statusCode = response.getStatusCode(); int statusCodeValue = response.getStatusCodeValue(); HttpHeaders headers = response.getHeaders(); System.out.println("HTTP 响应状态:" + statusCode); System.out.println("HTTP 响应状态码:" + statusCodeValue); System.out.println("HTTP Headers信息:" + headers); }
@RestControllerpublic class TestController { /** * 模拟表单请求,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("请求成功,方法:testPostByForm,请求参数userName:" + userName + ",userPwd:" + userPwd); return result; } }
@Autowiredprivate RestTemplate restTemplate; /** * 模拟表单提交,post请求 */@Testpublic void testPostByForm(){ //请求地址 String url = "http://localhost:8080/testPostByForm"; // 请求头设置,x-www-form-urlencoded格式的数据 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); //提交参数设置 MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); map.add("userName", "唐三藏"); map.add("userPwd", "123456"); // 组装请求体 HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); //发起请求 ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class); System.out.println(responseBean.toString()); }
@RestControllerpublic class TestController { /** * 模拟表单请求,post方法测试 * @param request * @return */ @RequestMapping(value = "testPostByFormAndObj", method = RequestMethod.POST) public ResponseBean testPostByForm(RequestBean request){ ResponseBean result = new ResponseBean(); result.setCode("200"); result.setMsg("请求成功,方法:testPostByFormAndObj,请求参数:" + 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; } }
@Autowiredprivate RestTemplate restTemplate; /** * 模拟表单提交,post请求 */@Testpublic void testPostByForm(){ //请求地址 String url = "http://localhost:8080/testPostByFormAndObj"; // 请求头设置,x-www-form-urlencoded格式的数据 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); //提交参数设置 MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); map.add("userName", "唐三藏"); map.add("userPwd", "123456"); // 组装请求体 HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); //发起请求 ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class); System.out.println(responseBean.toString()); }
@RestControllerpublic class TestController { /** * 模拟JSON请求,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("请求成功,方法:testPostByJson,请求参数:" + JSON.toJSONString(request)); return result; } }
@Autowiredprivate RestTemplate restTemplate; /** * 模拟JSON提交,post请求 */@Testpublic void testPostByJson(){ //请求地址 String url = "http://localhost:8080/testPostByJson"; //入参 RequestBean request = new RequestBean(); request.setUserName("唐三藏"); request.setUserPwd("123456789"); //发送post请求,并打印结果,以String类型接收响应结果JSON字符串 ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class); System.out.println(responseBean.toString()); }
@Controllerpublic class LoginController { /** * 重定向 * @param request * @return */ @RequestMapping(value = "testPostByLocation", method = RequestMethod.POST) public String testPostByLocation(@RequestBody RequestBean request){ return "redirect:index.html"; } }
@Autowiredprivate RestTemplate restTemplate; /** * 重定向,post请求 */@Testpublic void testPostByLocation(){ //请求地址 String url = "http://localhost:8080/testPostByLocation"; //入参 RequestBean request = new RequestBean(); request.setUserName("唐三藏"); request.setUserPwd("123456789"); //用于提交完成数据之后的页面跳转,返回跳转url URI uri = restTemplate.postForLocation(url, request); System.out.println(uri.toString()); }
http://localhost:8080/index.html
@RestControllerpublic class TestController { /** * 模拟JSON请求,put方法测试 * @param request * @return */ @RequestMapping(value = "testPutByJson", method = RequestMethod.PUT) public void testPutByJson(@RequestBody RequestBean request){ System.out.println("请求成功,方法:testPutByJson,请求参数:" + JSON.toJSONString(request)); } }
@Autowiredprivate RestTemplate restTemplate; /** * 模拟JSON提交,put请求 */@Testpublic void testPutByJson(){ //请求地址 String url = "http://localhost:8080/testPutByJson"; //入参 RequestBean request = new RequestBean(); request.setUserName("唐三藏"); request.setUserPwd("123456789"); //模拟JSON提交,put请求 restTemplate.put(url, request); }
@RestControllerpublic class TestController { /** * 模拟JSON请求,delete方法测试 * @return */ @RequestMapping(value = "testDeleteByJson", method = RequestMethod.DELETE) public void testDeleteByJson(){ System.out.println("请求成功,方法:testDeleteByJson"); } }
@Autowiredprivate RestTemplate restTemplate; /** * 模拟JSON提交,delete请求 */@Testpublic void testDeleteByJson(){ //请求地址 String url = "http://localhost:8080/testDeleteByJson"; //模拟JSON提交,delete请求 restTemplate.delete(url); }
@Test public void rtExchangeTest() throws JSONException { RestTemplate restTemplate = new RestTemplate(); String url = "http://xxx.top/notice/list"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); JSONObject jsonObj = new JSONObject(); jsonObj.put("start",1); jsonObj.put("page",5); HttpEntity<String> entity = new HttpEntity<>(jsonObj.toString(), headers); ResponseEntity<JSONObject> exchange = restTemplate.exchange(url, HttpMethod.GET, entity, JSONObject.class); System.out.println(exchange.getBody()); }
@Override @Nullable public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException { RequestCallback requestCallback = httpEntityCallback(request, responseType); HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger); return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables); }
restTemplate.postForEntity等方法虽然表面上接收的request是@Nullable Object request类型,但是你追踪下去会发现,这个request是用HttpEntity来解析,所以就直接使用HttpEntity.
//文件: RestTemplate.java//行数: 899 package org.springframework.web.client; public HttpEntityRequestCallback(@Nullable Object requestBody, @Nullable Type responseType) { super(responseType); if (requestBody instanceof HttpEntity) { this.requestEntity = (HttpEntity<?>) requestBody; } else if (requestBody != null) { this.requestEntity = new HttpEntity<>(requestBody); } else { this.requestEntity = HttpEntity.EMPTY; } }
我们知道,调用reseful接口传递的数据内容是json格式的字符串,返回的响应也是json格式的字符串。然而restTemplate.postForObject方法的请求参数RequestBean和返回参数ResponseBean却都是java类。是RestTemplate通过HttpMessageConverter自动帮我们做了转换的操作。
默认情况下RestTemplate自动帮我们注册了一组HttpMessageConverter用来处理一些不同的contentType的请求。
如StringHttpMessageConverter来处理text/plain;MappingJackson2HttpMessageConverter来处理application/json;MappingJackson2XmlHttpMessageConverter来处理application/xml。
你可以在org.springframework.http.converter包下找到所有spring帮我们实现好的转换器。
如果现有的转换器不能满足你的需求,你还可以实现org.springframework.http.converter.HttpMessageConverter接口自己写一个。详情参考官方api。
本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕,E-mail:xinmeigg88@163.com
本文链接:http://www.glev.cn/tnews/1330.html