欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RestTemplate

程序员文章站 2022-04-28 18:32:40
...

实验环境

  • JAVA8
  • Spring Boot 多模块架构

基础实现

pom.xml

<!-- HttpClient,如果底层需要使用HttpClient实现,则添加如下依赖 -->
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
</dependency>

application.yml

ConnectTimeout, 用来建立连接的时间,如果到了指定的时间,还没建立连接,则报异常。
ReadTiemout, 已经建立连接,并开始读取服务端资源。如果到了指定的时间,没有可能的数据被客户端读取,则报异常。

# 设置读取超时时间,连接超时时间为5s
project:
  restTemplate:
    # 客户端和服务端连接超时时间 ms
    connectTimeout: 5000 
    # 客户端和服务端读取数据的超时时间 ms
    readTimeout: 5000
    # 从连接池获取连接的超时时间,不宜过长
    connectionRequestTimeout: 200
    # 长连接保持时间 s
    timeToLive: 30
    # shezhi 总连接数
    maxTotal: 1000
    # 设置同路由的并发数
    defaultMaxPerRoute: 1000
    # 设置重置次数
    retryCount: 3
    # 缓冲数据请求,默认为true
    bufferRequestBody: false

ProjectRestTemplateConfig.java
RestTemplate配置类,用于RestTemplate类的实例化和配置。

@Configuration
public class RestTemplateConfig {
    @Value("${project.restTemplate.readTimeout}")
    private int readTimeout;

    @Value("${project.restTemplate.connectTimeout}")
    private int connectTimeout;

    @Value("${project.restTemplate.timeToLive}")
    private int timeToLive;

    @Value("${project.restTemplate.maxTotal}")
    private int maxTotal;

    @Value("${project.restTemplate.defaultMaxPerRoute}")
    private int defaultMaxPerRoute;

    @Value("${project.restTemplate.retryCount}")
    private int retryCount;

    @Value("${project.restTemplate.connectionRequestTimeout}")
    private int connectionRequestTimeout;

    @Value("${project.restTemplate.bufferRequestBody}")
    private boolean bufferRequestBody;

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }

    /**
     * 底层使用java.net包提供的方式创建Http连接请求
     */
    /*@Bean
    public ClientHttpRequestFactory clientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(readTimeout);
        factory.setConnectTimeout(connectTimeout);
        return factory;
    }*/

    /**
     * ClientHttpRequestFactory的另一种实现方式
     * 底层使用Httpclient连接池的方式创建Http连接请求
     * @return
     */
    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory() {
        // HttpClient连接池,长连接保持30秒
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(timeToLive, TimeUnit.SECONDS);

        // 设置总连接数
        connectionManager.setMaxTotal(maxTotal);
        // 设置同路由的并发数
        connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);

        // 设置header
        List<Header> headers = new ArrayList<>();
        headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));
        headers.add(new BasicHeader("Accept", "*/*"));
        // headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
        // headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));
        headers.add(new BasicHeader("Connection", "keep-alive"));

        // 创建HttpClient
        HttpClient httpClient = HttpClientBuilder.create()
                .setConnectionManager(connectionManager)
                .setDefaultHeaders(headers)
                .setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, true))
                .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy())
                .build();

        // 创建HttpComponentsClientHttpRequestFactory实例
        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory(httpClient);

        // 设置客户端和服务端建立连接的超时时间
        requestFactory.setConnectTimeout(connectTimeout);
        // 设置客户端从服务端读取数据的超时时间
        requestFactory.setReadTimeout(readTimeout);
        // 设置从连接池获取连接的超时时间,不宜过长
        requestFactory.setConnectionRequestTimeout(connectionRequestTimeout);
        // 缓冲请求数据,默认为true。通过POST或者PUT大量发送数据时,建议将此更改为false,以免耗尽内存
        requestFactory.setBufferRequestBody(bufferRequestBody);

        return requestFactory;
    }
}

RestTemplateUtils.java
构建发送Http请求的API, 主要分为发送Get请求和Post请求, 并注册为应用程序的服务。

@Service
public class RestTemplateUtils {
    @Autowired
    private RestTemplate restTemplate;

    private static final Logger log = LoggerFactory.getLogger(RestTemplateUtils.class);

    /**
     * @param url 请求链接
     * @param mapParam 请求参数
     * @return 如果请求出错则返回null, 请求成功则返回请求结果
     */
    public String postForObject(String url, MultiValueMap<String, ?> mapParam) {
        String result = null;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HttpEntity<MultiValueMap<String, ?>> request = new HttpEntity<>(mapParam, headers);

        try {
            result = restTemplate.postForObject(url, request, String.class);
        } catch (Exception e)
        {
            log.error("调用RestTemplateUtils.postForObject Exception, url=" + url + ",param=" + mapParam, e);
        }

        return result;
    }

    /**
     * @param url 请求链接
     * @param mapParam 请求参数
     * @return 如果请求出错则返回null, 请求成功则返回请求结果
     */
    public String postForEntity(String url, MultiValueMap<String, ?> mapParam) {
        String result = null;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HttpEntity<MultiValueMap<String, ?>> request = new HttpEntity<>(mapParam, headers);

        try {

            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
            result = response.getBody();
        } catch (Exception e) {
            log.error("调用RestTemplateUtils.postForEntity Exception, url=" + url + ",param=" + mapParam, e);
        }

        return result;
    }

    /**
     * @param url 请求链接
     * @param mapParam 请求参数
     * @return 如果请求出错则返回null, 请求成功则返回请求结果
     */
    public String getForObject(String url, Map<String, ?> mapParam) {
        String result = null;

        try {
            result = restTemplate.getForObject(url, String.class, mapParam);
        } catch (Exception e) {
            log.error("调用RestTemplateUtils.getForObject Exception, url=" + url + ",param=" + mapParam, e);
        }

        return result;
    }

    /**
     * @param url 请求链接
     * @param mapParam 请求参数
     * @return 如果请求出错则返回null, 请求成功则返回请求结果
     */
    public String getForEntity(String url, Map<String, ?> mapParam) {
        String result = null;

        try {
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class, mapParam);
            result = response.getBody();
        } catch (Exception e) {
            log.error("调用RestTemplateUtils.getForObject Exception, url=" + url + ",param=" + mapParam, e);
        }

        return result;
    }
}

UnitTest.java
发送送请求测试。

    private static final Logger log = LoggerFactory.getLogger(RestTemplateTest.class);

    @Autowired
    private RestTemplateUtils restTemplateUtils;

    @Test
    public void test() {
    	// 构建请求参数
        String accessToken = projectTokenUtils.getAccessTokenFromRedis();
        int pageStart = 0;
        int pageSize = 10;
        MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>(3);
        paramMap.add("accessToken", accessToken);
        paramMap.add("pageStart", String.valueOf(pageStart));
        paramMap.add("pageSize", String.valueOf(pageSize));

		// 发送请求
        String result = null;
        result = restTemplateUtils.postForEntity(ProjectConstants.URL, paramMap);

		// 解析返回结果
        JSONObject resultObj = JSON.parseObject(result);
        Assert.assertNotNull(result);
	
		// "200".equals(code)表示网络请求成功
        String code = resultObj.getString("code");
        Assert.assertEquals("200", code);

        System.out.println(resultObj);
    }

链接

Spring RestTemplate – Spring REST Client Example

相关标签: RestTemplate