Spring RestTemplate 调用https

Spring RestTemplate 调用REST API 给我们的开发工作带来了极大的方便, 默认的SimpleClientHttpRequestFactory 并不支持https的调用,我们可以通过引入Apache HttpClient实现对https的调用支持。

首先注册

package com.fly.config;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * 
 * 注册 RestTemplate
 * 
 * @author 00fly
 * @version [版本号, 2018年11月20日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Configuration
public class RestTemplateConfig
{
    @Bean
    public RestTemplate restTemplate()
    {
        ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient());
        return new RestTemplate(requestFactory);
    }
    
    /**
     * Apache HttpClient
     * 
     * @return
     * @see [类、类#方法、类#成员]
     */
    private HttpClient httpClient()
    {
        // 支持HTTP、HTTPS
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create()
            .register("http", PlainConnectionSocketFactory.getSocketFactory())
            .register("https", SSLConnectionSocketFactory.getSocketFactory())
            .build();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
        connectionManager.setMaxTotal(200);
        connectionManager.setDefaultMaxPerRoute(100);
        connectionManager.setValidateAfterInactivity(2000);
        RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(65000) // 服务器返回数据(response)的时间,超时抛出read timeout
            .setConnectTimeout(5000) // 连接上服务器(握手成功)的时间,超时抛出connect timeout
            .setConnectionRequestTimeout(1000)// 从连接池中获取连接的超时时间,超时抛出ConnectionPoolTimeoutException
            .build();
        return HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager).build();
    }
}

Spring 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
						http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context-4.3.xsd
						http://www.springframework.org/schema/aop 
						http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
						http://www.springframework.org/schema/tx 
						http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<!-- 使用默认扫描方式, 排除controller类注解 -->
	<context:component-scan base-package="com.fly" use-default-filters="true">
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
		<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
	</context:component-scan>
</beans>

单元测试代码

package com.fly.rest;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

/**
 * 
 * RestTest
 * 
 * @author 00fly
 * @version [版本号, 2018年11月20日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@RunWith(SpringRunner.class)
@ContextConfiguration({"/applicationContext.xml"})
public class RestTest
{
    private static final Logger LOGGER = LoggerFactory.getLogger(RestTest.class);
    
    @Autowired
    private RestTemplate restTemplate;
   
    
    @Test
    public void testHttps()
    {
        String url = "https://www.baidu.com/"; // 百度返回乱码
        url = "https://www.so.com/";
        String responseBody;
        
        responseBody = restTemplate.getForObject(url, String.class);
        LOGGER.info("responseBody={}", responseBody);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
        responseBody = restTemplate.postForObject(url, requestEntity, String.class);
        LOGGER.info("responseBody={}", responseBody);
    }
}

运行结果

2018-11-22 10:47:05 |INFO |main|Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.we
b.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.suppor
t.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.trans
action.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]|
2018-11-22 10:47:05 |INFO |main|Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@13c78c0b,
 org.springframework.test.context.support.DependencyInjectionTestExecutionListener@12843fce, org.springframework.test.context.support.DirtiesContextTestExecutio
nListener@3dd3bcd]|
2018-11-22 10:47:05 |INFO |main|Loading XML bean definitions from class path resource [applicationContext.xml]|
2018-11-22 10:47:06 |INFO |main|Refreshing org.springframework.context.support.GenericApplicationContext@6a41eaa2: startup date [Thu Nov 22 10:47:06 CST 2018]; 
root of context hierarchy|
2018-11-22 10:47:09 |INFO |main|responseBody=<!DOCTYPE html>
<!--[if lt IE 7 ]><html class="ie6"><![endif]-->
<!--[if IE 7 ]><html class="ie7"><![endif]-->
<!--[if IE 8 ]><html class="ie8"><![endif]-->
<!--[if IE 9 ]><html class="ie9"><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html class="w3c"><!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>360搜索,SO靠谱</title>
<link rel="dns-prefetch" href="//p.ssl.qhimg.com"><link rel="dns-prefetch" href="//s.ssl.qhimg.com"><link rel="dns-prefetch" href="//s.ssl.qhres.com">
<link rel="dns-prefetch" href="//p418.ssl.qhimgs4.com"><link rel="dns-prefetch" href="//p419.ssl.qhimgs4.com"><link rel="dns-prefetch" href="//p420.ssl.qhimgs4.
com">
<link rel="search" type="application/opensearchdescription+xml" href="https://www.so.com/soopensearch.xml" title="360搜索">
<meta name="keywords" content="360搜索,360搜索,网页搜索,视频搜索,图片搜索,音乐搜索,新闻搜索,软件搜索,学术搜索">
<meta name="description" content="360搜索是安全、精准、可信赖的新一代搜索引擎,依托于360母品牌的安全优势,全面拦截各类钓鱼欺诈等恶意网站,提供更放心的搜索服务。 360搜索 so靠谱。">
<meta content="always" name="referrer">
<noscript>
<img src="//s.qhupdate.com/so/click.gif?pro=so&pid=home&mod=noscript&t=1542854819" style="display:none">
<meta http-equiv="refresh" content="0; url=http://www.so.com/haosou.html?src=home">
</noscript>
<link rel="shortcut icon" href="https://s.ssl.qhres.com/static/52166db8c450f68d.ico" type="image/x-icon">
<script>var TIME = {_: +new Date}</script><script>(function(e,t){function n(e){return t.getElementById(e)}function r(){u("stc_nls",1,1)}function i(n,r){var i=""
;try{i=p[n]||"",i.length<99&&(u(r,0),t.documentElement.style.display="none",l(),e.onbeforeunload=null,location.reload(!0))}catch(s){l()}return i}function s(e,t)
{try{p[e]=t,t!==p[e]&&l()}catch(n){l()}}function o(e){var n=t.cookie.split("; ");for(var r=0,i=n.length,s;r<i;r++){s=n[r].split("=");if(s[0]===e)return s[1]}ret
......

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值