无法在这个位置找到: head2.htm
当前位置: 建站首页 > 合作伙伴 >

静态网页设计模板

时间:2020-12-29 00:20来源:静态网页设计模板 作者:jianzhan 点击:
静态网页设计模板:java实现微信公众平台发送模板消息的示例代码 java实现微信公众平台发送模板消息的示例代码 更新2019年09月06日 作者:Jello 这篇文章主要介绍了java实现微信公众

静态网页设计模板:java实现微信公众平台发送模板消息的示例代码

java实现微信公众平台发送模板消息的示例代码  更新2019年09月06日   作者:Jello   这篇文章主要介绍了java实现微信公众平台发送模板消息的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

最近开发公众号项目,前端采用vue开发,后台使用java开发,由于业务需求,需要实现公众号向用户发送重要的服务通知,提醒工作人员进行业务审核。这时候就需要用到微信平台的模板消息,为了保证用户不受到骚扰,在开发者出现需要主动提醒、通知用户时,才允许开发者在公众平台网站中模板消息库中选择模板,选择后获得模板ID,再根据模板ID向用户主动推送提醒、通知消息。常用的服务场景,如信用卡刷卡通知,商品下单成功、购买成功通知等。

获取template_id(注意:仅微信开放平台同事可获取)

通过向微信公众平台申请模板,来获取模板id,模板消息调用时主要需要模板ID和模板中各参数的赋值内容。请注意:
1.模板中参数内容必须以".DATA"结尾,否则视为保留字;
2.模板保留符号"{{ }}"

下图是在微信测试公众号申请模板

请求模板消息接口

