手把手教您开发JAVA微信SDK-接受消息

首先感谢大家的支持!

今天我们来讲一下,微信怎么接受消息。

接受消息是指:普通用户(也就是关注了我们订阅号或者服务号的用户)发送信息给我们的订阅号或者服务号,我们要接收的就是这个消息。

这个消息一般分为三大类(普通消息、事件消息、语音识别消息)。

普通消息又分:文本、图片、语音、视频、地理位置、链接

事件消息又分:关注/取消关注、扫描带参数二维码、上报地理位置事件、自定义菜单、点击菜单拉取消息、点击菜单跳转链接

这些消息虽然很多很复杂,但是他们有一个共同的点,那就是都是通过POST形式发送的XML数据包。

好了,我们开始写接受消息的代码吧。

我们需要将POST过来的XML数据包读取出来,所以我们需要一个XStream对象,这个对象引用于xstream-1.4.6.jar。

下面我们需要昨天我们创建好的com.ansitech.weixin.sdk.WeixinUrlFilter.java

1.修改com.ansitech.weixin.sdk.WeixinUrlFilter.java

我们将会在下段代码,处理接收消息处,开始我们今天的代码。

        if (isGet) {
            //验证URL真实性  
            String signature = request.getParameter("signature");// 微信加密签名  
            String timestamp = request.getParameter("timestamp");// 时间戳  
            String nonce = request.getParameter("nonce");// 随机数  
            String echostr = request.getParameter("echostr");//随机字符串  
            List<String> params = new ArrayList<String>();
            params.add(Token);
            params.add(timestamp);
            params.add(nonce);
            //1. 将token、timestamp、nonce三个参数进行字典序排序  
            Collections.sort(params, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    return o1.compareTo(o2);
                }
            });
            //2. 将三个参数字符串拼接成一个字符串进行sha1加密  
            String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));
            if (temp.equals(signature)) {
                response.getWriter().write(echostr);
            }
        } else {
            //处理接收消息  
        }
上段代码中,GET时,验证URL真实性,POST时就是用户以各种形式给我们订阅号发送的消息,我们现在就需要来读取并解析它。

由于发送的是xml数据包,我们读取不便,所以我们用XStream对象来转换为JAVA对象。

2.新建XML对应的消息处理对象com.ansitech.weixin.sdk.message.InputMessage.java

/*
 * 微信公众平台(JAVA) SDK
 *
 * Copyright (c) 2014, Ansitech Network Technology Co.,Ltd All rights reserved.
 * http://www.ansitech.com/weixin/sdk/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ansitech.weixin.sdk.message;

/**
 * POST的XML数据包转换为消息接受对象
 *
 * <p>由于POST的是XML数据包,所以不确定为哪种接受消息,<br/>
 * 所以直接将所有字段都进行转换,最后根据<tt>MsgType</tt>字段来判断取何种数据</p>
 *
 * @author qsyang<yangqisheng274@163.com>
 */
public class InputMessage {

    private String ToUserName;
    private String FromUserName;
    private Long CreateTime;
    private String MsgType = "text";
    private Long MsgId;
    // 文本消息
    private String Content;
    // 图片消息
    private String PicUrl;
    // 位置消息
    private String LocationX;
    private String LocationY;
    private Long Scale;
    private String Label;
    // 链接消息
    private String Title;
    private String Description;
    private String Url;
    // 语音信息
    private String MediaId;
    private String Format;
    private String Recognition;
    // 事件
    private String Event;
    private String EventKey;
    private String Ticket;

    public String getToUserName() {
        return ToUserName;
    }

    public void setToUserName(String toUserName) {
        ToUserName = toUserName;
    }

    public String getFromUserName() {
        return FromUserName;
    }

    public void setFromUserName(String fromUserName) {
        FromUserName = fromUserName;
    }

    public Long getCreateTime() {
        return CreateTime;
    }

    public void setCreateTime(Long createTime) {
        CreateTime = createTime;
    }

    public String getMsgType() {
        return MsgType;
    }

    public void setMsgType(String msgType) {
        MsgType = msgType;
    }

    public Long getMsgId() {
        return MsgId;
    }

    public void setMsgId(Long msgId) {
        MsgId = msgId;
    }

    public String getContent() {
        return Content;
    }

    public void setContent(String content) {
        Content = content;
    }

    public String getPicUrl() {
        return PicUrl;
    }

    public void setPicUrl(String picUrl) {
        PicUrl = picUrl;
    }

    public String getLocationX() {
        return LocationX;
    }

    public void setLocationX(String locationX) {
        LocationX = locationX;
    }

    public String getLocationY() {
        return LocationY;
    }

