最近公司做小程序需要用到消息推送,笔者在一路采坑做完后几个笔记,希望能帮到大家少采坑。

如果你连小程序都没有注册也没有做,那就不要继续看了。。。。。。。

微信官方文档:  微信消息推送      微信小程序订阅消息


 一、加上依赖

<!-- 针对   org.apache.commons.codec.binary.Base64,
             需要导入架包           -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>

入架包commons-codec-1.9(或commons-codec-1.8等其他版本)

否则在base64 操作上 会报 Last encoded character (before the paddings if any) is a valid base 64 alpha 的错

java开发公众号消息推动给指定人发消息 java微信推送信息_微信


二、编写验证URL代码

微信消息推送工具类

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

public class WXMsgPushUtils {

    /**
     * 用SHA1算法生成安全签名
     */
    public static String getSHA1(String... values) throws Exception {

        try {
            String[] array = new String[values.length];
            for (int i = 0; i < values.length; i++) {
                array[i] = values[i];
            }

            StringBuffer sb = new StringBuffer();
            // 字符串排序
            Arrays.sort(array);
            for (int i = 0; i < values.length; i++) {
                sb.append(array[i]);
            }
            String str = sb.toString();
            // SHA1签名生成
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();

            StringBuffer hexstr = new StringBuffer();
            String shaHex = "";
            for (int i = 0; i < digest.length; i++) {
                shaHex = Integer.toHexString(digest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexstr.append(0);
                }
                hexstr.append(shaHex);
            }
            return hexstr.toString();
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("SHA1加密失败");
        }

    }
}

验证URL接口

import WXMsgPushUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * 微信小程序 模板消息推送
 */
@RestController
@RequestMapping("weixinpublic")
public class WxMsgPushController {

    /**
     * 正确响应微信发送的Token验证,注意 这里是 get请求
     *
     */
    @GetMapping("/verify")
    public String verifyUrl(@RequestParam Map<String, String> params) throws Exception {
        // 微信发送的请求中 会有四个参数
        // 微信加密签名,signature结合了开发者填写的 token 参数和请求中的 timestamp 参数、nonce参数。
        String signature = params.get("signature");
        // 随机字符串
        String echostr = params.get("echostr");
        // 时间戳
        String timestamp = params.get("timestamp");
        // 随机数
        String nonce = params.get("nonce");

        // 消息推送配置中的 Token(令牌)
        String token = "DTBMpnU";

        // 验证
        String msgSignature = WXMsgPushUtils.getSHA1(token, timestamp, nonce);

        // 验证失败
        if (!signature.equals(msgSignature)) {
            return "false";
        }
        // 验证成功 将 echostr 原格式返回 ,即可完成验证
        return echostr;
    }
}

题外话。。。。微信官方给的文档说明是三个参数加密,但是下载得到的java 官方demo 加密参数是4个,不知道为啥。。。。浪费了半天时间

java开发公众号消息推动给指定人发消息 java微信推送信息_java_02

但是官方文档上写的 又是三个参数

java开发公众号消息推动给指定人发消息 java微信推送信息_消息推送_03

最后删除 掉demo中的一个参数 测试成功. 


 三、登录微信平台,配置消息推送,验证URL

 URL地址为项目推送的接口地址,即 微信官方会像这个接口地址发送GET请求,验证接口以及验证消息的确来自微信服务器,所以需要配置上服务器的接口地址(需要单独写一个接口来验证)

Token :自定义任意满足微信规则的字符,记录下来验证接口中会用到

EncodingAESKey:我是点击随机生成的,大家也可按需操作,一个月只能修改三次

加密方式、数据格式 大家按需就好不会影响验证 URL

完成代码的编写和这边的配置,确定好两边 Token一致,点击提交即可完成配置

java开发公众号消息推动给指定人发消息 java微信推送信息_微信_04