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

(Java)微信之个人公众账号开发(二)——接收并处理用户消息 (中)

2014-03-05 20:56 816 查看
我们继续来看MessageUtil(消息解析工具类)的完整代码:

/**
* 消息工具类
*
* @author liufeng
* @date 2013-05-19
*/
public class MessageUtil {
// 返回消息类型:文本
public static final String RESP_MESSAGE_TYPE_TEXT = "text";
// 返回消息类型:音乐
public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
// 返回消息类型:图文
public static final String RESP_MESSAGE_TYPE_NEWS = "news";
// 请求消息类型:文本
public static final String REQ_MESSAGE_TYPE_TEXT = "text";
// 请求消息类型:图片
public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
// 请求消息类型:链接
public static final String REQ_MESSAGE_TYPE_LINK = "link";
// 请求消息类型:地理位置
public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
// 请求消息类型:音频
public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
// 请求消息类型:推送
public static final String REQ_MESSAGE_TYPE_EVENT = "event";
// 事件类型:subscribe(订阅)
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
// 事件类型:unsubscribe(取消订阅)
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
// 事件类型:CLICK(自定义菜单点击事件)
public static final String EVENT_TYPE_CLICK = "CLICK";

/**
* 解析微信发来的请求(XML)
* @param request
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
// 将解析结果存储在HashMap中
Map<String, String> map = new HashMap<String, String>();
// 从request中取得输入流
InputStream inputStream = request.getInputStream();
// 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点
for (Element e : elementList)
map.put(e.getName(), e.getText());
// 释放资源
inputStream.close();
inputStream = null;
return map;
}
//文本消息对象转换成xml
public static String textMessageToXml(TextMessage textMessage) {
xstream.alias("xml", textMessage.getClass());
return xstream.toXML(textMessage);
}
//音乐消息对象转换成xml
public static String musicMessageToXml(MusicMessage musicMessage) {
xstream.alias("xml", musicMessage.getClass());
return xstream.toXML(musicMessage);
}
// 图文消息对象转换成xml
public static String newsMessageToXml(NewsMessage newsMessage) {
xstream.alias("xml", newsMessage.getClass());
xstream.alias("item", new Article().getClass());
return xstream.toXML(newsMessage);
}
//扩展xstream,使其支持CDATA块
private static XStream xstream = new XStream(new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
// 对所有xml节点的转换都增加CDATA标记
boolean cdata = true;
@SuppressWarnings("unchecked")
public void startNode(String name, Class clazz) {
super.startNode(name);
}
protected void writeText(QuickWriter writer, String text) {
if (cdata) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});

/**
* 判断是否是QQ表情
* @param content
* @return
*/
public static boolean isQqFace(String content) {
boolean result = false;
// 判断QQ表情的正则表达式
String qqfaceRegex = "/::\\)|/::~|/::B|/::\\||/:8-\\)|/::<|/::$|/::X|/::Z|/::'\\(|/::-\\||/::@|/::P|/::D|/::O|/::\\(|/::\\+|/:--b|/::Q|/::T|/:,@P|/:,@-D|/::d|/:,@o|/::g|/:\\|-\\)|/::!|/::L|/::>|/::,@|/:,@f|/::-S|/:\\?|/:,@x|/:,@@|/::8|/:,@!|/:!!!|/:xx|/:bye|/:wipe|/:dig|/:handclap|/:&-\\(|/:B-\\)|/:<@|/:@>|/::-O|/:>-\\||/:P-\\(|/::'\\||/:X-\\)|/::\\*|/:@x|/:8\\*|/:pd|/:<W>|/:beer|/:basketb|/:oo|/:coffee|/:eat|/:pig|/:rose|/:fade|/:showlove|/:heart|/:break|/:cake|/:li|/:bome|/:kn|/:footb|/:ladybug|/:shit|/:moon|/:sun|/:gift|/:hug|/:strong|/:weak|/:share|/:v|/:@\\)|/:jj|/:@@|/:bad|/:lvu|/:no|/:ok|/:love|/:<L>|/:jump|/:shake|/:<O>|/:circle|/:kotow|/:turn|/:skip|/:oY|/:#-0|/:hiphot|/:kiss|/:<&|/:&>";
Pattern p = Pattern.compile(qqfaceRegex);
Matcher m = p.matcher(content);
if (m.matches()) {
result = true;
}
return result;
}

/**
* 计算采用utf-8编码方式时字符串所占字节数
* @param content
* @return
*/
public static int getByteSize(String content) {
int size = 0;
if (null != content) {
try {
// 汉字采用utf-8编码时占3个字节
size = content.getBytes("utf-8").length;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return size;
}

}
大家可以看到,它其实就是根据用户发来的信息,自定义的一些回复内容,以达到简单的人机交互目的,再回过头来看BylService:




这一步,Map<String,String> requestMap = MessageUtil.parseXml(request);,通过MessageUtil.parseXml将请求数据解析后数据放进map,然后就尅通过map去一一获得各参数值,默认回复的消息是文本类型,如上图,通过requestMap.get("MsgType");,可以得到请求消息类型,通过requestMap.get("Content");可以得到消息内容,接下来就是判断请求消息类型:

// 文本消息
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
//DisposeMsgUtil是对文本消息的处理工具类
textMessage.setContent(DisposeMsgUtil.disposeMsg(content));

textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}

如果是文本消息则执行里面的程序,通过DisposeMsgUtil.disposeMsg(content)获得返回内容,然后通过textMessage.setContent,封装回复消息内容,比如:

用户输入"你好",那么requestMap.get("MsgType")就等于"text",那么if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT))成立,则执行里面对应的程序,通过DisposeMsgUtil.disposeMsg(content),将返回字符串"ipastor很好,谢谢您的关心"+"/微笑",然后通过MessageUtil.textMessageToXml(textMessage)处理后转换为xml格式,回复给用户,如图:



