java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java微信公众号模板消息推送

Java微信公众号模板消息推送功能实例代码

作者:振宇i

这篇文章主要介绍了Java微信公众号模板消息推送功能的相关资料,包括了公众号开发者平台的参数获取、微信发送接口的实际调用、消息发送的util类、示例模板以及接口调用的示例,需要的朋友可以参考下

一、公众号开发者平台相关参数获取

如下图所示, 需要获取:

开发者ID(AppID)

开发者密码(AppSecret) 

二、官方发送接口

实际调用接口填下如下参数即可:

touser template_id data

三、消息发送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 微信开发平台里找
     * secret 微信开发平台里找
     * @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 关注此公众号的人员的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形式发送HttpPost的Json请求,String形式返回响应结果
     *
     * @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;
    }

    /**
     * 发送不带参数的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.执行get请求并返回结果
            response = httpclient.execute(httppost);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 4.处理结果,这里将结果返回为字符串
        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的三个变量名一一对应,不能有错

五、接口调用示例

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, 但是

这一步操作的时候一直值放不进去,一直为空

为空示例:

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进值

2、微信token接口

获取微信的token接口次数每日上限2000次,所以如果要发送大量消息,请获取一次access_token,然后批量调用发送接口,不要调一次发一次

3、发送失败解决

请求接口的时候一定要把access_token拼到url上,不要放入body中,不然调用会失败

如果返回"errcode":47001,"errmsg":"data format error   则是因为发送的数据格式不对

但是即使格式对了,某些情况下依旧会返回如上错误.  博主踩坑了一天后才发现, 因为发送http的post请求如果构建不对依旧会报47001!

所以建议报了47001后,先把请求的参数放到postman等工具中测试了, 排除掉不是自己数据体构建得有问题后, 再去排查自己的post请求代码

7、建议

appid, template_id, sercet这些可以写在yml的配置项中, 灵活一点不建议写死

总结

到此这篇关于Java微信公众号模板消息推送功能的文章就介绍到这了,更多相关Java微信公众号模板消息推送内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文