在SpringBoot项目中,当我们调用第三方接口时,一般有HttpClient和框架自带的RestTemplate两种,我下面用的框架自带的restTemplate
@Bean(name = "customRestTemplate")
public RestTemplate restTemplate(RestTemplateBuilder builder) {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(15000);//设置连接超时时间
factory.setReadTimeout(10000);//设置读取超时时间
restTemplate.setRequestFactory(factory);
return restTemplate;
}
通过配置构建一个简单的模板,再在工具类里引用一下就能实现最基本的调用:
@Resource
private RestTemplate customRestTemplate;
/**
* POST请求
* @param url 请求url
* @param jsonParams json参数
* @param headers 自定义请求头参数
* @param classz 返回类型
* @return
*/
public <T> T post(String url, String jsonParams, Map<String, String> headers, Class<T> classz) {
HttpHeaders headersContent = new HttpHeaders();
//headersContent.set("Content-Type",headers.get("Content-Type")); 自定义请求头
HttpEntity<String> entity = new HttpEntity<>(jsonParams, headersContent);
return customRestTemplate.postForObject(url, entity, classz, "1");
}
测试代码:
/*
*tyfoRequestUtils——是工具类的名称
*url:请求路径
*paramMap: 请求参数Map
*headers: 自定义请求头(没有的也可以改下上面方法,多加一个方法调用(headers为null)的情况)
*/
String result = tyfoRequestUtils.post(url, paramMap, headers, String.class);
重点:上面的方法在请求https接口时会出现SSL认证问题;也就是
nested exception is javax.net.ssl.SSLHandshakeException: No subject
alternative names matching IP address 192.168.00.00 found
这种错误
这是由于请求https回去认证证书,可以选择添加认证证书(没做过)具体可以去查别人的博客,我这里用的绕过认证请求到数据:
/**
* 访问第三方https 绕过/忽略 SSL认证
*
* @return RestTemplate
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
@Bean(name = "httpsRestTemplate")
public RestTemplate httpsRestTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
//配置信赖策略
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
// 配置NoopHostnameVerifier.INSTANCE (new NoopHostnameVerifier() 也行)
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
requestFactory.setConnectTimeout(15000);
requestFactory.setReadTimeout(10000);
return new RestTemplate(requestFactory);
}
工具类
/**
* 访问第三方https 绕过证书认证
* Post请求(调用第三方接口——form表单数据)
* @param url 请求url
* @param paramMap 参数map
* @param classz 返回类型(Object、String)
* @param <T>
* @return
*/
public <T> T post(String url, LinkedMultiValueMap<String, String> paramMap, Class<T> classz) {
HttpHeaders headers = new HttpHeaders();
//我是用LinkedMultiValueMap提交表单类型数据(可以自己改其他的)
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<LinkedMultiValueMap<String, String>> entity = new HttpEntity<>(paramMap, headers);
return httpsRestTemplate.postForObject(url, entity, classz, "1");
}
调用
//这是将自己的参数对象转为map
Map<String, String> entryMap = JSON.parseObject(JSONObject.toJSONString(integralOrderDto), Map.class);
//提交表单类型数据所以做了转换(不传map可以删掉这些,直接传)
LinkedMultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
for (Map.Entry<String, String> map : entryMap.entrySet()) {
paramMap.add(map.getKey(), map.getValue());
}
//调用返回数据(一般返回String、Object)
Object result = tyfoRequestUtils.post(url, paramMap, Object.class);
通过上面这些配置基本就能直接访问调用https的接口了,但是如果嫌麻烦还可以直接用Hutool的工具
1.在pom文件中引入依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.17</version>
</dependency>
2.直接使用
String post = HttpUtil.post(url, JSONObject.toJSONString(integralOrderDto));
用Hutool很方便,直接就能请求,拿到返回的数据自己在转换解析就行。