要推送微信的模板消息,我们需要准备的条件有:
  • 1、有效的access_token
  • 2、微信公众号提供的消息模板的Template_id
access_token:

公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,access_token在2小时内有效,过期需要重新获取,但1天内获取次数有限,开发者需自行存储,详见获取接口调用凭据(access_token)文档。

这里我使用缓存存储access_token,并定时到微信平台获取更新。

Template_id:

Template_id是我们需要推送的模板消息的模板的唯一标识,微信公众平台提供了很多模板,也支持自定义格式。在实际使用时,我们需要到微信公众平台申请开启模板消息功能。在微信公众平台的首页,左侧菜单有一个“添加功能插件”,选择模板消息,微信平台审核需要一定时间。

消息模板举例:
{{first.DATA}}
告警内容:{{keyword1.DATA}}
告警发生时间:{{keyword2.DATA}}
{{keyword3.DATA}}

为了方便封装数据,我们使用模板类来包装要发送的信息:

TemplateParam 类封装了模板消息中的一个数据,比如上面的“{{first.DATA}} ”,具体属性可阅读注释:

public class TemplateParam {
    // 参数名称
    private String name;
    // 参数值
    private String value;
    // 颜色
    private String color;

    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;
    }


}

Template类代表了整个微信模板消息,这里我使用了特定的toJSON()方法生成要发送给微信云平台的json数据:

public class Template {

    // 消息接收方
    private String toUser;
    // 模板id
    private String templateId;
    // 模板消息详情链接
    private String url;
    // 消息顶部的颜色
//    private String topColor;
    // 参数列表
    private List<TemplateParam> 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 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();
    }

    public List<TemplateParam> getTemplateParamList() {
        return templateParamList;
    }

    public void setTemplateParamList(List<TemplateParam> templateParamList) {
        this.templateParamList = templateParamList;
    }

准备好了模板消息实体,就可以封装数据并发送了。关注公众号的微信用户,会使用openid来唯一标识,下面的方法是实现了多用户群发,for循环逐一发送,目前没有找到更好的群发方法:

@RequestMapping("/sendWarningByWechat")
    @ResponseBody
    public ResultMap sendWarningByWechat(String openIds, String content, String alarmDescriptions, String sendDateTime) {
        ResultMap res = new ResultMap();
        StringBuffer resBuff = new StringBuffer();
        try {
            String templateMsgUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
            templateMsgUrl = templateMsgUrl.replace("ACCESS_TOKEN", MemoryData.access_token);

            //封装请求体
            Template template = new Template();
            template.setTemplateId("0ZUeqUJQ7jxB3G-fxgKyP17SPoo44wFuxnYBqLu5zA4E");
            List<TemplateParam> templateParams = new ArrayList<>();
            String[] failures = alarmDescriptions.split("\\|\\|");
            String alarmDescStr = "\\r\\n";
            if (failures != null && failures.length > 0) {
                for (String failure : failures) {
                    alarmDescStr += failure + "\\r\\n";
                }
                //去掉最后的换行符号
                alarmDescStr = alarmDescStr.substring(0, alarmDescStr.lastIndexOf("\\r\\n"));
            }
            String allStr = content + alarmDescStr;
            while (allStr.length() > 180) {
                alarmDescStr = alarmDescStr.substring(0, alarmDescStr.lastIndexOf("\\r\\n"))+"...";
                allStr = content + alarmDescStr;
            }
            TemplateParam first = new TemplateParam("first", content + "\\r\\n", "#DB1A1B");
            TemplateParam keyword1 = new TemplateParam("keyword1", alarmDescStr + "\\r\\n", "#DB1A1B");
            TemplateParam keyword2 = new TemplateParam("keyword2", sendDateTime + "", "#DB1A1B");
            TemplateParam keyword3 = new TemplateParam("keyword3", "", "#DB1A1B");
            templateParams.add(first);
            templateParams.add(keyword1);
            templateParams.add(keyword2);
            templateParams.add(keyword3);
            template.setTemplateParamList(templateParams);
            String[] openIdArr = openIds.split(",");
            if (openIdArr.length > 0) {
                for (String openID : openIdArr) {
                    template.setToUser(openID);
                    String paramStr = template.toJSON();
                    String resJson = HttpClientUtil.doTemplateMsgPost(templateMsgUrl, paramStr);
                   
                }
            }
           
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            res.setFailureResult();
        }
        return res;
    }

给微信云平台发送json数据时,使用Apache的HttpClient,工具方法如下:

/**
	 * 发送模板消息的方法
	 * @param templateMsgUrl 模板消息请求URL
	 * @param paramStr  模板消息json字符串
	 * @return
	 */
	public static String doTemplateMsgPost(String templateMsgUrl,String paramStr){
		String res=null;
		URL url = null;
		try {
			url = new URL(templateMsgUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			if (null != paramStr) {
				OutputStream outputStream = conn.getOutputStream();
				// 注意编码格式
				outputStream.write(paramStr.getBytes("UTF-8"));
				outputStream.close();
			}
			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			conn.disconnect();
			res=buffer.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return  res;
	}