Java实现微信开发者-测试账号申请及配置

最近在搞微信的开发者模式,对于第一次接触这东西的人来说还真是没有头绪,因为需要跟微信进行交互,难免会碰到一些问题,不像我们在本机开发那样,很快就能把逻辑代码写完。今天主要是让测试耽误了时间,由于微信只能绑定域名,不能使用ip地址,但是在公司中域名直接解析到线上服务器,但是线上服务器该域名下已经有服务在运行,所以不能使用线上服务器直接进行开发测试,也不能把已有的服务号打开开发者模式,因为打开开发者模式之后好多已有的自动回复就不能使用了,总之遇到了各种问题,记录下开发过程。


申请测试账号

进入申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

点击登录按钮,会弹出一个二维码,使用手机微信扫描即可

登录成功之后会出现下面的界面


appID和appsecret在调用微信接口的时候会用到,这里是微信自动给我们生成好的,直接使用就可以。

URL:是我们自己服务器的URL,用户微信推送用户消息和事件用的。这里只能配置域名,不能使用IP。这个URL是用来接收微信的token认证和消息事件用的,我们自己的服务器要能对这个url的请求进行处理并相应,所以要求该域名必须是外网可以访问的,否则在点“提交”按钮的时候会报token异常。

Token:是验证签名用的,此处填写的要与代码中的Token保持一致否则验证不过。

URL和Token都填好之后点击提交按钮,若验证通过,会返回配置成功,否则返回配置失败。

配置失败的原因可能有几个:

1、URL地址不能访问

2、Token填写错误

注意:在点击提交按钮之前一定要先把服务端的代码写好,否则会返回配置失败,具体实现代码在后面演示。

到此为止,我们的接口配置信息就算完成了。

扫描测试号二维码就可以来测试我们的功能了


Token认证

我配置的URL是,http://www.xxx.com/XX/wxProcess/service,所以微信会把所有的请求都发到我的/service路径上,包括Token认证和事件处理,我使用两个方法来处理的,但是请求类型不同,Token认证是用的GET请求,事件处理使用的是POST请求。演示代码如下:

/**
     * 打开开发者模式签名认证
     * @param signature
     * @param timestamp
     * @param nonce
     * @param echostr
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/service", method = RequestMethod.GET)
    public Object defaultView(String signature, String timestamp, String nonce, String echostr) {
        if (echostr == null || echostr.isEmpty()) {
            return nonce;
        }
        if (SignUtil.checkSignature(signature, timestamp, nonce)) {
            return echostr;
        }
        return nonce;
    }

    /**
     * 事件处理
     * @param signature
     * @param timestamp
     * @param nonce
     * @param message
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/service", method = RequestMethod.POST, consumes = "text/xml", produces = "text/xml;charset=UTF-8")
    public String defaultViewHandler(String signature, String timestamp, String nonce, @RequestBody String message) {
        String result = "";
        if (SignUtil.checkSignature(signature, timestamp, nonce)) {
            result = coreService.processRequest(message);
        }
        return result;
    }

做签名认证的时候会调用我的defaultView方法,其他的事件都走defaultViewHandler方法。

coreService.processRequest(): 是对所有的请求事件进行处理

CoreService.java主要代码实现如下:

@Override
    public String processRequest(String msg) {
        String respMessage = null;
        try {
            // 默认返回的文本消息内容
            String respContent = "";

            // xml请求解析
            Map<String, String> requestMap = MessageUtil.parseXml(msg);

            // 发送方帐号(open_id)
            String fromUserName = requestMap.get("FromUserName");
            // 公众帐号
            String toUserName = requestMap.get("ToUserName");
            // 消息类型
            String msgType = requestMap.get("MsgType");
            String eventType = requestMap.get("Event");

            // 存在事件类型且类型有效 或者 消息类型可以处理,才需要进行身份处理,防止没有意义的事件引起发送大量绑定消息
            if ((!StringUtils.isEmpty(eventType) && !eventArrays.contains(eventType)) || !msgArrays.contains(msgType)) {
                return "";
            }

            respMessage = handleWxMessage(requestMap);
        } catch (Exception e) {
            LOGGER.error("error", e);
            e.printStackTrace();
        }
        return respMessage;
    }

    @Override
    public String handleWxMessage(Map<String, String> requestMap) {
        // 发送方帐号(open_id)
        String fromUserName = requestMap.get("FromUserName");
        // 公众帐号
        String toUserName = requestMap.get("ToUserName");
        // 消息类型
        String msgType = requestMap.get("MsgType");
        // 回复文本消息
        String respContent = "";
        BaseMessage textMessage = new TextMessage();
        textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
        switch (msgType) {
            case MessageUtil.REQ_MESSAGE_TYPE_TEXT:
                // 文本类型消息,暂时设置成用户发什么就回复什么
                String content = requestMap.get("Content");
                respContent = "";
                break;
            case MessageUtil.REQ_MESSAGE_TYPE_VOICE:
                // 使用语音识别功能需要开启微信公众号相关权限
                // 语音识别结果
                String recognizeText = requestMap.get("Recognition");
                respContent = "";
                break;
            case MessageUtil.REQ_MESSAGE_TYPE_EVENT:
                // 事件类型
                String eventType = requestMap.get("Event");
                // 事件KEY值,qrscene_为前缀,后面为二维码的参数值
                String eventKey = requestMap.get("EventKey");
                // 自定义事件
                switch (eventType) {
                    // 用户未关注时,进行关注后的事件推送
                    case MessageUtil.EVENT_TYPE_SUBSCRIBE:
                        if (isUserBuyLastActivity(fromUserName)) {
                            textMessage = getAddClassTextMessage(fromUserName);
                        } else {
                            textMessage = getDefaultTextMessage(fromUserName);
                        }
                        Integer eventKeyValue = 1;// 带参数的情景值
                        if (!StringUtils.isEmpty(eventKey) && eventKey.contains("qrscene_")) {
                            eventKey = eventKey.replace("qrscene_", "");
                            // 渠道ID
                            eventKeyValue = Integer.parseInt(eventKey);
                        }
                        subscribeAction(fromUserName, eventKeyValue);
                        break;
                    // 取消关注
                    case MessageUtil.EVENT_TYPE_UNSUBSCRIBE:
                        unSubscribeAction(fromUserName);
                        break;
                    // 用户已关注时的事件推送
                    case MessageUtil.EVENT_TYPE_SCAN:
                        textMessage = getDefaultTextMessage(fromUserName);
                        break;
                    default:
                        respContent = "";
                        break;
                }
                break;
            default:
                respContent = "";
                break;
        }

        if (textMessage instanceof TextMessage) {
            // 文本内容为空且是文本消息返回空字符串,防止微信发送异常消息
            String content = ((TextMessage) textMessage).getContent();
            if (StringUtils.isEmpty(respContent) && StringUtils.isEmpty(content)) {
                return "";
            }
            if (org.apache.commons.lang.StringUtils.isBlank(content)) {
                ((TextMessage) textMessage).setContent(respContent);
            }
        }
        textMessage.setToUserName(fromUserName);
        textMessage.setFromUserName(toUserName);
        textMessage.setCreateTime(new Date().getTime());
        String xmlString = MessageUtil.messageToXml(textMessage);
        return xmlString;
    }

上面只是展示了部分核心代码,具体代码可以去我的GitHub下载,地址:https://github.com/liuyanmin/wxDemo

下面是微信开发相关的链接:

申请个人测试账号:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

微信被动回复消息开发文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543

微信错误码文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543


©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页