spring boot resttemplate 使用及支持https协议
RestTemplate 使用
-
添加httpclient依赖
<!-- httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency>
-
配置类
package net.fanci.stars.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.RestTemplate; import java.util.Arrays; import java.util.List; /** * @author xxx * @create 2018/06/28 15:32 * @description RestTemplate配置类: * 1.将 HttpClient 作为 RestTemplate 的实现,添加 httpclient 依赖即可 * 2.设置响应类型和内容类型 */ @Configuration public class RestConfiguration { @Autowired private RestTemplateBuilder builder; @Bean public RestTemplate restTemplate() { return builder .additionalMessageConverters(new WxMappingJackson2HttpMessageConverter()) .build(); } class WxMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter { WxMappingJackson2HttpMessageConverter() { List<MediaType> mediaTypes = Arrays.asList( MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON_UTF8 ); setSupportedMediaTypes(mediaTypes);// tag6 } } }
-
使用方法(如:通过微信code获取token信息)
@Autowired private RestTemplate restTemplate; /** * 获取access_token的完整信息 * * @param code * @return */ @Override public WechatAuthAccesstoken getWechatAuthAccesstoken(String code) { String url = ACCESS_TOKEN_URL + "appid=" + wechatData.getAppID() + "&secret=" + wechatData.getAppsecret() + "&code=" + code + "&grant_type=authorization_code"; // com.alibaba.fastjson JSONObject jsonObject = restTemplate.getForObject(url, JSONObject.class); WechatAuthAccesstoken wechatAuthAccesstoken = new WechatAuthAccesstoken(); if (jsonObject != null) { wechatAuthAccesstoken.setId(PayUtil.genUniqueKey()); wechatAuthAccesstoken.setCreatedDate(DateTime.now().toDate()); wechatAuthAccesstoken.setModifiedDate(DateTime.now().toDate()); wechatAuthAccesstoken.setAccessToken((String) jsonObject.get("access_token")); DateTime now = DateTime.now(); DateTime expired = now.plusSeconds((Integer) jsonObject.get("expires_in")); wechatAuthAccesstoken.setExpires(expired.toDate()); wechatAuthAccesstoken.setRefreshToken(jsonObject.getString("refresh_token")); wechatAuthAccesstoken.setOpenid((String) jsonObject.get("openid")); wechatAuthAccesstoken.setScope(jsonObject.getString("scope")); int isOk = tokenMapper.insert(wechatAuthAccesstoken); if (isOk > 0) { logger.info("本地存储access_token信息成功"); return wechatAuthAccesstoken; } else { logger.error("本地存储access_token信息失败"); } } else { logger.error("获取access_token信息失败"); } return null; }
https支持
-
配置类
import org.springframework.http.client.SimpleClientHttpRequestFactory; import javax.net.ssl.*; import java.io.IOException; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.Socket; import java.security.cert.X509Certificate; /** * @author xxx * @create 2018/07/16 11:41 * @description 创建 HttpsClientRequestFactory 以支持 RestTemplate 调用 https 请求 */ public class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory { @Override protected void prepareConnection(HttpURLConnection connection, String httpMethod) { try { if (!(connection instanceof HttpsURLConnection)) { throw new RuntimeException("An instance of HttpsURLConnection is expected"); } HttpsURLConnection httpsConnection = (HttpsURLConnection) connection; TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); httpsConnection.setSSLSocketFactory(new MyCustomSSLSocketFactory(sslContext.getSocketFactory())); httpsConnection.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }); super.prepareConnection(httpsConnection, httpMethod); } catch (Exception e) { e.printStackTrace(); } } /** * We need to invoke sslSocket.setEnabledProtocols(new String[] {"SSLv3"}); * see http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html (Java 8 section) */ private static class MyCustomSSLSocketFactory extends SSLSocketFactory { private final SSLSocketFactory delegate; public MyCustomSSLSocketFactory(SSLSocketFactory delegate) { this.delegate = delegate; } @Override public String[] getDefaultCipherSuites() { return delegate.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return delegate.getSupportedCipherSuites(); } @Override public Socket createSocket(final Socket socket, final String host, final int port, final boolean autoClose) throws IOException { final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose); return overrideProtocol(underlyingSocket); } @Override public Socket createSocket(final String host, final int port) throws IOException { final Socket underlyingSocket = delegate.createSocket(host, port); return overrideProtocol(underlyingSocket); } @Override public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort) throws IOException { final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort); return overrideProtocol(underlyingSocket); } @Override public Socket createSocket(final InetAddress host, final int port) throws IOException { final Socket underlyingSocket = delegate.createSocket(host, port); return overrideProtocol(underlyingSocket); } @Override public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress, final int localPort) throws IOException { final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort); return overrideProtocol(underlyingSocket); } private Socket overrideProtocol(final Socket socket) { if (!(socket instanceof SSLSocket)) { throw new RuntimeException("An instance of SSLSocket is expected"); } ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1"}); return socket; } } }
-
使用类
String message = null; String url = "https://ip:port/xxx"; RestTemplate restTemplateHttps = new RestTemplate(new HttpsClientRequestFactory()); List<HttpMessageConverter<?>> messageConverters = new ArrayList<>(); StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8")); messageConverters.add(stringHttpMessageConverter); restTemplateHttps.setMessageConverters(messageConverters); ResponseEntity<String> responseEntity = restTemplateHttps.postForEntity(url, paramsData, String.class); if (responseEntity != null && responseEntity.getStatusCodeValue() == 200) { message = responseEntity.getBody(); }