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.dbeile.cn/news/1180.html