    public void setLocationY(String locationY) {
        LocationY = locationY;
    }

    public Long getScale() {
        return Scale;
    }

    public void setScale(Long scale) {
        Scale = scale;
    }

    public String getLabel() {
        return Label;
    }

    public void setLabel(String label) {
        Label = label;
    }

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return Description;
    }

    public void setDescription(String description) {
        Description = description;
    }

    public String getUrl() {
        return Url;
    }

    public void setUrl(String url) {
        Url = url;
    }

    public String getEvent() {
        return Event;
    }

    public void setEvent(String event) {
        Event = event;
    }

    public String getEventKey() {
        return EventKey;
    }

    public void setEventKey(String eventKey) {
        EventKey = eventKey;
    }

    public String getMediaId() {
        return MediaId;
    }

    public void setMediaId(String mediaId) {
        MediaId = mediaId;
    }

    public String getFormat() {
        return Format;
    }

    public void setFormat(String format) {
        Format = format;
    }

    public String getRecognition() {
        return Recognition;
    }

    public void setRecognition(String recognition) {
        Recognition = recognition;
    }

    public String getTicket() {
        return Ticket;
    }

    public void setTicket(String ticket) {
        Ticket = ticket;
    }
}
为了区分消息类型,我们定义了一个消息类型枚举对象

3.新建枚举com.ansitech.weixin.sdk.message.MsgType.java

/*
 * 微信公众平台(JAVA) SDK
 *
 * Copyright (c) 2014, Ansitech Network Technology Co.,Ltd All rights reserved.
 * http://www.ansitech.com/weixin/sdk/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ansitech.weixin.sdk.message;

/**
 * 消息类型
 *
 * @author qsyang<yangqisheng274@163.com>
 */
public enum MsgType {

    Text("text"),
    Image("image"),
    Music("music"),
    Video("video"),
    Voice("voice"),
    Location("location"),
    Link("link");
    private String msgType = "";

    MsgType(String msgType) {
        this.msgType = msgType;
    }

    /**
     * @return the msgType
     */
    @Override
    public String toString() {
        return msgType;
    }
}

基础工作先做到这,我们来补充一下WeixinUrlFilter的POST部分的代码

4.添加以下代码片段到“//处理接受消息”处

package com.ansitech.weixin.sdk;

import com.ansitech.weixin.sdk.message.InputMessage;
import com.ansitech.weixin.sdk.message.MsgType;
import com.ansitech.weixin.sdk.util.SHA1;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import ...

public class WeixinUrlFilter implements Filter {

    ...

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        //微信服务器将发送GET请求到填写的URL上,这里需要判定是否为GET请求  
        boolean isGet = request.getMethod().toLowerCase().equals("get");
        System.out.println("获得微信请求:" + request.getMethod() + " 方式");
        if (isGet) {
            ....
        } else {
            //处理接收消息  
            ServletInputStream in = request.getInputStream();
            //将POST流转换为XStream对象
            XStream xs = new XStream(new DomDriver());
            //将指定节点下的xml节点数据映射为对象
            xs.alias("xml", InputMessage.class);
            //将流转换为字符串
            StringBuilder xmlMsg = new StringBuilder();
            byte[] b = new byte[4096];
            for (int n; (n = in.read(b)) != -1;) {
                xmlMsg.append(new String(b, 0, n, "UTF-8"));
            }
            //将xml内容转换为InputMessage对象
            InputMessage inputMsg = (InputMessage) xs.fromXML(xmlMsg.toString());
            // 取得消息类型
            String msgType = inputMsg.getMsgType();
            //根据消息类型获取对应的消息内容
            if (msgType.equals(MsgType.Text.toString())) {
                //文本消息
                System.out.println("开发者微信号:" + inputMsg.getToUserName());
                System.out.println("发送方帐号:" + inputMsg.getFromUserName());
                System.out.println("消息创建时间:" + inputMsg.getCreateTime());
                System.out.println("消息内容:" + inputMsg.getContent());
                System.out.println("消息Id:" + inputMsg.getMsgId());
            }
        }
    }

    ...
}
到这里,基本上我们已经可以接受文本消息了,大家可以先用普通账号往你的服务发送一下文本消息测试一下吧。

如有疑问,请留言。

你可以微信关注我的订阅号:vzhanqun 微站管家

手把手教您开发JAVA微信SDK-接受消息


手把手教您开发JAVA微信SDK-接受消息,布布扣,bubuko.com

手把手教您开发JAVA微信SDK-接受消息

上一篇:在oracle下如何创建database link全面总结


下一篇:微信公众平台开发[13]-html5新颖活动-摇一摇