微信公众号模板消息推送javaDemo

266 阅读4分钟

1.背景

根据需求给特定用户推送消息,不太清楚的请先看一遍 微信开放文档 ,主要了解入门指引和接入指南这两个。

开发流程:

1.配置url和token接口

2.关注测试号和配置模板消息接口

3.推送消息

2.配置url和token接口

本demo使用的是微信公众平台的测试号进行开发,实际公众号与测试号步骤流程几乎差不多。进入微信公众平台,登陆微信后进行接口配置,如下图:

image.png ps:url配置的话需要把接口项目部署到云服务器进行微信接口转发, 微信开发文档接口介绍:

image.png

2.1部署到服务器代码:

pom如下:
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>1.6.1</version>
    </dependency>
</dependencies>

项目结构:

image.png

wx接口转发:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@RestController
public class wx {

    @GetMapping("/")
    String hi(HttpServletRequest request, HttpServletResponse response){

        String signature =request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");/// 时间戳
        String nonce = request.getParameter("nonce"); /// 随机数
        String echostr = request.getParameter("echostr"); // 随机字符串

        System.out.println("signature:"+signature);
        System.out.println("timestamp:"+timestamp);
        System.out.println("nonce:"+nonce);
        System.out.println("echostr:"+echostr);


        if (SignUtil.checkSignature(signature, timestamp, nonce)) {
            System.out.println("校验成功!!!!!!!!!!!!!");
            return echostr;

        }
        return "error";
    }


}

SignUtil工具类:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;


public class SignUtil {
    // 与接口配置信息中的Token要一致
    private static String token = "wxtoken";


    public static boolean checkSignature(String signature, String timestamp, String nonce) {
        String[] arr = new String[] { token, timestamp, nonce };
        // 将token、timestamp、nonce三个参数进行字典序排序
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
        MessageDigest md = null;
        String tmpStr = null;

        try {
            md = MessageDigest.getInstance("SHA-1");
            // 将三个参数字符串拼接成一个字符串进行sha1加密
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        content = null;
//这里可以打印出来对比一下。看看是不是一样的。
        // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param byteArray
     * @return
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }

    /**
     * 将字节转换为十六进制字符串
     *
     * @param mByte
     * @return
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];

        String s = new String(tempArr);
        return s;
    }


}

本地运行无问题的话打jar包丢到服务器跑,接下来按照微信开发文档进行接口配置。 没有云服务器的小伙伴可以用ngrok来本地进行,详情可以百度看ngrok相关文档

接口配置可能碰到的问题:

1.接口注意格式,比如http只能是80端口,https只能是443端口,打jar包的时候记得在yaml(application.properties)里配置好端口

2.在服务器上跑的话url就到端口加项目的controller层接口就行,比如,服务器的项目位置如下

image.png

但是实际接口url:

http://+服务器ip+:80/就可以了

如目录2部分图示。

3.服务器查看端口占用命令: lsof -i:端口号
如:lsof -i:80

token的话建议全英文,如:wxtoken

以上配置都没问题的话,进入到微信公众平台,提交。

那么接口配置应该就可以了

3.关注测试公众号和配置模板消息

关注测试公众号这个就是扫微信公众平台的测试号二维码拿到自己的openid

配置模板消息:

image.png

格式按照上图,这时候我们就完成了模板消息配置,拿到了模板id

image.png

4.推送消息

建一个测试类复制

import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;

import java.util.Arrays;
import java.util.List;

public class wx_msg {
    public static void main(String[] args) {
        push();
    }
    public static void push() {

        //1,配置
        WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
        //配置公众号的appid和secret
        wxStorage.setAppId("wx276845bb6f054b2h");
        wxStorage.setSecret("31643e16d503b0042269a20135076d99");
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxStorage);


        List<WxMpTemplateData> data = Arrays.asList(
                new WxMpTemplateData("first","哈喽" , "#FF0000"),
                new WxMpTemplateData("key", "客服", "#173177"),
                new WxMpTemplateData("key1", "10086******", "#173177"),
                new WxMpTemplateData("remark", "点击详情可了解更多信息", "#173177")
        );
        //2,推送消息
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                //要推送的用户openid
                .toUser("obmrL6bStjY6L8sFPfLiQ1wRsZQY")
                )
                .templateId("g9CJnqz51-nqpqHLAgznzOAroOZRffgQsnWMS4KHwV4")//模版id
                //点击模版消息要访问的网址
            
                .url("https://www.baidu.com/")
                .data(data)
                .build();
        try {
            wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
        } catch (Exception e) {
            System.out.println("推送失败:" + e.getMessage());
            e.printStackTrace();
        }

    }

}

需要修改的配置:

1.appID和secret 也就是一开始登录微信公众平台给的测试号信息

2.openid 就是推送给谁,刚刚我们关注了测试公共号,拿到的就是openid

3.templateId 这个就是刚刚配置的模板,刚刚我们拿到的模板id

修改后跑起来没问题,微信就会收到

image.png

关于怎么获取全部关注用户的问题,大致总结为通过appid和secret去拿到token,再通过token拿到全部关注用户的openid.

image.png

image.png 具体的代码实现百度即可。

新人入坑,有不对的地方请各位大佬多多指正!