美文网首页
【干货】订阅号开发[3] 微信服务端验证与消息接收

【干货】订阅号开发[3] 微信服务端验证与消息接收

作者: 5d44bc28b93d | 来源:发表于2018-11-21 17:42 被阅读13次
订阅号.png

微信服务接入

微信服务器传递signature、timestamp、nonce、echostr这四个参数。定义时需要根据{token, timestamp, nonce}此顺序进行校验,经过SHA编码后是否与signature相等。

  • 接口提供
@GetMapping("/wx")
public String wxAuthentication(String signature, Long timestamp, String nonce, String echostr) {

        logger.info(" signature: " + signature + " timestamp: " + timestamp + " nonce: " + nonce + " echostr: " + echostr);
        if (!StringUtils.isEmpty(signature) && !StringUtils.isEmpty(timestamp)
                && !StringUtils.isEmpty(nonce) && !StringUtils.isEmpty(echostr)) {
            if (wxServerVerifyService.checkSignature(signature, timestamp.toString(), nonce)) {
                return echostr;
            }
        } else {
            logger.error("params is null");
        }
        return null;
}
  • 校验服务
public class WxServerVerifyService {

    @Value("${wx.token}")
    private  String token;

    public  boolean checkSignature(String signature, String timestamp, String nonce) {
        String[] str = new String[]{token, timestamp, nonce};
        Arrays.sort(str);
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < str.length; i++) {
            buffer.append(str[i]);
        }
        String temp = SHAUtil.encode(buffer.toString());
        return signature.equals(temp);
    }


}
  • SHAUtil
public class SHAUtil {
    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * Takes the raw bytes from the digest and formats them correct.
     *
     * @param bytes the raw bytes from the digest.
     * @return the formatted bytes.
     */
    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }

    public static String encode(String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

  • 注意服务必须是以80端口向外暴露(或者由nginx等工具80映射到此服务)
  • 接入方法为GET请求,POST为接收微信服务端消息接口。

微信消息接收

  • 接口提供
@PostMapping("/wx")
public void handleWxEvent(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter out = null;
        String responseMessage = null;
        try {
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            out = response.getWriter();
            responseMessage = wxMessageProcessService.responseMessage(request);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                if (responseMessage != null) {
                    out.print(responseMessage);
                } else {
                    out.print("");
                }
                out.flush();
                out.close();
            }
        }
}
  • 定义消息处理 wxMessageProcessService
    public String responseMessage(HttpServletRequest request) {
        String replyMessage = "";
        try {
            String content = MessageUtil.requestToXml(request);
            logger.info(content);
            Map<String, String> requestMap = MessageUtil.parseXml(content);
            if (requestMap.containsKey("MsgType")) {
                if ("event".equals(requestMap.get("MsgType"))) {
                    replyMessage = processEventMessage(requestMap, content);
                } else {
                    replyMessage = processCommonMessage(requestMap, content);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return replyMessage;
    }
  • 普通消息
 private String processCommonMessage(Map<String, String> requestMap, String content) {
        String msgType = requestMap.get("MsgType");
        String replyMessage = "";
        MsgType type = MsgType.valueOf(msgType);
        switch (type) {
            case text:
                break;
            case link:
                break;
            case image:
                break;
            case video:
                break;
            case voice:
                break;
            case location:
                break;
            case shortvideo:
                break;
            default:
                replyMessage = "";

        }
        return replyMessage;
    }
  • 事件消息
private String processEventMessage(Map<String, String> requestMap, String reciveContent) {
        String eventName = requestMap.get("Event");
        String replyMessage = "";
        EventMessage.Event event = EventMessage.Event.valueOf(eventName);
        TextMessage replyTextMessage = new TextMessage();
        switch (event) {

            case unsubscribe:
                break;
            case CLICK:
                break;
            case LOCATION:
                break;
            case SCAN:
                break;
            case VIEW:
                break;
            case subscribe:
                break;
            default:

        }
        return replyMessage;
    }
  • 默认请回复""或者"success",否则用户一段时间接收不到正确的消息格式,就会出现服务异常信息。

相关文章

网友评论

      本文标题:【干货】订阅号开发[3] 微信服务端验证与消息接收

      本文链接:https://www.haomeiwen.com/subject/iyncqqtx.html