一:简介 通常在Java代码中调用其它http 接口的话会使用HttpClient,不过这个使用起来有些繁琐,Spring中推出了一个简单的RestTemplate用来调用rest api,使用起来非常简单。
二:基础示例
@RestController
@RequestMapping("/user")
public class UserController {@PostMapping("/regist")
public User regist(@RequestBody CreateUserDTO param) {
return new User(1L, param.getUsername());
}
}
RestTemplate 使用起来非常简单,创建一个模板对象,直接调用接口接口。RestTemplate中的方法都是以请求方法来作为前缀。
String url = "http://localhost:8080/user/regist";
CreateUserDTO param = new CreateUserDTO("monday", "123456");
RestTemplate restTemplate = new RestTemplate();
// 请求地址、请求参数、HTTP响应被转换成的对象类型
User user = restTemplate.postForObject(url, param, User.class);
System.out.println(user);
三:HttpMessageConverter RestTemplate调用接口发送参数会将参数转为json,同样在处理响应时也是json格式。而RestTemplate中的接口接收的参数是对象,返回值类型也是对象,这就需要将参数转为json,将返回值转为对象,这就需要用到HTTP消息转换器了。默认情况下RestTemplate自动帮我们注册了一组HttpMessageConverter用来处理一些不同的contentType的请求。
- StringHttpMessageConverter来处理 text/plain;
- MappingJackson2HttpMessageConverter来处理 application/json ;
- MappingJackson2XmlHttpMessageConverter来处理 application/xml
- HttpMessageConverter接口自定义转换器
文章图片
com.alibaba
fastjson
1.2.74
FastJsonConfig fastJsonConfig=new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
SerializerFeature.QuoteFieldNames,
SerializerFeature.WriteMapNullValue,
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.WriteNullStringAsEmpty);
List mediaTypeList=new ArrayList<>();
mediaTypeList.add(MediaType.APPLICATION_JSON);
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
fastJsonHttpMessageConverter.setSupportedMediaTypes(mediaTypeList);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
// 使用FastJsonHttpMessageConverter来处理json
RestTemplate restTemplate = new RestTemplate();
List> messageConverters = restTemplate.getMessageConverters();
messageConverters.remove(6);
messageConverters.add(fastJsonHttpMessageConverter);
四:设置底层连接参数 我们在使用httpclient时都会配置一些参数,如最大连接数、连接超时时间、重试次数等。RestTemplate直接使用httpclient中的配置类来配置RestTemplate。
org.apache.httpcomponents
httpclient
// 长连接保持30秒
PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);
// 总连接数
pollingConnectionManager.setMaxTotal(1000);
// 同路由的并发数
pollingConnectionManager.setDefaultMaxPerRoute(1000);
HttpClientBuilder httpClientBuilder = HttpClients.custom();
httpClientBuilder.setConnectionManager(pollingConnectionManager);
// 重试次数,默认是3次,没有开启
httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(2, true));
// 保持长连接配置,需要在头添加Keep-Alive
httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
List headers = new ArrayList<>();
headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate"));
headers.add(new BasicHeader("Accept-Language", "zh-CN"));
headers.add(new BasicHeader("Connection", "Keep-Alive"));
httpClientBuilder.setDefaultHeaders(headers);
HttpClient httpClient = httpClientBuilder.build();
// httpClient连接配置,底层是配置RequestConfig
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
// 指客户端和服务器建立连接的timeout,就是http请求的三个阶段,(1)建立连接(2)数据传送(3)断开连接,超时后会ConnectionTimeOutExceptioin。
clientHttpRequestFactory.setConnectTimeout(1000 * 10);
// 数据读取超时时间,即SocketTimeout
clientHttpRequestFactory.setReadTimeout(1000 * 40);
// 连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的,指从连接池取连接的timeout
clientHttpRequestFactory.setConnectionRequestTimeout(500);
// 缓冲请求数据,默认值是true。通过POST或者PUT大量发送数据时,建议将此属性更改为false,以免耗尽内存。
clientHttpRequestFactory.setBufferRequestBody(true);
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
五:拦截器 拦截器可以在发出请求之前统一进行拦截,对请求进行修改,如增加请求头(如 timestamp、token)等。自定义拦截器需要实现ClientHttpRequestInterceptor接口。
public class HttpHeadInterceptor implements ClientHttpRequestInterceptor {@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
String timestamp = String.valueOf(System.currentTimeMillis());
String body = new String(bytes);
String signature = body + timestamp + "key";
httpRequest.getHeaders().add("timestamp", timestamp);
httpRequest.getHeaders().add("nonce", UUID.randomUUID().toString());
httpRequest.getHeaders().add("sign", MD5Encoder.encode(signature.getBytes()));
return clientHttpRequestExecution.execute(httpRequest, bytes);
}
}
// 添加拦截器
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(new HttpHeadInterceptor());
【spring|SpringBoot使用RestTemplate调用接口】
推荐阅读
- Java小案例|Java小案例(台灯类Lamp,有开关on这个方法...)
- 常见的一些容器部署|CentOS7安装JDK8
- intellij-idea|MyBatis-Plus(四.Page分页查询)
- Java小案例|Jdbc数据库的连接工具类
- java|lamda表达式是啥(是如何来的呢?如何快速理解lamda表达式)
- lambda|Lamda表达式详解
- Spring MVC实现拦截器功能
- spark|莎士比亚统计最高的词频数 java,spark,rdd
- 工作记录|软件测试必备技能(抓包(一))