package com.care.common.util; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.care.client.dto.MpTemplateMsgOriginalDTO; import com.care.client.dto.WxTemplateDTO; import com.care.client.dto.WxUniformTemplateDTO; import com.care.client.vo.WxAccessTokenVO; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.RequestMethod; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import java.security.SecureRandom; /** * 微信接口访问工具封装 */ @Slf4j public class WxTemplateUtil { /** * 获取access_token的接口地址(GET) 限200(次/天) */ public final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; /** * 发送模板消息(POST) */ public final static String SEND_TEMPLATE_URL_OLD = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN"; /** * 发送模板消息(POST) */ public final static String SEND_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN"; /** * 获取微信用户数据 */ private final static String SEND_USER_OPENID_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; /** * 接口描述:请求工具 * @params [requestUrl, requestMethod, outputStr] * @return net.sf.json.JSONObject */ public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 创建SSLContext对象,并使用我们指定的信任管理器初始化 TrustManager[] tm = {new MyX509TrustManager()}; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new SecureRandom()); // 从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 设置请求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if(RequestMethod.GET.equals(requestMethod)){ httpUrlConn.connect(); } // 当有数据需要提交时 if(null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 释放资源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONUtil.parseObj(buffer.toString()); } catch (ConnectException ce) { System.out.println("Weixin server connection timed out."); } catch (Exception e) { System.out.println("https request error:{}" + e); } return jsonObject; } /** * 接口描述:获取access_token * @params [appId, appSecret] * @return com.gzschool.prismtestcms.model.vo.WxAccessTokenVO */ public static WxAccessTokenVO getAccessToken(String appId, String appSecret) { WxAccessTokenVO wxAccessTokenVO = null; String requestUrl = ACCESS_TOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecret); log.error("获取token的URL:"+ requestUrl); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); log.error("获取token返回的对象:"+ jsonObject.toString()); // 如果请求成功 if (null != jsonObject) { try { wxAccessTokenVO = new WxAccessTokenVO(); wxAccessTokenVO.setAccessToken(jsonObject.getStr("access_token")); wxAccessTokenVO.setExpiresIn(jsonObject.getInt("expires_in")); if (StringUtils.isBlank(wxAccessTokenVO.getAccessToken())) { return null; } } catch (Exception e) { wxAccessTokenVO = null; // 获取token失败 log.error("WxTemplateUtil获取token失败",e); } } return wxAccessTokenVO; } /** * 解析公众号订阅/取消时用户信息 * @param accessToken * @param openId * @return */ public static JSONObject parseWxOpenIdBySubscribe(String accessToken, String openId) { if (StringUtils.isBlank(accessToken) || StringUtils.isBlank(openId)) { return null; } String requestUrl = SEND_USER_OPENID_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId); return httpRequest(requestUrl, "GET", null); } /** * 接口描述:消息模板发送 * @params [wxTemplateDTO, accessToken] * @return net.sf.json.JSONObject */ public static JSONObject sendTemplateMsg(MpTemplateMsgOriginalDTO mpTemplateMsgOriginalDTO, String accessToken) { String url = SEND_TEMPLATE_URL_OLD.replace("ACCESS_TOKEN", accessToken); // 将模板数据对象转换成json字符串 String wxTemplate = JSONUtil.toJsonStr(mpTemplateMsgOriginalDTO); //发送请求 JSONObject result = httpRequest(url, "POST", wxTemplate); if (result != null) { return result; } else{ return null; } } /** * 接口描述:消息模板发送 * @params [wxTemplateDTO, accessToken] * @return net.sf.json.JSONObject */ public static JSONObject sendTemplateMsg(WxUniformTemplateDTO wxUniformTemplateDTO, String accessToken) { String url = SEND_TEMPLATE_URL.replace("ACCESS_TOKEN", accessToken); // 将模板数据对象转换成json字符串 String wxTemplate = JSONUtil.toJsonStr(wxUniformTemplateDTO); //发送请求 JSONObject result = httpRequest(url, "POST", wxTemplate); if (result != null) { return result; } else{ return null; } } }