Spring Boot 3 微信公众号推送模版消息的方法示例
要在Java中向微信公众号推送模板消息,首先需要确保我们已经有了微信公众号,并且已经设置了模板消息权限和模板ID。模板消息是一种向用户发送通知的服务,广泛用于订单状态更新、服务提醒等场景。
下面,我将详细介绍如何使用Java结合微信官方提供的API来实现模板消息的推送。这通常涉及几个步骤:获取access_token、组装模板消息数据、发送请求。
第一步:准备工作
- 微信公众号配置:确保我们的公众号已经开通模板消息功能,并创建了相应的模板。
- 引入依赖:我们可能需要使用HTTP客户端库,如Apache HttpClient或OkHttp。这里我们使用Apache HttpClient。
在我们的pom.xml
中添加依赖(如果使用Maven):
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
第二步:获取Access Token
微信公众号API的调用大多需要Access Token,这是一个临时票据,用于调用接口的身份验证。
/**
* @author Will
*/
@Slf4j
public class WeChatUtil {
private static final String APP_ID = "wx3839291575c66e7a";
private static final String APP_SECRET = "aed8535d62febc069400183b02b51b5c";
private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APP_ID}&secret={APP_SECRET}";
public static String getAccessToken() throws Exception {
String url = TOKEN_URL.replace("{APP_ID}", APP_ID.trim()).replace("{APP_SECRET}", APP_SECRET.trim());
log.info("url:{}", url);
HttpGet request = new HttpGet(url);
CloseableHttpClient httpClient = HttpClients.createDefault();
String result = httpClient.execute(request, httpResponse ->
EntityUtils.toString(httpResponse.getEntity()));
log.info("result:{}", result);
// 解析JSON获取access_token,这里假设已经通过某种方式(如Jackson, Gson)解析
// 这里简单用String.split()模拟解析
String[] parts = result.split(",");
for (String part : parts) {
if (part.contains("access_token")) {
String[] tokenParts = part.split(":");
return tokenParts[1].trim().replace("\"", "");
}
}
return null;
}
}
第三步:发送模板消息
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicHeader;
import java.util.Map;
/**
* @author Will
*/
@Slf4j
public class TemplateMessageSender {
public static void sendTemplateMessage(String accessToken, String toUserOpenId, String templateId, String url, Map<String, TemplateData> data) throws Exception {
String json = "{\"touser\":\"" + toUserOpenId + "\",\"template_id\":\"" + templateId + "\",\"url\":\"" + url + "\",\"data\":{";
for (Map.Entry<String, TemplateData> entry : data.entrySet()) {
json += "\"" + entry.getKey() + "\":{\"value\":\"" + entry.getValue().getValue() + "\",\"color\":\"" + entry.getValue().getColor() + "\"},";
}
if (json.endsWith(",")) {
json = json.substring(0, json.length() - 1);
}
json += "}}";
log.info("json:{}", JSONUtil.toJsonStr(json));
String messageUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
HttpPost request = new HttpPost(messageUrl);
request.setHeader(new BasicHeader("Content-Type", "application/json; charset=UTF-8"));
request.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
CloseableHttpClient httpClient = HttpClients.createDefault();
String result = httpClient.execute(request, httpResponse ->
EntityUtils.toString(httpResponse.getEntity()));
log.info("发送结果:{}", result);
}
public static class TemplateData {
private String value;
private String color;
public TemplateData() {
}
public TemplateData(String value, String color) {
this.value = value;
this.color = 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;
}
}
}
第四步:调用发送模板消息的方法
在完成了WeChatUtil
类用于获取access_token
和TemplateMessageSender
类用于发送模板消息后,我们需要在我们的应用逻辑中调用这些方法。以下是一个示例,展示如何整合这些步骤来发送模板消息。
首先,确保我们有一个包含模板消息数据的Map
,其中键是模板中定义的字段名,值是TemplateData
对象(包含具体的值和可选的颜色)。
/**
* @return String
*/
@GetMapping(value = "/message", produces = "text/html;charset=utf-8")
@ApiOperationSupport(order = 1)
public String messageTest() {
try {
// 获取access_token
String accessToken = WeChatUtil.getAccessToken();
if (accessToken == null) {
log.error("获取access_token失败");
return "";
}
log.info("获取 accessToken:{}", accessToken);
// 准备模板消息数据
Map<String, TemplateMessageSender.TemplateData> data = new HashMap<>(4);
data.put("first", new TemplateMessageSender.TemplateData("李飞", "#8ba5e9"));
data.put("keyword1", new TemplateMessageSender.TemplateData("睡眠自评量表(AIS)", "#e9a08b"));
data.put("keyword2", new TemplateMessageSender.TemplateData("健康管理", "#e9a08b"));
data.put("remark", new TemplateMessageSender.TemplateData("这是备注信息", "#173177"));
// 发送模板消息
String toUserOpenId = "olODm645OL1h8k5Tt-0FQr3PFs80";
String templateId = "ZN4PFfZ4RynJv1S_zdmrH3pT381_-qrH-DpuM8C4Drs";
String url = "https://www.baidu.com/";
TemplateMessageSender.sendTemplateMessage(accessToken, toUserOpenId, templateId, url, data);
log.info("模板消息发送成功");
} catch (Exception e) {
e.printStackTrace();
log.error("发送模板消息失败:{}", e.getMessage());
}
return "微信消息投递";
}
发送JSON
{
"touser": "olODm645OL1h8k5Tt-0FQr3PFs80",
"template_id": "ZN4PFfZ4RynJv1S_zdmrH3pT381_-qrH-DpuM8C4Drs",
"url": "https://www.baidu.com/",
"data": {
"remark": {
"value": "这是备注信息",
"color": "#173177"
},
"first": {
"value": "李飞",
"color": "#8ba5e9"
},
"keyword1": {
"value": "睡眠自评量表(AIS)",
"color": "#e9a08b"
},
"keyword2": {
"value": "健康管理",
"color": "#e9a08b"
}
}
}
注意事项
- 安全性:在实际应用中,应避免将
APP_ID
和APP_SECRET
硬编码在代码中,可以通过配置文件或环境变量等方式来管理; - 错误处理:上述示例中的错误处理非常简单,仅打印了堆栈跟踪和错误消息。在生产环境中,我们可能需要更复杂的错误处理逻辑,比如重试机制、日志记录等;
- HTTP客户端:示例中使用了Apache HttpClient,但我们也可以选择其他HTTP客户端库,如OkHttp、Retrofit等;
- JSON解析:示例中使用了简单的字符串操作来模拟JSON解析,但在实际开发中,我们应该使用专门的JSON库(如Jackson、Gson)来解析和构建JSON数据;
- 模板ID和OpenID:确保模板ID和用户的OpenID是正确的,并且模板ID与我们要发送的数据字段相匹配;
- API限制:微信对API调用有频率限制,请确保我们的应用不会超出这些限制;
通过上述步骤,我们应该能够在Java中成功地向微信公众号发送模板消息。