美文网首页
HttpClient和ResetTemplate

HttpClient和ResetTemplate

作者: landscape_f117 | 来源:发表于2020-04-21 17:55 被阅读0次

相关依赖

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.2</version>
    </dependency>

Javadoc:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

代码

restTemplate配置类

D:\springbootdemo\src\main\java\cn\greenleaf\config\RestTemplateConfiguration.java

package cn.greenleaf.config;

import cn.greenleaf.common.RequestResponseLoggingInterceptor;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: Leon Liu
 * @Date: 2020/04/04/11:42
 * @Description:
 **/
@Configuration
public class RestTemplateConfiguration {
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        RestTemplate restTemplate = builder.build();
        //使用HttpClient代替默认的simpleClient
        restTemplate.setRequestFactory(clientHttpRequestFactory());
        // 使用 utf-8 编码集的 converter 替换默认的 converter(默认的 StringHttpMessageConverter 的编码集为"ISO-8859-1")
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        messageConverters.removeIf(converter -> converter instanceof StringHttpMessageConverter);
        //messageConverters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter); //去掉json自动解析
        messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        //设置拦截器
        restTemplate.setInterceptors(Collections.singletonList(new RequestResponseLoggingInterceptor()));
        return restTemplate;
    }

    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory() {
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        clientHttpRequestFactory.setHttpClient(httpClientBuilder().build());
        clientHttpRequestFactory.setConnectTimeout(3000); // 连接超时,毫秒
        clientHttpRequestFactory.setReadTimeout(10000); // 读写超时,毫秒
        clientHttpRequestFactory.setConnectionRequestTimeout(2000);
        return clientHttpRequestFactory;
    }

    @Bean
    public HttpClientBuilder httpClientBuilder() {
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        //设置HTTP连接管理器
        httpClientBuilder.setConnectionManager(poolingConnectionManager());
        return httpClientBuilder;
    }

    @Bean
    public HttpClientConnectionManager poolingConnectionManager() {
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(registry);
        poolingConnectionManager.setMaxTotal(1000); // 连接池最大连接数
        poolingConnectionManager.setDefaultMaxPerRoute(100); // 每个主机的并发

        //启动监控线程定时清除不活动的连接
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(new IdleConnectionMonitorThread(poolingConnectionManager),
                1000, 500, TimeUnit.MILLISECONDS);
        return poolingConnectionManager;
    }

    public static class IdleConnectionMonitorThread extends Thread {

        private final HttpClientConnectionManager connMgr;
        private volatile boolean shutdown;

        public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
            super();
            this.connMgr = connMgr;
        }

        @Override
        public void run() {
            synchronized (this) {
                // 关闭失效的连接
                connMgr.closeExpiredConnections();
                // 可选的, 关闭5秒内不活动的连接
                connMgr.closeIdleConnections(5, TimeUnit.SECONDS);
//                LoggerUtils.getLogger().debug("close idle connections");
            }
        }
    }
}

日志拦截器

D:\springbootdemo\src\main\java\cn\greenleaf\common\RequestResponseLoggingInterceptor.java

package cn.greenleaf.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.nio.charset.Charset;

/**
 * @Auther: Leon Liu
 * @Date: 2020/04/04/12:23
 * @Description:
 **/
public class RequestResponseLoggingInterceptor implements ClientHttpRequestInterceptor {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException
    {
        logRequest(request, body);
        ClientHttpResponse response = execution.execute(request, body);
        logResponse(response);

        //Add optional additional headers
        response.getHeaders().add("headerName", "VALUE");

        return response;
    }

    private void logRequest(HttpRequest request, byte[] body) throws IOException
    {
        if (log.isDebugEnabled())
        {
            log.debug("===========================request begin================================================");
            log.debug("URI         : {}", request.getURI());
            log.debug("Method      : {}", request.getMethod());
            log.debug("Headers     : {}", request.getHeaders());
            log.debug("Request body: {}", new String(body, "UTF-8"));
            log.debug("==========================request end================================================");
        }
    }

    private void logResponse(ClientHttpResponse response) throws IOException
    {
        if (log.isDebugEnabled())
        {
            log.debug("============================response begin==========================================");
            log.debug("Status code  : {}", response.getStatusCode());
            log.debug("Status text  : {}", response.getStatusText());
            log.debug("Headers      : {}", response.getHeaders());
            log.debug("Response body: {}", StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
            log.debug("=======================response end=================================================");
        }
    }
}

测试

D:\springbootdemo\src\test\java\cn\greenleaf\config\RestTemplateConfigurationTest.java

package cn.greenleaf.config;

import cn.greenleaf.domain.Cp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: Leon Liu
 * @Date: 2020/04/04/13:09
 * @Description:
 **/

@SpringBootTest
@RunWith(SpringRunner.class)
public class RestTemplateConfigurationTest {
    @Autowired
    RestTemplate restTemplate;

    @Test
    public void testGet() {
        restTemplate.getForObject("https://www.baidu.com", String.class);
    }

    @Test
    public void testPost() {
        Map map = new HashMap();
        map.put("offset", "0");
        map.put("page_size", "1");
        map.put("sign", "6fc9c71e4c5f5bf763f560d32b37bf17b5e6cd9e962ddd581e81b");
        Cp cp = restTemplate.postForObject("http://hybrid.xiaomi.com/test/audit_app_list/fetch/", null, Cp.class, map);
    }
}

相关文章

网友评论

      本文标题:HttpClient和ResetTemplate

      本文链接:https://www.haomeiwen.com/subject/rzepihtx.html