java实现微信公众号模板消息推送

要推送微信的模板消息,我们需要准备的条件有:
  • 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;
	}
### 使用Java开发微信公众号消息推送接口教程 #### 准备工作 为了能够通过Java微信公众号发送模板消息,前期准备必不可少。这包括但不限于注册成为微信公众平台开发者并创建应用以获得`appId`和`appSecret`。另外,由于授权页面需在微信客户端内打开,因此建议使用微信提供的开发工具,并设置本地测试环境为`127.0.0.1/getCode`以便于调试[^2]。 #### 获取Access Token 每次调用微信API之前都需要先获取到有效的`access_token`,这是访问大多数微信API所必需的身份验证令牌。可以通过HTTP GET请求的方式从指定URL中取得该token: ```java public String getAccessToken(String appId, String appSecret){ String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret; OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); try (Response response = client.newCall(request).execute()) { JSONObject jsonObject = new JSONObject(response.body().string()); return jsonObject.getString("access_token"); } catch (IOException e) { throw new RuntimeException(e); } } ``` 此方法返回的字符串即为所需的`access_token`[^1]。 #### 组装模板消息数据 构建要发送的信息体时需要注意参数的选择与组合。特别是对于`openId`(目标用户的唯一标识)、`template_id`(预定义的消息模板ID),以及可选字段如链接地址(`url`)或小程序路径(`miniprogram`)等。如果两者均被设定,则优先考虑跳转至小程序;但如果用户设备不支持这一特性,则会转向给定的网页链接[^3]。 以下是用于构造JSON格式的数据包的一个简单例子: ```json { "touser": "OPENID", "template_id": "TEMPLATE_ID", "page": "index", "form_id": "FORMID", "data": { "keyword1": {"value": "商品名称"}, "keyword2": {"value": "订单号"} }, "emphasis_keyword": "" } ``` 请注意,在实际编码过程中应当将上述占位符替换为真实的变量值。 #### 发送请求 最后一步就是利用已有的信息去发起HTTPS POST请求,从而完成整个流程。这里给出一段完整的示例代码片段展示如何执行这项操作: ```java import okhttp3.*; // ...其他必要的导入语句... public void sendTemplateMessage(String accessToken, Map<String,Object> messageData){ MediaType JSON = MediaType.parse("application/json; charset=utf-8"); String jsonBody = new Gson().toJson(messageData); // 假设messageData已经包含了所有必要键值对 HttpUrl url = new HttpUrl.Builder() .scheme("https") .host("api.weixin.qq.com") .addPathSegment("cgi-bin") .addPathSegment("message") .addPathSegment("template") .addPathSegment("send") .addQueryParameter("access_token", accessToken) .build(); RequestBody body = RequestBody.create(jsonBody, JSON); Request request = new Request.Builder() .url(url) .post(body) .build(); OkHttpClient okHttpClient = new OkHttpClient(); Call call = okHttpClient.newCall(request); try(Response response = call.execute()){ System.out.println(response.body().string()); // 输出服务器响应结果供查看 }catch(IOException e){ e.printStackTrace(); } } ``` 这段程序展示了怎样把前面几步收集起来的信息打包成一个标准的POST请求,并最终将其提交给微信服务器处理[^4]。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值