概述
制作本辅助类原因:公司服务器访问外网需要通过代理服务器,主要用于微信支付相关接口
作用:调用RestTemplate 时自动设置代理相关参数,
restTemplateCre 是设置带安全证书的(微信退款需要携带安全证书请求接口)
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
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.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.Map;
@Slf4j
@Component
public class RestTemplateUtil {
/**
* 代理ip地址
*/
@Value("${proxyHost}")
private String PROXY_HOST;
/**
* 代理 开关
*/
@Value("${proxySwitch}")
private boolean proxySwitch;
/**
* 代理服务器端口
*/
@Value("${proxyPort}")
private int PROXY_PORT;
/**
* 代理服务器用户名
*/
@Value("${proxyUserName}")
private String PROXY_USER_NAME;
/**
* 代理服务器密码
*/
@Value("${proxyPassword}")
private String PROXY_PASSWORD;
/**
* 微信mchId
*/
@Value("${WxPayConfig.mchId}")
private String mchId;
/**
* 证书地址
*/
@Value("${certificateUrl}")
private String certPath;
private static RestTemplate restTemplate;
private static RestTemplate restTemplateCre;
public byte[] postReByte(String url, Map map) throws Exception{
log.info("访问微信接口地址:{},参数:{}", url,JSON.toJSONString(map));
HttpHeaders headers = getHttpHeaders();
HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(map), headers);
byte[] result = this.restTemplate.postForEntity(url,entity,byte[].class).getBody();
log.info("-执行成功返回数据:{}",result);
return result;
}
public byte[] postReByteByXml(String url, String paramStr) throws Exception{
log.info("访问微信接口地址:{},参数:{}", url,paramStr);
HttpHeaders headers = getXMLHeaders();
HttpEntity<String> entity = new HttpEntity<>(paramStr, headers);
byte[] result = this.restTemplate.postForEntity(url,entity,byte[].class).getBody();
log.info("-执行成功返回数据:{}",result);
return result;
}
public String postReStringByXml(String url, String paramStr) throws Exception{
log.info("访问微信接口地址:{},参数:{}", url,paramStr);
HttpHeaders headers = getXMLHeaders();
HttpEntity<String> entity = new HttpEntity<>(paramStr, headers);
String result = this.restTemplate.postForEntity(url,entity,String.class).getBody();
log.info("-执行成功返回数据:{}",result);
return result;
}
public String getReStringByUrl(String url) throws Exception{
log.info("访问微信接口地址:{},参数:{}", url);
HttpHeaders headers = getXMLHeaders();
String result = this.restTemplate.getForEntity(url,String.class).getBody();
log.info("-执行成功返回数据:{}",result);
return result;
}
/**
* 需要证书代理
* @param url
* @param paramStr
* @return
* @throws Exception
*/
public String postReStringByXmlCret(String url, String paramStr) throws Exception{
log.info("访问微信接口地址:{},参数:{}", url,paramStr);
HttpHeaders headers = getXMLHeaders();
HttpEntity<String> entity = new HttpEntity<>(paramStr, headers);
String result = this.restTemplateCre.postForEntity(url,entity,String.class).getBody();
log.info("-执行成功返回数据:{}",result);
return result;
}
@Autowired
public void setRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
try {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
httpClientBuilder.setSSLContext(sslContext);
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory).build();// 注册http和https请求
// 开始设置连接池
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(
socketFactoryRegistry);
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
this.setProxy(restTemplate); //设置代理
this.setCredsProvider(httpClientBuilder); //设置代理密码
CloseableHttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient); // httpClient连接配置
restTemplate.setRequestFactory(clientHttpRequestFactory);
RestTemplateUtil.restTemplate = restTemplate;
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
log.error("初始化HTTP连接池出错", e);
}
}
@Autowired
public void setRestTemplateCre() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
try {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
KeyStore keyStore = null;
try {
keyStore = initCert(mchId, certPath);
} catch (Exception e) {
e.printStackTrace();
}
SSLContext sslcontext = SSLContext.getInstance("SSL");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { }
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { }
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
String alg = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(alg);
try {
keyManagerFactory.init(keyStore, mchId.toCharArray());
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
KeyManager[] kms = keyManagerFactory.getKeyManagers();
sslcontext.init(kms, new TrustManager[] { tm }, null);
httpClientBuilder.setSSLContext(sslcontext);
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslConnectionSocketFactory).build();// 注册http和https请求
// 开始设置连接池
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
this.setProxy(restTemplate); // 设置代理
this.setCredsProvider(httpClientBuilder); // 设置代理密码
HttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); // httpClient连接配置
restTemplate.setRequestFactory(clientHttpRequestFactory);
restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
RestTemplateUtil.restTemplateCre = restTemplate;
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
log.error("初始化HTTP连接池出错", e);
}
}
public void setProxy(RestTemplate restTemplate) {
if (proxySwitch && StringUtils.isBlank(PROXY_USER_NAME)) {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
requestFactory.setProxy(proxy);
restTemplate.setRequestFactory(requestFactory);
}
}
public void setCredsProvider(HttpClientBuilder httpClientBuilder) {
if (proxySwitch && StringUtils.isNotBlank(PROXY_USER_NAME)) {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(PROXY_HOST, PROXY_PORT),
new UsernamePasswordCredentials(PROXY_USER_NAME, PROXY_PASSWORD)
);
HttpHost proxy = new HttpHost(PROXY_HOST, PROXY_PORT);
httpClientBuilder.setProxy(proxy).setDefaultCredentialsProvider(credsProvider).disableCookieManagement();
}
}
public HttpHeaders getHttpHeaders() {
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
return headers;
}
public static HttpHeaders getXMLHeaders() {
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/x-www-form-urlencoded;charset=utf-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_XML.toString());
return headers;
}
/**
* 加载证书
*
* @param mchId 商户ID
* @param certPath 证书位置
* @throws Exception
*/
private static KeyStore initCert(String mchId, String certPath){
// 证书密码,默认为商户ID
String key = mchId;
// 证书的路径
String path = certPath;
// 指定读取证书格式为PKCS12
KeyStore keyStore = null;
try {
keyStore = KeyStore.getInstance("PKCS12");
} catch (KeyStoreException e) {
e.printStackTrace();
}
// 读取本机存放的PKCS12证书文件
// String currentPath = Thread.currentThread().getContextClassLoader().getResource(certPath).getPath();
// log.info("路径:{}", currentPath);
// FileInputStream instream = new FileInputStream(new File(currentPath));
InputStream instream = PropertiesUtil.class.getClassLoader().getResourceAsStream(certPath);
try {
// 指定PKCS12的密码(商户ID)
keyStore.load(instream, key.toCharArray());
Enumeration<String> aliasenum = keyStore.aliases();
String keyAlias = null;
if (aliasenum.hasMoreElements()) {
keyAlias = aliasenum.nextElement();
}
X509Certificate cert = (X509Certificate) keyStore
.getCertificate(keyAlias);
log.info("证书SerialNumber:{}", cert.getSerialNumber().toString());
} catch (Exception e) {
log.error("keyStoreException", e);
} finally {
try {
instream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return keyStore;
}
}
调用示例(代码有删减):
public class WXPayServiceImpl implements WXPayService {
@Autowired
private RestTemplateUtil restTemplateUtil;
public Map<String, String> orderquery(String outTradeNo) throws Exception {
String xmlParam = "";
Map<String, String> xmlToMap = new HashMap<String, String> ();
Map<String, String> map = new TreeMap<String, String>();
map.put("appid", appId);
map.put("sub_mch_id",subMchId );
map.put("mch_id", mchId);
map.put("nonce_str", CommonUtil.getUUID());
map.put("out_trade_no", outTradeNo);
String sign = WXPayUtil.createWxPaySign(merchantPlatformKey, map);
map.put("sign", sign);
xmlParam = WXPayUtil.mapToXml(map);
log.info(orderqueryUrl+"==================xmlParam 入参:" + xmlParam);
// 异常处理
String strXML = "";
try {
strXML =restTemplateUtil.postReStringByXml(orderqueryUrl, xmlParam);
xmlToMap = WXPayUtil.xmlToMap(strXML);
} catch (Exception e) {
log.error("=============访问微信接口异常==================",e);
xmlToMap.put("result_code", "SUCCESS");
xmlToMap.put("trade_state", "USERPAYING");
}
String return_code = xmlToMap.get("result_code");
if (!"SUCCESS".equals(return_code)) {
log.error(orderqueryUrl+"==================xmlParam 返回" + xmlToMap);
throw new OrderException(""+ xmlToMap.get("err_code_des") + xmlToMap.get("return_msg"));
}
return xmlToMap;
}
}
辅助类:
package com.cre.dmp.osp.dealer.utils;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@Slf4j
public class WXPayUtil {
public static void main(String[] args) {
}
public static String createWxPaySign(String signKey, Map<String, String> parameters) throws Exception {
StringBuilder sb = new StringBuilder(); // 多线程访问的情况下需要用StringBuffer
// Set es = parameters.keySet(); // 所有参与传参的key按照accsii排序(升序)
Map<String, String> sortMap = new TreeMap<String, String>(parameters);
for (Map.Entry<String, String> iterable_element : sortMap.entrySet()) {
sb.append(iterable_element.getKey()).append("=").append(iterable_element.getValue()).append("&");
}
sb.append("key=").append(signKey);
String sign = sb.toString();
log.info("========sign:"+sign);
return MD5(sign).toUpperCase();
}
/**
* 将Map转换为XML格式的字符串
*
* @param data Map类型数据
* @return XML格式的字符串
* @throws Exception
*/
public static String mapToXml(Map<String, String> data) throws Exception {
org.w3c.dom.Document document = WXPayXmlUtil.newDocument();
org.w3c.dom.Element root = document.createElement("xml");
document.appendChild(root);
for (String key: data.keySet()) {
String value = data.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString(); //.replaceAll("n|r", "");
try {
writer.close();
}
catch (Exception ex) {
}
return output;
}
/**
* XML格式字符串转换为Map
*
* @param strXML XML字符串
* @return XML数据转换后的Map
* @throws Exception
*/
public static Map<String, String> xmlToMap(String strXML) throws Exception {
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
data.put(element.getNodeName(), element.getTextContent());
}
}
try {
stream.close();
} catch (Exception ex) {
// do nothing
}
return data;
} catch (Exception ex) {
log.error("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
throw ex;
}
}
/**
* 生成 MD5
*
* @param data 待处理数据
* @return MD5结果
*/
public static String MD5(String data) throws Exception {
java.security.MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
}
最后
以上就是朴实音响为你收集整理的java 调用代理服务器(设置账号密码) 辅助类的全部内容,希望文章能够帮你解决java 调用代理服务器(设置账号密码) 辅助类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复