SpringBoot使用RestTemplate调用接口

一:简介

通常在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接口自定义转换器

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.74</version>
</dependency>
FastJsonConfig fastJsonConfig=new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
        SerializerFeature.QuoteFieldNames,
        SerializerFeature.WriteMapNullValue,
        SerializerFeature.DisableCircularReferenceDetect,
        SerializerFeature.WriteDateUseDateFormat,
        SerializerFeature.WriteNullStringAsEmpty);

List<MediaType> 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<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
messageConverters.remove(6);
messageConverters.add(fastJsonHttpMessageConverter);

四:设置底层连接参数

我们在使用httpclient时都会配置一些参数,如最大连接数、连接超时时间、重试次数等。RestTemplate直接使用httpclient中的配置类来配置RestTemplate。

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
// 长连接保持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<Header> 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());

猜你喜欢

转载自blog.csdn.net/aa119101/article/details/125285641