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发送模板消息~的主要内容,如果未能解决你的问题,请参考以下文章

PHP实现发送模板消息(微信公众号版)

shell使用微信公众号发送模板消息

微信公众号模板消息开发小结

微信模板消息群发系统

主动发送微信公众平台“模板消息”需要啥条件?

c# 有openid 如何发微信消息