1)微信网页授权

 //前端发请请求
 this.axios.get('/wx/get_code_num').then((res) = {
 window.location.href = res.data;
 }).catch((error) = {
 console.log(error)
 * 1.用户同意授权,获取code
 @RequestMapping(value = "/get_code_num", method = RequestMethod.GET)
 public String getCode() throws UnsupportedEncodingException {
 return "https://open.weixin.qq.com/connect/oauth2/authorize appid=" + Constants.APPID + " redirect_uri="
 + URLEncoder.encode("http://192.168.0.152:8085/wx/send_wx_msg", "UTF-8") + " response_type=code scope="
 + Constants.GRANTSCOPE + " state=STATE#wechat_redirect";
 } 


2)获取用户openid

 * 2.通过code换取网页授权access_token及openid
@RequestMapping(value = "/send_wx_msg", method = RequestMethod.GET)
public String sendWxMsg(String code) {
 String access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token";
 String accessTokenObj = HttpClientUtil.sendGet(access_token_url, "appid=" + Constants.APPID + " secret="
 + Constants.APPSECRET + " code=" + code + " grant_type=authorization_code");
 JSONObject jsonToken = JSONObject.fromObject(accessTokenObj);
 String openId = null;
 if (StringUtils.isNotBlank(String.valueOf(jsonToken))) {
 openId = jsonToken.getString("openid");
 logger.info("获取openid,微信平台接口返回{}", openId);
 return openId;
}

3)组装、发送模板消息

import java.util.TreeMap;
public class WechatTemplate {
 private String touser;//用戶openid
 private String template_id;//模板ID
 private String url;//URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)
 private TreeMap String, TreeMap String, String data; //data数据
 public static TreeMap String, String item(String value, String color) {
 TreeMap String, String params = new TreeMap String, String 
 params.put("value", value);
 params.put("color", color);
 return params;
 public TreeMap String, TreeMap String, String getData() {
 return data;
 public void setData(TreeMap String, TreeMap String, String data) {
 this.data = data;
 public String getTouser() {
 return touser;
 public void setTouser(String touser) {
 this.touser = touser;
 public String getTemplate_id() {
 return template_id;
 public void setTemplate_id(String template_id) {
 this.template_id = template_id;
 public String getUrl() {
 return url;
 public void setUrl(String url) {
 this.url = url;
 @Override
 public String toString() {
 return "WechatTemplate{" +
 "touser='" + touser + '\'' +
 ", template_id='" + template_id + '\'' +
 ", url='" + url + '\'' +
 ", data=" + data +
 '}';
}

//微信模板接口 private final String SEND_TEMPLATE_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send"; //模板消息详情跳转URL private static String url = "https://www.baidu.com/"; @RequestMapping(value = "/send_wx_msg", method = RequestMethod.GET) public String sendWxMsg(String code) { String access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token"; String accessTokenObj = HttpClientUtil.sendGet(access_token_url, "appid=" + Constants.APPID + " secret=" + Constants.APPSECRET + " code=" + code + " grant_type=authorization_code"); JSONObject jsonToken = JSONObject.fromObject(accessTokenObj); String openId = null; if (StringUtils.isNotBlank(String.valueOf(jsonToken))) { openId = jsonToken.getString("openid"); logger.info("获取openid,微信平台接口返回{}", openId); String urlToken = "https://api.weixin.qq.com/cgi-bin/token"; String tokenObj = HttpClientUtil.sendGet(urlToken, "grant_type=client_credential" + " secret=" + Constants.APPSECRET + " appid=" + Constants.APPID); JSONObject retToken = JSONObject.fromObject(tokenObj); String accessToken = String.valueOf(retToken.get("access_token")); logger.info("获取access_token,微信平台接口返回{}", accessToken); TreeMap String, TreeMap String, String params = new TreeMap String, TreeMap String, String (); //根据具体模板参数组装 params.put("first", WechatTemplate.item("您的户外旅行活动订单已经支付完成,可在我的个人中心中查看", "#000000")); params.put("keyword1", WechatTemplate.item("发现尼泊尔—人文与自然的旅行圣地", "#000000")); params.put("keyword2", WechatTemplate.item("5000元", "#000000")); params.put("keyword3", WechatTemplate.item("2019.09.04", "#000000")); params.put("keyword4", WechatTemplate.item("5", "#000000")); params.put("remark", WechatTemplate.item("请届时携带好身份证件准时到达集合地点,若临时退改将产生相应损失,敬请谅解,谢谢!", "#000000")); WechatTemplate wechatTemplate = new WechatTemplate(); wechatTemplate.setTemplate_id(Constants.TEMPLATEID); wechatTemplate.setTouser(openId); wechatTemplate.setUrl(url); wechatTemplate.setData(params); JSONObject json = JSONObject.fromObject(wechatTemplate);//将java对象转换为json对象 String sendData = json.toString();//将json对象转换为字符串 logger.info("板参数组装{}", sendData); TreeMap String, String treeMap = new TreeMap String, String treeMap.put("access_token", accessToken); String retInfo = HttpUtil.doPost(SEND_TEMPLATE_MESSAGE_URL, treeMap, sendData); logger.info("消息模板返回{}", retInfo); return retInfo; }

请求的数据格式

 "data": {
 "first": {
 "color": "#000000",
 "value": "您的户外旅行活动订单已经支付完成,可在我的个人中心中查看"
 "keyword1": {
 "color": "#000000",
 "value": "发现尼泊尔—人文与自然的旅行圣地"
 "keyword2": {
 "color": "#000000",
 "value": "5000元"
 "keyword3": {
 "color": "#000000",
 "value": "2019.09.04"
 "keyword4": {
 "color": "#000000",
 "value": "5"
 "remark": {
 "color": "#000000",
 "value": "请届时携带好身份证件准时到达集合地点,若临时退改将产生相应损失,敬请谅解,谢谢!"
 "template_id": "ZUMTnYtG0O4vZSv4bPTtWTOFZ2zirOjaM50GYywRRnA",
 "touser": "olv_asx8nmggCQEmAFNbQstx3xd0",
 "url": "https://www.baidu.com/"
}

微信平台返回的结果:


微信公众号通知消息


工具类:

import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
public class HttpUtil {
 private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
 protected static final String POST_METHOD = "POST";
 private static final String GET_METHOD = "GET";
 static {
 TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
 @Override
 public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
 logger.debug("ClientTrusted");
 @Override
 public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
 logger.debug("ServerTrusted");
 @Override
 public X509Certificate[] getAcceptedIssuers() {
 return new X509Certificate[]{};
 HostnameVerifier doNotVerify = (s, sslSession) - true;
 try {
 SSLContext sc = SSLContext.getInstance("SSL", "SunJSSE");
 sc.init(null, trustAllCerts, new SecureRandom());
 HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
 HttpsURLConnection.setDefaultHostnameVerifier(doNotVerify);
 } catch (Exception e) {
 logger.error("Initialization https impl occur exception : {}", e);

private static String HttpDefaultExecute(String url, String method, Map String, String map, String data) { String result = ""; try { url = setParmas(url, map, null); result = defaultConnection(url, method, data); } catch (Exception e) { logger.error("出错参数 {}", map); return result; public static String httpGet(String url, Map String, String map) { return HttpDefaultExecute(url, GET_METHOD, map, null); public static String httpPost(String url, Map String, String map, String data) { return HttpDefaultExecute(url, POST_METHOD, map, data); * 默认的https执行方法,返回 * @param url url 路径 * @param method 请求的方法 POST/GET * @param map 请求参数集合 * @param data 输入的数据 允许为空 * @return result private static String HttpsDefaultExecute(String url, String method, Map String, String map, String data) { try { url = setParmas(url, map, null); logger.info(data); return defaultConnection(url, method, data); } catch (Exception e) { logger.error("出错参数 {}", map); return ""; public static String doGet(String url, Map String, String map) { return HttpsDefaultExecute(url, GET_METHOD, map, null); public static String doPost(String url, Map String, String map, String data) { return HttpsDefaultExecute(url, POST_METHOD, map, data); * @param path 请求路径 * @param method 方法 * @param data 输入的数据 允许为空 * @return * @throws Exception private static String defaultConnection(String path, String method, String data) throws Exception { if (StringUtils.isBlank(path)) { throw new IOException("url can not be null"); String result = null; URL url = new URL(path); HttpURLConnection conn = getConnection(url, method); if (StringUtils.isNotEmpty(data)) { OutputStream output = conn.getOutputStream(); output.write(data.getBytes(StandardCharsets.UTF_8)); output.flush(); output.close(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream input = conn.getInputStream(); result = IOUtils.toString(input, StandardCharsets.UTF_8); input.close(); conn.disconnect(); // log.info(result); return result; * 根据url的协议选择对应的请求方式 * @param url 请求路径 * @param method 方法 * @return conn * @throws IOException 异常 //待改进 protected static HttpURLConnection getConnection(URL url, String method) throws IOException { HttpURLConnection conn; if (StringUtils.equals("https", url.getProtocol())) { conn = (HttpsURLConnection) url.openConnection(); } else { conn = (HttpURLConnection) url.openConnection(); if (conn == null) { throw new IOException("connection can not be null"); conn.setRequestProperty("Pragma", "no-cache");// 设置不适用缓存 conn.setRequestProperty("Cache-Control", "no-cache"); conn.setRequestProperty("Connection", "Close");// 不支持Keep-Alive conn.setUseCaches(false); conn.setDoOutput(true); conn.setDoInput(true); conn.setInstanceFollowRedirects(true); conn.setRequestMethod(method); conn.setConnectTimeout(8000); conn.setReadTimeout(8000); return conn;
//待改进 protected static HttpURLConnection getConnection(URL url, boolean isFile) throws IOException { HttpURLConnection conn = (HttpURLConnection) url.openConnection(); if (conn == null) { throw new IOException("connection can not be null"); //设置从httpUrlConnection读入 conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); //如果是上传文件,则设为POST if (isFile) { conn.setRequestMethod(POST_METHOD); //GET和 POST都可以 文件略大改成POST // 设置请求头信息 conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Charset", String.valueOf(StandardCharsets.UTF_8)); conn.setConnectTimeout(8000); conn.setReadTimeout(8000); return conn;
public static String setParmas(String url, Map String, String map, String charset) throws Exception { String result = StringUtils.EMPTY; boolean hasParams = false; if (StringUtils.isNotEmpty(url) MapUtils.isNotEmpty(map)) { StringBuilder builder = new StringBuilder(); for (Map.Entry String, String entry : map.entrySet()) { String key = entry.getKey().trim(); String value = entry.getValue().trim(); if (hasParams) { builder.append(" } else { hasParams = true; if (StringUtils.isNotEmpty(charset)) { builder.append(key).append("=").append(URLEncoder.encode(value, charset)); } else { builder.append(key).append("=").append(value); result = builder.toString(); URL u = new URL(url); if (StringUtils.isEmpty(u.getQuery())) { if (url.endsWith(" ")) { url += result; } else { url = url + " " + result; } else { if (url.endsWith(" ")) { url += result; } else { url = url + " " + result; logger.debug("request url is {}", url); return url; }

遇到的问题

1)"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hint: [Ua2IXa0080sz47!]"
获取的access_token不对,这边的token不是授权的token,是公众号调用各接口时使用的access_token

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。


相关文章

这篇文章主要介绍了Java实现随机出题,10道10以内加减法计算,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

这篇文章主要介绍了Spring Boot 连接LDAP的方法,仅仅涉及基本的使用ODM来快速实现LDAP增删改查操作。具有一定的参考价值,有兴趣的可以了解一下

这篇文章主要介绍了详解Springboot+React项目跨域访问问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

这篇文章主要介绍了Java对日期Date类进行加减运算、年份加减月份加减、时间差等等,在网上查阅资料,加上自己总结的一些关于Date类的工具类

这篇文章主要介绍了Java使用easyExcel导出excel数据案例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

这篇文章主要介绍了Eclipse导入项目报错问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

这篇文章主要介绍了Spring 跨域配置请求详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

这篇文章主要介绍了记一次公司JVM堆溢出抽丝剥茧定位的过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

本篇文章主要介绍了详解spring boot配置 ssl,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

这篇文章主要介绍了java并发分段锁实践代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 (责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
无法在这个位置找到: ajaxfeedback.htm
栏目列表
推荐内容


扫描二维码分享到微信

在线咨询
联系电话

400-888-8866