Springboot使用OkHttp实现微信支付API-V3签名、证书的管理和使用( 二 )

decodeWxPlatCert(String json) {ObjectMapper mapper = new ObjectMapper();JsonNode jsonNode;JsonNode dataNode;try {jsonNode = mapper.readTree(json);dataNode = jsonNode.get("data");} catch (Exception e) {throw new RuntimeException("读取证书JSON失败", e);}SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");List certList = new ArrayList<>();for (JsonNode itemNode : dataNode) {JsonNode certNode = itemNode.get("encrypt_certificate");String cert = AesUtil.decryptJsonNodeToString(certNode);try {CertificateFactory cf = CertificateFactory.getInstance("X509");X509Certificate x509Cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getBytes(StandardCharsets.UTF_8)));x509Cert.checkValidity();WxPlatCertDO wxPlatCertDO = new WxPlatCertDO();wxPlatCertDO.setCertificate(x509Cert);wxPlatCertDO.setCert(cert);wxPlatCertDO.setEffectiveTime(format.parse(itemNode.get("effective_time").asText()));wxPlatCertDO.setExpireTime(format.parse(itemNode.get("expire_time").asText()));wxPlatCertDO.setSerialNumber(itemNode.get("serial_no").asText());certList.add(wxPlatCertDO);} catch (Exception e) {logger.error("update wx plat cert err", e);}}return certList;}/*** 封装的http get请求 , 直接使用即可 , 证书、签名的生成和校验已经集成* @param url* @param headerMap* @return*/public static String wxGet(String url, HashMap headerMap) {boolean lazyVerify = false;if (url.equals(CERT_LIST)) {//是下载证书的请求 , 允许延迟验签lazyVerify = true;}String token = generateToken(url, "get", null);headerMap = intHeader(headerMap);headerMap.put("Authorization", token);Request.Builder builder = new Request.Builder().url(url);for (Map.Entry entry : headerMap.entrySet()) {builder.addHeader(entry.getKey(), entry.getValue());}Request request = builder.build();try (Response response = getClient().newCall(request).execute()) {return checkResponseSign(response, lazyVerify);} catch (IOException e) {throw new RuntimeException("wx okHttp get err", e);}}/*** 封装的http post请求 , 直接使用即可 , 证书、签名的生成和校验已经集成* @param url* @param json* @param headerMap* @return*/public static String wxPost(String url, String json, HashMap headerMap) {RequestBody requestBody = RequestBody.create(json, MediaType.parse("application/json"));String token = generateToken(url, "post", json);headerMap = intHeader(headerMap);headerMap.put("Authorization", token);Request.Builder builder = new Request.Builder().url(url).post(requestBody);for (Map.Entry entry : headerMap.entrySet()) {builder.addHeader(entry.getKey(), entry.getValue());}try (Response response = getClient().newCall(builder.build()).execute()) {return checkResponseSign(response, false);} catch (IOException e) {throw new RuntimeException("wx okHttp post err", e);}}/*** 从微信下载微信平台证书* @return*/public static List getCertList() {String s = wxGet(CERT_LIST, null);return decodeWxPlatCert(s);}}上面的代码中 , 依赖了很多我自己写的其他类库 , 这里逐一介绍一下 。

  • OkHttpUtil 基于OkHttp封装的HTTP请求库 , 代码后面放 。
  • AesUtil 敏感信息解密的类 , 比如微信下载平台证书的请求 , 返回结果就是加密的 , 需要解密 。
  • WxCertUtil 主要有两个功能 , 一个是从本地文件读取商户自己的证书 , 给其他地方用;另一个是请求微信时 , 对敏感信息加密 , 这个功能和AesUtil是对应的 。
  • 各种POJO类 , 比如加载证书信息后 , 证书信息有一个POJO类 。这些类就不放代码了 , 每个人需求不一样 , 自己自定义即可 。 好吧 , 好多读者反馈需要 , 那我放到文章最后 。
package com.coderbbb.blogv2.utils;import okhttp3.*;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.SSLSession;import java.util.Collections;import java.util.HashMap;import java.util.Map;import java.util.concurrent.TimeUnit;public class OkhttpUtil {private static OkHttpClient client = null;private static final Logger logger = LoggerFactory.getLogger(OkhttpUtil.class);private synchronized static void createClient() {if (client == null) {OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();okHttpBuilder.protocols(Collections.singletonList(Protocol.HTTP_1_1));okHttpBuilder.connectTimeout(60, TimeUnit.SECONDS);okHttpBuilder.readTimeout(60, TimeUnit.SECONDS);okHttpBuilder.writeTimeout(60, TimeUnit.SECONDS);okHttpBuilder.hostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String s, SSLSession sslSession) {//支持所有类型https请求return true;}});ConnectionPool pool = new ConnectionPool(200, 1, TimeUnit.SECONDS);okHttpBuilder.connectionPool(pool);client = okHttpBuilder.build();client.dispatcher().setMaxRequests(2000);client.dispatcher().setMaxRequestsPerHost(1000);}}public static OkHttpClient getClient() {if (client == null) {createClient();}return client;}public static String get(String url, HashMap<String, String> headerMap) {Request.Builder builder = new Request.Builder().url(url);if (headerMap != null) {for (Map.Entry<String, String> entry : headerMap.entrySet()) {builder.addHeader(entry.getKey(), entry.getValue());}}Request request = builder.build();String result = null;try {result = excute(request);} catch (Exception e) {logger.warn("http get fail:" + url + "###" + e.getMessage());}return result;}public static String postRaw(String url, String contentType, String json, HashMap<String, String> headerMap) throws Exception {RequestBody requestBody = RequestBody.create(json,MediaType.parse(contentType));Request.Builder builder = new Request.Builder().url(url).post(requestBody);if (headerMap != null) {for (Map.Entry<String, String> entry : headerMap.entrySet()) {builder.addHeader(entry.getKey(), entry.getValue());}}Request request = builder.build();String result = null;try {result = excute(request);} catch (Exception e) {logger.error("http post raw fail:" + url + "###" + e.getMessage());}return result;}public static String post(String url, HashMap<String, String> data, HashMap<String, String> headerMap) throws Exception {FormBody.Builder formBodyBuilder = new FormBody.Builder();for (Map.Entry<String, String> entry : data.entrySet()) {formBodyBuilder.add(entry.getKey(), entry.getValue());}RequestBody requestBody = formBodyBuilder.build();Request.Builder builder = new Request.Builder().url(url).post(requestBody);for (Map.Entry<String, String> entry : headerMap.entrySet()) {builder.addHeader(entry.getKey(), entry.getValue());}Request request = builder.build();String result = null;try {result = excute(request);} catch (Exception e) {logger.error("http post fail:" + url + "###" + e.getMessage());}return result;}private static String excute(Request request) throws Exception {Response response = getClient().newCall(request).execute();ResponseBody body = response.body();if (body != null) {String str = body.string();body.close();response.close();return str;}return null;}}


推荐阅读