JAVA微信公众号通过openid发送模板消息~
Posted 七号房子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA微信公众号通过openid发送模板消息~相关的知识,希望对你有一定的参考价值。
1,问题产生
在微信公众号开发过程中,我们有时候做不同权限的时候,比如在注册的时候,需要审核,然后我们要想办法让对方知道审核的结果。这时候我们可以通过模板消息来通知。
2,第一步,首先在微信公众号上获取模板消息
首先,登录微信公众平台,看有没有模板消息这一块,没有的话点击添加功能插件,去添加,这里就省略不说了,这个主要就是选择你公众号的行业对应的模板消息,然后通过审核之后就可以使用了,说是几个工作日
但是一般很快就审核通过的。
有模板消息之后点进来,对应自己所需要的模板消息进行添加,比如,我添加了一个审核的模板,在模板使用介绍上面其实也是没说的很清楚,我看了感觉完全就是不会用,就是给你个数据类型,数据样式查看
好了,这些大概百度下了解是什么意思,我们现在主要还是上代码部分吧。
3,用JAVA代码实现通过openid发送模板消息
(一)首先我们先上一个工具类
1 import java.io.BufferedReader; 2 import java.io.InputStream; 3 import java.io.InputStreamReader; 4 import java.io.OutputStream; 5 import java.net.ConnectException; 6 import java.net.URL; 7 8 import javax.net.ssl.HttpsURLConnection; 9 import javax.net.ssl.SSLContext; 10 import javax.net.ssl.SSLSocketFactory; 11 import javax.net.ssl.TrustManager; 12 13 import net.sf.json.JSONException; 14 import net.sf.json.JSONObject; 15 16 import org.slf4j.Logger; 17 import org.slf4j.LoggerFactory; 18 19 import com.mj.agriculturalByProduct.templatemessage.pojo.Token; 20 import com.mj.templatemessage.util.MyX509TrustManager; 21 22 public class CommonUtil { 23 24 private static Logger log = LoggerFactory.getLogger(CommonUtil.class); 25 26 // 凭证获取(GET) 27 public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; 28 29 /** 30 * 发送 https 请求 31 * 32 * @param requestUrl 请求地址 33 * @param requestMethod 请求方式(GET、POST) 34 * @param outputStr 提交的数据 35 * @return JSONObject(通过 JSONObject.get(key) 的方式获取 JSON 对象的属性值) 36 */ 37 public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { 38 39 JSONObject jsonObject = null; 40 41 try { 42 // 创建 SSLContext 对象,并使用我们指定的信任管理器初始化 43 TrustManager[] tm = { new MyX509TrustManager() }; 44 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); 45 sslContext.init(null, tm, new java.security.SecureRandom()); 46 // 从上述 SSLContext 对象中得到 SSLSocketFactory 对象 47 SSLSocketFactory ssf = sslContext.getSocketFactory(); 48 49 URL url = new URL(requestUrl); 50 HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 51 conn.setSSLSocketFactory(ssf); 52 53 conn.setDoOutput(true); 54 conn.setDoInput(true); 55 conn.setUseCaches(false); 56 57 // 设置请求方式(GET/POST) 58 conn.setRequestMethod(requestMethod); 59 60 // 当 outputStr 不为 null 时,向输出流写数据 61 if (null != outputStr) { 62 OutputStream outputStream = conn.getOutputStream(); 63 64 // 注意编码格式 65 outputStream.write(outputStr.getBytes("UTF-8")); 66 outputStream.close(); 67 } 68 69 // 从输入流读取返回内容 70 InputStream inputStream = conn.getInputStream(); 71 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 72 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 73 String str = null; 74 StringBuffer buffer = new StringBuffer(); 75 76 while ((str = bufferedReader.readLine()) != null) { 77 buffer.append(str); 78 } 79 80 // 释放资源 81 bufferedReader.close(); 82 inputStreamReader.close(); 83 inputStream.close(); 84 inputStream = null; 85 conn.disconnect(); 86 jsonObject = JSONObject.fromObject(buffer.toString()); 87 } catch (ConnectException ce) { 88 log.error(" 连接超时:{}", ce); 89 } catch (Exception e) { 90 log.error("https 请求异常:{}", e); 91 } 92 93 return jsonObject; 94 } 95 96 /** 97 * 获取接口访问凭证 98 * 99 * @param appid 凭证 100 * @param appsecret 密钥 101 * @return 102 */ 103 public static Token getToken(String appid, String appsecret) { 104 Token token = null; 105 String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret); 106 // 发起GET请求获取凭证 107 JSONObject jsonObject = httpsRequest(requestUrl, "GET", null); 108 109 if (null != jsonObject) { 110 try { 111 token = new Token(); 112 token.setAccessToken(jsonObject.getString("access_token")); 113 token.setExpiresIn(jsonObject.getInt("expires_in")); 114 System.out.println(jsonObject.getString("access_token")+"========="); 115 } catch (JSONException e) { 116 token = null; 117 // 获取token失败 118 log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); 119 } 120 } 121 return token; 122 } 123 124 }
public class Token {
//接口访问凭证
private String accessToken;
//接口有效期,单位:秒
private int expiresIn;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
}
(二)一个模板消息类
1 import java.text.SimpleDateFormat; 2 import java.util.Date; 3 4 import net.sf.json.JSONObject; 5 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 import org.springframework.stereotype.Service; 9 10 import com.mj.agriculturalByProduct.templatemessage.pojo.Data; 11 import com.mj.agriculturalByProduct.templatemessage.pojo.Data_style; 12 import com.mj.agriculturalByProduct.templatemessage.pojo.NewOrdersTemplate; 13 import com.mj.agriculturalByProduct.templatemessage.pojo.Token; 14 import com.mj.basic.util.TTResult; 15 @Service 16 public class Template { 17 18 private static Logger log = LoggerFactory.getLogger(Template.class); 19 20 /** 21 * 发送模板消息 22 * appId 公众账号的唯一标识 23 * appSecret 公众账号的密钥 24 * openId 用户标识 25 * @return 26 */ 27 public TTResult send_template_message(String appId, String appSecret, String openId) { 28 //因为我申请的模板是需要填写当前时间戳的,所以在这里我获取了当前的时间 29 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-HH-MM"); 30 String format = simpleDateFormat.format(new Date()); 31 Token token = CommonUtil.getToken(appId, appSecret);//这里要注意,如果你是申请的正式公众号的话,获取token的时候,一定要在后台加上你的ip,不然获取token的时候会报错 32 String access_token = token.getAccessToken(); 33 String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+access_token; 34 String templateId = "填写你所使用的模板id"; 35 String goUrl = "填写接收模板消息之后,你想要跳转的url页面。"; 36 37 Data_style first = new Data_style(); 38 Data_style keyword1 = new Data_style(); 39 Data_style keyword2 = new Data_style(); 40 Data_style remark = new Data_style(); 41 42 NewOrdersTemplate temp = new NewOrdersTemplate(); 43 Data data = new Data(); 44 45 first.setValue(format); 46 first.setColor("#173177"); 47 48 keyword1.setValue("您申请的审核已通过,请到PC端浏览器输入以下链接进行管理后台的设置:(这些都是自定义内容)" 49 + "自定义内容"); 50 keyword1.setColor("#173177"); 51 52 keyword2.setValue(format); 53 keyword2.setColor("#173177"); 54 55 remark.setValue(""); 56 remark.setColor("#173177"); 57 58 data.setFirst(first); 59 data.setKeyword1(keyword1); 60 data.setKeyword2(keyword2); 61 data.setRemark(remark); 62 63 temp.setTouser(openId); 64 temp.setTemplate_id(templateId); 65 temp.setUrl(goUrl); 66 temp.setTopcolor("#173177"); 67 temp.setData(data); 68 69 String jsonString = JSONObject.fromObject(temp).toString().replace("day", "Day"); 70 JSONObject jsonObject = CommonUtil.httpsRequest(url, "POST", jsonString); 71 System.out.println(jsonObject); 72 int result = 0; 73 if (null != jsonObject) { 74 if (0 != jsonObject.getInt("errcode")) { 75 result = jsonObject.getInt("errcode"); 76 log.error("错误 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); 77 } 78 } 79 log.info("模板消息发送结果:"+result); 80 return TTResult.ok(); 81 }
}
https://mp.weixin.qq.com/advanced/tmplmsg?action=faq&token=1244423508&lang=zh_CN 这个是模板消息接口文档地址。
上面的
Data_style first = new Data_style();
Data_style keyword1 = new Data_style();
Data_style keyword2 = new Data_style();
Data_style remark = new Data_style();
根据你实际的模板消息的参数个数添加修改。我这里是两个参数的模板。
(三)controller层接口
1 @Controller 2 public class TemplateController { 3 4 @Autowired 5 private Template template; 6 7 /** 8 * @param openid 9 * @param request 10 * @return 11 */ 12 @RequestMapping("/template/adopt") 13 public @ResponseBody TTResult test(String openid,HttpServletRequest request){ 14 try { 15 return template.send_template_message("你的APPID", "APPID对应的秘钥", openid); 16 //openid 你想发送给你公众号上的人 这个openid获取方法下次写,到这一步的话openid应该早就获取过了吧。 17 } catch (Exception e) { 18 // TODO: handle exception 19 } 20 return TTResult.fail(); 21 } 22 这个TTresult的话就是一个返回值的一个参数说明 这个大家的定义都不一样,这个无所谓的 就是 200成功 500失败 之类的 自定义code
(4)问我还是把我的TTresult贴出来吧
1 import java.util.List; 2 import com.fasterxml.jackson.databind.JsonNode; 3 import com.fasterxml.jackson.databind.ObjectMapper; 4 5 public class TTResult { 6 // 定义jackson对象 7 private static final ObjectMapper MAPPER = new ObjectMapper(); 8 9 // 响应业务状态 10 private Integer status; // 200 代表成功, 500 代表失败 11 12 // 响应消息 13 private String msg; 14 15 // 响应中的数据 16 private Object data; 17 18 public static TTResult build(Integer status, String msg, Object data) { 19 return new TTResult(status, msg, data); 20 } 21 22 public static TTResult ok(Object data) { 23 return new TTResult(data); 24 } 25 26 27 public static TTResult ok() { 28 return new TTResult(null); 29 } 30 31 public static TTResult fail(){ 32 return new TTResult(500,"fail",null); 33 } 34 35 public static TTResult fail(Object data){ 36 return new TTResult(500,"fail",data); 37 } 38 39 public TTResult() { 40 41 } 42 43 public static TTResult build(Integer status, String msg) { 44 return new TTResult(status, msg, null); 45 } 46 47 public TTResult(Integer status, String msg, Object data) { 48 this.status = status; 49 this.msg = msg; 50 this.data = data; 51 } 52 53 public TTResult(Object data) { 54 this.status = 200; 55 this.msg = "OK"; 56 this.data = data; 57 } 58 59 60 // public Boolean isOK() { 61 // return this.status == 200; 62 // } 63 64 public Integer getStatus() { 65 return status; 66 } 67 68 public void setStatus(Integer status) { 69 this.status = status; 70 } 71 72 public String getMsg() { 73 return msg; 74 } 75 76 public void setMsg(String msg) { 77 this.msg = msg; 78 } 79 80 public Object getData() { 81 return data; 82 } 83 84 public void setData(Object data) { 85 this.data = data; 86 } 87 88 /** 89 * 将json结果集转化为TTResult对象 90 * 91 * @param jsonData 92 * json数据 93 * @param clazz 94 * TTResult中的object类型 95 * @return 96 */ 97 public static TTResult formatToPojo(String jsonData, Class<?> clazz) { 98 try { 99 if (clazz == null) { 100 return MAPPER.readValue(jsonData, TTResult.class); 101 } 102 JsonNode jsonNode = MAPPER.readTree(jsonData); 103 JsonNode data = jsonNode.get("data"); 104 Object obj = null; 105 if (clazz != null) { 106 if (data.isObject()) { 107 obj = MAPPER.readValue(data.traverse(), clazz); 108 } else if (data.isTextual() || data.isNumber()) { 109 obj = MAPPER.readValue(data.asText(), clazz); 110 } 111 } 112 return build(jsonNode.get("status").intValue(), jsonNode.get("msg") 113 .asText(), obj); 114 } catch (Exception e) { 115 return null; 116 } 117 } 118 119 /** 120 * 没有object对象的转化 121 * 122 * @param json 123 * @return 124 */ 125 public static TTResult format(String json) { 126 try { 127 return MAPPER.readValue(json, TTResult.class); 128 } catch (Exception e) { 129 e.printStackTrace(); 130 } 131 return null; 132 } 133 134 /** 135 * Object是集合转化 136 * 137 * @param jsonData 138 * json数据 139 * @param clazz 140 * 集合中的类型 141 * @return 142 */ 143 public static TTResult formatToList(String jsonData, Class<?> clazz) { 144 try { 145 JsonNode jsonNode = MAPPER.readTree(jsonData); 146 JsonNode data = jsonNode.get("data"); 147 Object obj = null; 148 if (data.isArray() && data.size() > 0) { 149 obj = MAPPER.readValue(data.traverse(), MAPPER.getTypeFactory() 150 .constructCollectionType(List.class, clazz)); 151 } 152 return build(jsonNode.get("status").intValue(), jsonNode.get("msg") 153 .asText(), obj); 154 } catch (Exception e) { 155 return null; 156 } 157 } 158 }
MyX509TrustManager 工具类
import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; /** * 信任管理器 * */ public class MyX509TrustManager implements 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; } }
还有上面所用到的一些类,接口
public class Data_style { private String value; private String color; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } }
public class Data { private Data_style first; private Data_style keyword1; private Data_style keyword2; private Data_style remark; public Data_style getFirst() { return first; } public void setFirst(Data_style first) { this.first = first; } public Data_style getKeyword1() { return keyword1; } public void setKeyword1(Data_style keyword1) { this.keyword1 = keyword1; } public Data_style getKeyword2() { return keyword2; } public void setKeyword2(Data_style keyword2) { this.keyword2 = keyword2; } public Data_style getRemark() { return remark; } public void setRemark(Data_style remark) {以上是关于JAVA微信公众号通过openid发送模板消息~的主要内容,如果未能解决你的问题,请参考以下文章