httpclient、webClient和restTeamplate配置与使用

三者的的区别

httpClient是apache jakarta common下的项目。请求时是异步的,获取结果时是阻塞的。

        写起来比较复杂,需要手动关闭连接。4.X之后提供了异步的功能

restTeamplate是阻塞的,使用简单但是因为是阻塞的,所以在多线程情况下不理想

webClient是基于响应式的非阻塞,通过事件驱动

HttpClient

引入依赖

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

使用:

// 创建客户端
CloseableHttpClient client = HttpClients.createDefault();
HttpClientBuilder builder = HttpClients.custom();
// 通过builder设置Client
CloseableHttpClient client1 = builder.build();

// Get请求
HttpGet httpGet = new HttpGet("www.baidu.com");

HttpPost httpPost = new HttpPost();
httpPost.setURI(new URI("www.baidu.com"));
httpPost.setHeader("headerName","headerValue");
// 通过NameValuePair作为键值对存储,再通过list统一存到请求中
List<BasicNameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("name","value"));
httpPost.setEntity(new UrlEncodedFormEntity(params,"utf-8"));

// 也可以发送json格式参数
httpPost.setHeader("Content-Type","application/Json");
httpPost.setEntity(new StringEntity(objectMapper.writeValueAsString(传入的对象)));

CloseableHttpResponse response = client.execute(httpGet);
//CloseableHttpResponse response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
// 转字符串
String s = EntityUtils.toString(entity);
// 转数组
byte[] bytes = EntityUtils.toByteArray(entity);

RestTeamplate

配置参数:

http_pool.max_total=200
http_pool.default_max_per_route=100
http_pool.connect_timeout=5000
http_pool.connection_request_timeout=1000
http_pool.socket_timeout=65000
http_pool.validate_after_inactivity=2000
@Configuration
public class RestTemplateConfig {

    @Value("${http_pool.max_total}")
    private int maxTotal;

    @Value("${http_pool.default_max_per_route}")
    private int maxPerRoute;

    @Value("${http_pool.connect_timeout}")
    private int connTimeOut;

    @Value("${http_pool.connection_request_timeout}")
    private int connReqTimeOut;

    @Value("${http_pool.socket_timeout}")
    private int socketTimeout;

    @Value("${http_pool.validate_after_inactivity}")
    private int inactivity;

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

    @Bean
    public ClientHttpRequestFactory httpRequestFactory() {
        return new HttpComponentsClientHttpRequestFactory(httpClient());
    }

    @Bean
    public HttpClient httpClient() {
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
        connectionManager.setMaxTotal(maxTotal);
        connectionManager.setDefaultMaxPerRoute(maxPerRoute);
        connectionManager.setValidateAfterInactivity(inactivity);
        RequestConfig requestConfig = RequestConfig.custom()
                //服务器返回数据(response)的时间,超过抛出read timeout
                .setSocketTimeout(socketTimeout)
                //连接上服务器(握手成功)的时间,超出抛出connect timeout
                .setConnectTimeout(connTimeOut)
                //从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
                .setConnectionRequestTimeout(connReqTimeOut)
                .build();
        return HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .build();
    }
}

使用

Map<String,Object> operateInfo = restTemplate.getForObject(请求地址, 相应的类型HashMap.class);

WebClient

引入:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

配置:

@Configuration
public class WebClientConfig {

    @Bean
    ReactorResourceFactory resourceFactory() {
        ReactorResourceFactory factory = new ReactorResourceFactory();
        factory.setUseGlobalResources(false);
        factory.setConnectionProvider(ConnectionProvider.builder("httpClient")
                .maxConnections(50).pendingAcquireTimeout(Duration.ofSeconds(10)).build());
        factory.setLoopResources(LoopResources.create("httpClient", 50, true));
        return factory;
    }

    @Bean
    WebClient webClient() {
        Function<HttpClient, HttpClient> mapper = client ->
                client.tcpConfiguration(c ->
                        c.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10)
                                .option(ChannelOption.TCP_NODELAY, true)
                                .doOnConnected(conn -> {
                                    conn.addHandlerLast(new ReadTimeoutHandler(10));
                                    conn.addHandlerLast(new WriteTimeoutHandler(10));
                                }));

        ClientHttpConnector connector =
                new ReactorClientHttpConnector(resourceFactory(), mapper);

        return WebClient.builder().clientConnector(connector).build();
    }
}

使用:

Mono<Map> result = webClient.get().uri(请求地址)
                       .retrieve()//发送请求
                       .bodyToMono(Map.class) // 将响应转换成Mono,Mono对应单个数据/Flux对应多个数据
                       .doOnError(WebClientResponseException.class, err -> {
                            throw new RuntimeException("getDayPassengerflow error,error Message:"+err.getMessage());}
                       );当出现异常时的操作
Map<String,Object> data = (Map)((List)((Map)result.block().get("data"))).get(0);//获取响应内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值