Java微信公眾號模板消息推送功能實例代碼
一、公眾號開發(fā)者平臺相關(guān)參數(shù)獲取
如下圖所示, 需要獲取:
開發(fā)者ID(AppID)
開發(fā)者密碼(AppSecret)

二、官方發(fā)送接口
實際調(diào)用接口填下如下參數(shù)即可:
touser template_id data

三、消息發(fā)送util類
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class WeChatTemplateUtil {
// 本地測試
public static void main(String[] args) {
String accessToken = "xxx";
String touser = "xxx"; //openid
String templateId = "xxxx";
JSONObject body = new JSONObject();
body.put("touser", touser);
body.put("template_id", templateId);
// 封裝消息體
JSONObject data = new JSONObject();
data.put("character_string2", new JSONObject().put("value","111"));
data.put("thing3", new JSONObject().put("value","222"));
data.put("amount5", new JSONObject().put("value", "333"));
body.put("data", data);
System.out.println("Request Body: " + body.toString());
try {
String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
// String response = sendPost(url, body.toString());
String response = sendPostJsonStr(url, body.toString());
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲取微信token
* grantType 寫死的值,填client_credential即可
* appId 微信開發(fā)平臺里找
* secret 微信開發(fā)平臺里找
* @return
* @throws Exception
*/
public static String getWeChatToken() throws Exception{
String grantType = "client_credential"; //寫死
String appId = "123";
String secret = "123";
String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
String params = "grant_type=" + grantType + "&appid=" + appId + "&secret=" + secret;
String tokenResponse = WeChatHttpUtils.sendGet(tokenUrl, params);
JSON parse = JSONUtil.parseObj(tokenResponse);
return parse.getByPath("access_token").toString();
}
/**
* 推送水費欠費模板提示消息
* @param accessToken 微信token
* @param touser 關(guān)注此公眾號的人員的openid
* @param acccountNo 戶號
* @param accountName 戶名
* @param money 欠費金額
*/
public static void sendWeChatTemplateMessage(String accessToken, String touser, String acccountNo, String accountName, String money) {
// 模板ID
String templateId = "xxxx";
JSONObject body = new JSONObject();
body.put("touser", touser);
body.put("template_id", templateId);
// 封裝消息體
JSONObject data = new JSONObject();
data.put("character_string2", new JSONObject().put("value",acccountNo));
data.put("thing3", new JSONObject().put("value",accountName));
data.put("amount5", new JSONObject().put("value", money));
body.put("data", data);
try {
String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
sendPostJsonStr(url, body.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 以jsonString形式發(fā)送HttpPost的Json請求,String形式返回響應(yīng)結(jié)果
*
* @param url
* @param jsonString
* @return
*/
private static String sendPostJsonStr(String url, String jsonString) throws IOException {
if (jsonString == null || jsonString.isEmpty()) {
return sendPost(url);
}
String resp = "";
StringEntity entityStr = new StringEntity(jsonString,
ContentType.create("text/plain", "UTF-8"));
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(entityStr);
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
resp = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (resp == null || resp.equals("")) {
return "";
}
return resp;
}
/**
* 發(fā)送不帶參數(shù)的HttpPost請求
*
* @param url
* @return
*/
private static String sendPost(String url) throws IOException {
// 1.獲得一個httpclient對象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 2.生成一個post請求
HttpPost httppost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
// 3.執(zhí)行g(shù)et請求并返回結(jié)果
response = httpclient.execute(httppost);
} catch (IOException e) {
e.printStackTrace();
}
// 4.處理結(jié)果,這里將結(jié)果返回為字符串
HttpEntity entity = response.getEntity();
String result = null;
try {
result = EntityUtils.toString(entity);
} catch (ParseException | IOException e) {
e.printStackTrace();
}
return result;
}
}四、示例模板
如下圖所示, 模板中的變量名分別character_string2, thing3, amount5
所以三種的util的JSONObject中put的三個變量名一一對應(yīng),不能有錯

五、接口調(diào)用示例
1、controller
@PostMapping("/pushMessage")
@Operation(summary = "微信公眾號推送消息")
public CommonResult<Boolean> pushMessage() throws Exception {
pushService.pushMessage();
return success(true);
}2、service
/**
* 微信公眾號推送消息
*/
void pushMessage() throws Exception;3、serviceimpl
@Override
public void pushMessage() throws Exception {
// 獲取微信公眾號的token
String weChatToken = WeChatTemplateUtil.getWeChatToken();
// 推送消息(測試用)
WeChatTemplateUtil.sendWeChatTemplateMessage(weChatToken, "openid", "accountNo", "accountName", "money");
}六、注意項
1、JSONObject包選擇
博主之前一直用的fastjson包引入的JSONObject, 但是
這一步操作的時候一直值放不進(jìn)去,一直為空
為空示例:
new JSONObject().put("value",acccountNo) 不為空示例:
JSONObject data = new JSONObject()
JSONObject acccountNo= new JSONObject()
acccountNo.put("value",acccountNo)
data.put("acccountNo", acccountNo)后面改用hutool的包引入JSONObject,
new JSONObject().put("value",acccountNo) 就可以直接成功put進(jìn)值
2、微信token接口
獲取微信的token接口次數(shù)每日上限2000次,所以如果要發(fā)送大量消息,請獲取一次access_token,然后批量調(diào)用發(fā)送接口,不要調(diào)一次發(fā)一次
3、發(fā)送失敗解決
請求接口的時候一定要把access_token拼到url上,不要放入body中,不然調(diào)用會失敗
如果返回"errcode":47001,"errmsg":"data format error 則是因為發(fā)送的數(shù)據(jù)格式不對
但是即使格式對了,某些情況下依舊會返回如上錯誤. 博主踩坑了一天后才發(fā)現(xiàn), 因為發(fā)送http的post請求如果構(gòu)建不對依舊會報47001!
所以建議報了47001后,先把請求的參數(shù)放到postman等工具中測試了, 排除掉不是自己數(shù)據(jù)體構(gòu)建得有問題后, 再去排查自己的post請求代碼
7、建議
appid, template_id, sercet這些可以寫在yml的配置項中, 靈活一點不建議寫死
總結(jié)
到此這篇關(guān)于Java微信公眾號模板消息推送功能的文章就介紹到這了,更多相關(guān)Java微信公眾號模板消息推送內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
探討:使用httpClient在客戶端與服務(wù)器端傳輸對象參數(shù)的詳解
本篇文章是對使用httpClient在客戶端與服務(wù)器端傳輸對象參數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
SpringCloud Alibaba 基本開發(fā)框架搭建過程
這篇文章主要介紹了SpringCloud Alibaba 基本開發(fā)框架搭建過程,開發(fā)工具選用的idea,本文通過圖文實例相結(jié)合給大家分享搭建全過程,需要的朋友可以參考下2021-06-06
java父子節(jié)點parentid樹形結(jié)構(gòu)數(shù)據(jù)的規(guī)整
這篇文章主要介紹了java父子節(jié)點parentid樹形結(jié)構(gòu)數(shù)據(jù)的規(guī)整,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
SpringBoot將logback替換成log4j2的操作步驟
文章介紹了如何在SpringBoot項目中將默認(rèn)的日志框架logback替換為log4j2,以利用log4j2的高性能異步日志記錄特性,特別是通過Disruptor實現(xiàn)的無鎖化隊列,提高了日志處理速度,同時,文章提供了詳細(xì)的配置步驟,需要的朋友可以參考下2024-10-10