当然,当消息类型为其他类型时,大家可以根据实际情况做相应的处理。上图中的表情符我直接用"/微笑"返回就可以了,因为表情符传输过来时,其实转换成了文本类型,每个表情符都对应相应的代码,在DisposeMsgUtil中有如下判断:

if(MessageUtil.isQqFace(content)){
repMsg=content;
}

而MessageUtil中的isQqFace方法就是判断用户是否发来的是表情,代码如下:

/**
* 判断是否是QQ表情
* @param content
* @return
*/
public static boolean isQqFace(String content) {
boolean result = false;
// 判断QQ表情的正则表达式
String qqfaceRegex = "/::\\)|/::~|/::B|/::\\||/:8-\\)|/::<|/::$|/::X|/::Z|/::'\\(|/::-\\||/::@|/::P|/::D|/::O|/::\\(|/::\\+|/:--b|/::Q|/::T|/:,@P|/:,@-D|/::d|/:,@o|/::g|/:\\|-\\)|/::!|/::L|/::>|/::,@|/:,@f|/::-S|/:\\?|/:,@x|/:,@@|/::8|/:,@!|/:!!!|/:xx|/:bye|/:wipe|/:dig|/:handclap|/:&-\\(|/:B-\\)|/:<@|/:@>|/::-O|/:>-\\||/:P-\\(|/::'\\||/:X-\\)|/::\\*|/:@x|/:8\\*|/:pd|/:<W>|/:beer|/:basketb|/:oo|/:coffee|/:eat|/:pig|/:rose|/:fade|/:showlove|/:heart|/:break|/:cake|/:li|/:bome|/:kn|/:footb|/:ladybug|/:shit|/:moon|/:sun|/:gift|/:hug|/:strong|/:weak|/:share|/:v|/:@\\)|/:jj|/:@@|/:bad|/:lvu|/:no|/:ok|/:love|/:<L>|/:jump|/:shake|/:<O>|/:circle|/:kotow|/:turn|/:skip|/:oY|/:#-0|/:hiphot|/:kiss|/:<&|/:&>";
Pattern p = Pattern.compile(qqfaceRegex);
Matcher m = p.matcher(content);
if (m.matches()) {
result = true;
}
return result;
}

当用户输入表情时,ipastor(我的个人公众账号)会返回相同的表情:



当然根据不同的消息类型,大家可以做相应的处理,这篇文章就先讲到这里。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