您的位置:首页 > 移动开发 > 微信开发

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

2014-03-24 09:57 561 查看
首先感谢大家的支持!

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

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

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

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

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

这些消息虽然很多很复杂,但是他们有一个共同的点,那就是都是通过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 微站管家

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: