一.本篇要点:
1.首先这篇文章主要分为俩部分,先是介绍服务号发送消息模板,后面接着是测试号发送消息模板!
二.整体思路:
1、先创建菜单,引导用户进入授权页面同意授权,获取code 以及openId
2、通过code换取网页授权access_token(与基础支持中的access_token不同)
3、如果需要,开发者可以刷新网页授权access_token,避免过期
4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
三.代码的实现
-----------------------------------------服务号步骤--------------------------------------
1.创建自定义菜单,可以通过代码的方式,也可以直接在服务号后台中创建自定义菜单
页面地址:是后台用来处理 用户点击这个菜单获取用的的code 以及openId
2. 接下来后台用来处理数据的接口
@RequestMapping(value = "/getNews")
public String getNews(){
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
String REDIRECT_URI = "http://hgbcb.io/getOpenId";//你的回调页
url = url.replace("APPID",WeiXinParamesUtil.APPID);
url = url.replace("STATE", "test");
url = url.replace("REDIRECT_URI", REDIRECT_URI);
return "redirect:"+url;
}
public static String OPENID;
@RequestMapping(value = "/getOpenId")
public String callBack(ModelMap modelMap, HttpServletRequest req, HttpServletResponse response) throws Exception {
String code = req.getParameter("code");
OAuthInfo oat = GetOpenid.getOAuthOpenId(WeiXinParamesUtil.APPID, WeiXinParamesUtil.SECRET, code);
String openId=oat.getOpenId();
OPENID=openId;
//在这里查询出客户表中的openid是否存在
BosCustomerModel customer=weiService.findBosCustomerModelByOpenId(openId);
if(customer!=null) {
return "sucess";
}
return "findName";
}
3.在getOpenId这个接口得到了code,然后getOAuthOpenId这个方法去获取用户的openiD,然后就可以拿到点击这个菜单的人的openid。
public static OAuthInfo getOAuthOpenId(String appid, String secret, String code ) {
OAuthInfo oAuthInfo = null;
String o_auth_openid_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
String requestUrl = o_auth_openid_url.replace("APPID", appid).replace("SECRET", secret).replace("CODE", code);
JSONObject jsonObject = WeiXinUtil.httpRequest(requestUrl, "GET", null);
//oAuthInfo是作者自己把那几个属性参数写在一个类里面了。
// 如果请求成功
if (null != jsonObject) {
try {
oAuthInfo = new OAuthInfo();
oAuthInfo.setAccessToken(jsonObject.getString("access_token"));
oAuthInfo.setExpiresIn(jsonObject.getInt("expires_in"));
oAuthInfo.setRefreshToken(jsonObject.getString("refresh_token"));
oAuthInfo.setOpenId(jsonObject.getString("openid"));
oAuthInfo.setScope(jsonObject.getString("scope"));
} catch (Exception e) {
oAuthInfo = null;
// 获取token失败
log.error("网页授权获取openId失败 errcode:{} errmsg:{}", jsonObject
.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return oAuthInfo;
}
4.接下来是考虑模板的问题:发送模板最重要的就是拿到模板id
服务号的模板是要申请的,前提是要选择自己的行业,它会提供一些关于你选择的那个行业的一些模板。(有审核时间)
模板消息:点击微信公众平台-->添加功能插件-->模板消息-->申请然后选择适合的模板
5.发送模板的方法:(当中涉及的一些方法可以在测试号看到)
//接下来给这个客户发送模板消息
//先给模板中设置参数
Template tem=new Template();
tem.setTemplateId(WeiXinParamesUtil.TEMPLATEID); //模板id
tem.setTopColor("#00DD00");
tem.setToUser(customer.getOpenId());//得到用户的openid
tem.setUrl("");
List<TemplateParam> paras = new ArrayList<TemplateParam>();
paras.add(new TemplateParam("first", "我们将给您推送一些关于您项目进度的消息:", "#FF3333"));
paras.add(new TemplateParam("keyword1", newModel.getwName(), "#0044BB"));//项目名称
paras.add(new TemplateParam("keyword2", message, "#0044BB"));//项目进度
//paras.add(new TemplateParam("keyword3", newModel.getsTime(), "#0044BB"));//开始时间
paras.add(new TemplateParam("keyword3", newModel.getLeader(), "#0044BB"));//项目负责人
paras.add(new TemplateParam("remark", "感谢你对我们BIM项目的支持!!!!", "#AAAAAA"));
tem.setTemplateParamList(paras);
//将Accesstoken拿到
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
/* String APPID = WeiXinParamesUtil.APPID;
String SECRET = WeiXinParamesUtil.SECRET;*/
url = url.replace("APPID", WeiXinParamesUtil.APPID);
url = url.replace("APPSECRET",WeiXinParamesUtil. SECRET);
String content = HttpUtil.httpUrlConnect(url, null, "GET");
Map<String, Object> map = HttpUtil.getAccessTokenByJsonStr(content);
String accessToken = (String) map.get("access_token");
boolean result = SendMessage.sendTemplateMsg(accessToken, tem);
6.效果图如下:
--------------------------------------------测试号步骤------------------------------------
1.在测试号网页上拿到关注公众号的人员信息,将其保存在数据库中,注意:每个人的openid是唯一的
2.事先在公众号中定义模板,那么在后台你就可以拿到模板id 将数据已模板的方式发送给客户
3. ProjectController
// 4.根据id修改数据
@RequestMapping(value = "/updateProjectById", method = RequestMethod.POST)
public String updateById(Model model,
) throws Exception {
//根据bid去查询出bos_customer中的数据
Bos_customer customer=projectService.findCustomerByBid(bid);
System.out.println("Bos_customer:"+customer.getCid()+"-------"+customer.getCname()+"-------"+customer.getOpenId());
//接下来给这个客户发送模板消息
//先给模板中设置参数
Template tem=new Template();
tem.setTemplateId("4JDGT8xdV-PQYbtiwJaeb352WoeUDHRtb29gn62olJk"); //模板id
tem.setTopColor("#00DD00");
tem.setToUser(customer.getOpenId());//得到用户的openid
tem.setUrl("");
List<TemplateParam> paras=new ArrayList<TemplateParam>();
paras.add(new TemplateParam("first","我们将给您推送一些关于您项目进度的消息:","#FF3333"));
paras.add(new TemplateParam("keyword1",pro.getwName(),"#0044BB"));//项目名称
paras.add(new TemplateParam("keyword2",message,"#0044BB"));//项目进度
paras.add(new TemplateParam("keyword3",pro.getsTime(),"#0044BB"));//开始时间
paras.add(new TemplateParam("keyword4",pro.getLeader(),"#0044BB"));//项目负责人
paras.add(new TemplateParam("remark","感谢你对我们BIM项目的支持!!!!","#AAAAAA"));
tem.setTemplateParamList(paras);
//将Accesstoken拿到
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
String APPID = ConfigUtil.APPID;
String SECRET = ConfigUtil.SECRET;
url = url.replace("APPID", APPID);
url = url.replace("APPSECRET", SECRET);
String content = HttpUtil.httpUrlConnect(url, null, "GET");
Map<String, Object> map=HttpUtil.getAccessTokenByJsonStr(content);
String accessToken=(String) map.get("access_token");
boolean result=SendMessage.sendTemplateMsg(accessToken,tem);
if(result==true){
System.out.println("发送成功");
}
}
}
return "redirect:showAll";
}
4. Template类
package com.bos.pojo;
import java.util.List;
public class Template {
//消息接收方
private String toUser;
//模板id
private String templateId;
//模板消息详情链接
private String url;
//消息顶部的颜色
private String topColor;
//参数列表
private List<TemplateParam> templateParamList;
public Template() {
super();
// TODO Auto-generated constructor stub
}
public Template(String toUser, String templateId, String url,
String topColor, List<TemplateParam> templateParamList) {
super();
this.toUser = toUser;
this.templateId = templateId;
this.url = url;
this.topColor = topColor;
this.templateParamList = templateParamList;
}
public String getToUser() {
return toUser;
}
public void setToUser(String toUser) {
this.toUser = toUser;
}
public String getTemplateId() {
return templateId;
}
public void setTemplateId(String templateId) {
this.templateId = templateId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTopColor() {
return topColor;
}
public void setTopColor(String topColor) {
this.topColor = topColor;
}
public List<TemplateParam> getTemplateParamList() {
return templateParamList;
}
public void setTemplateParamList(List<TemplateParam> templateParamList) {
this.templateParamList = templateParamList;
}
public String toJSON() {
StringBuffer buffer = new StringBuffer();
buffer.append("{");
buffer.append(String.format("\"touser\":\"%s\"", this.toUser)).append(",");
buffer.append(String.format("\"template_id\":\"%s\"", this.templateId)).append(",");
buffer.append(String.format("\"url\":\"%s\"", this.url)).append(",");
buffer.append(String.format("\"topcolor\":\"%s\"", this.topColor)).append(",");
buffer.append("\"data\":{");
TemplateParam param = null;
for (int i = 0; i < this.templateParamList.size(); i++) {
param = templateParamList.get(i);
// 判断是否追加逗号
if (i < this.templateParamList.size() - 1){
buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"},", param.getName(), param.getValue(), param.getColor()));
}else{
buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"}", param.getName(), param.getValue(), param.getColor()));
}
}
buffer.append("}");
buffer.append("}");
return buffer.toString();
}
}
package com.bos.pojo;
public class TemplateParam {
//模板消息由于模板选取不同,那么就要封装俩个实体类
// 参数名称
private String name;
// 参数值
private String value;
// 颜色
private String color;
public TemplateParam() {
super();
// TODO Auto-generated constructor stub
}
public TemplateParam(String name,String value,String color){
this.name=name;
this.value=value;
this.color=color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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;
}
}
5.一些工具类
(1)HttpUtil
package com.wei.util;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
public class HttpUtil {
public static String httpUrlConnect(String httpUrl, String params,
String method) throws Exception {
URL url = new URL(httpUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestProperty("accept", "*/*");
urlConnection.setRequestProperty("connection", "Keep-Alive");
urlConnection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestMethod(method);
urlConnection.connect();
PrintWriter out = null;
BufferedReader in = null;
if (null != params && !"".equals(params)) {
out = new PrintWriter(new OutputStreamWriter(
urlConnection.getOutputStream(), "utf-8"));
out.print(params);
out.flush();
}
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(), "utf-8"));
String line;
String result = "";
while ((line = in.readLine()) != null) {
result += line;
}
return result;
}
/**
* 根据字符串json数据解析access_token
* @param jsonStr
* @return map
*/
public static Map<String,Object> getAccessTokenByJsonStr(String jsonStr){
Map<String,Object> map = new HashMap<String, Object>();
JSONObject jsonObj = new JSONObject(jsonStr);
if(jsonObj.has("access_token")){
map.put("access_token", jsonObj.get("access_token"));
}
if(jsonObj.has("expires_in")){
map.put("expires_in", jsonObj.get("expires_in"));
}
return map;
}
}
(2)发送模板消息的类
package com.wei.util;
import net.sf.json.JSONObject;
import com.bos.pojo.Template;
/*
*
* 这是发送模板消息的类
* 5.12
*
* */
public class SendMessage {
public static boolean sendTemplateMsg(String token,Template template){
boolean flag=false;
String requestUrl="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
requestUrl=requestUrl.replace("ACCESS_TOKEN", token);
JSONObject jsonResult=CommonUtil.httpsRequest(requestUrl, "POST", template.toJSON());
if(jsonResult!=null){
int errorCode=jsonResult.getInt("errcode");
String errorMessage=jsonResult.getString("errmsg");
if(errorCode==0){
flag=true;
}else{
System.out.println("模板消息发送失败:"+errorCode+","+errorMessage);
flag=false;
}
}
return flag;
}
}
最后给大家看一下简单的微信公众号的效果。