文档章节

微信开发:消息管理

点点与麦兜
 点点与麦兜
发布于 2016/09/29 16:53
字数 1834
阅读 201
收藏 1
点赞 0
评论 0

 

一,接收微信消息

      上一篇博文是介绍如何进行服务器端配置,配置的相当于为微信的消息接口,微信向服务器端推送消息或者推送用户发送的消息就会推送到该配置的URL中,配置好了过后,我们就需要在服务器端接收用户发送的一系列消息。

       服务器端接收用户消息和接收微信推送消息是使用的同一个地址,但是有一个区别接收推送消息为GET方法,接收用户发送的消息为POST方法。

       使用流接收POST消息转为String结果为XML的消息体,如果是在微信后台选择的为安全模式则需要解密,若是明文模式,那就直接解析XML就是了,此处为加密模式需用到解密类,本博文使用的为微信提供的解密类。链接为:

微信加解密文档:
http://mp.weixin.qq.com/wiki/11/2d2d1df945b75605e7fea9ea2573b667.html
加解密代码:
http://mp.weixin.qq.com/wiki/static/assets/a5a22f38cb60228cb32ab61d9e4c414b.zip

 

环境为:SpringMvc4     
栗子:

    //微信接收消息接口
    @ResponseBody
	@RequestMapping(value = "signature",method = RequestMethod.POST)
	public String signature(HttpServletRequest request) throws AesException{
		try {
            //接收流
			ServletInputStream sis = request.getInputStream();
			StringBuilder xmlMsg = new StringBuilder();  
		        byte[] b = new byte[4096];  
		        for (int n; (n = sis.read(b)) != -1;) {  
		            xmlMsg.append(new String(b, 0, n, "UTF-8"));  
		     }  
			    System.out.println(xmlMsg);
                //接收加密的xml
				Object[] encrypt = XMLParse.extract(xmlMsg.toString());
				//解密
		        WXBizMsgCrypt  wxcpt = new WXBizMsgCrypt("token", 
				                                         "encodingAesKey",
				                                         "appid");
                //获取解密后的XML
		        String msg = wxcpt.decrypt(encrypt[1].toString());
                //转对象
		        WxMsgRequest wmr = this.convertWxMesgToObj(msg);
		        System.out.println(wmr);

                if(wmr.getMsgType().equals(WxRequestMsgType.MSG_TEXT)){
		        	WxTextMsgResponse wtmr = new WxTextMsgResponse();
		        	wtmr.setContent("点点与麦兜的TEST");
		        	Long createTime = System.currentTimeMillis() / 1000;
		        	wtmr.setCreateTime(createTime.toString());
		        	wtmr.setFromUserName(wmr.getToUserName());
		        	wtmr.setToUserName(wmr.getFromUserName());
		        	wtmr.setMsgType(WxRequestMsgType.MSG_TEXT);
		        	
		        	String returnStr = this.convertObjToXml(wtmr);
		        	return returnStr;
		        }

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	//微信验证接口
	@ResponseBody
	@RequestMapping(value = "signature",method=RequestMethod.GET)
	public String signature(String signature,
							String timestamp,
							String nonce,
							String echostr){
		try {	
			String shaPw = SHA1.getSHA1("xiaofli007", timestamp, nonce);
			if(signature.equals(shaPw))
				return echostr;
			else
				return null;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
		
	}
  //将xml数据解析为对象
  private WxMsgRequest convertWxMesgToObj(String msg) throws JAXBException{
		JAXBContext context = JAXBContext.newInstance(WxMsgRequest.class);  
        Unmarshaller unmarshaller = context.createUnmarshaller();  
        return (WxMsgRequest)unmarshaller.unmarshal(new StringReader(msg));
	}
  //将对象转为xml字符串
  public String convertObjToXml(Object obj) throws JAXBException{
		JAXBContext context = JAXBContext.newInstance(obj.getClass());  
        Marshaller marshaller = context.createMarshaller();  
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        StringWriter writer = new StringWriter();  
        marshaller.marshal(obj, writer);  
        String temp =  writer.toString();
        return  temp; 
	}

解密前消息: 

<xml>
    <ToUserName><![CDATA[gh_e1c44a3a9f81]]></ToUserName>
    <Encrypt><![CDATA[HusAtbuEO8XmYaH4tzuZHcdi7Kg2e6szJfZrzdQLnpEs6D0jrNWKLFYftafLyKLFy7sOPbQUYI8DaVPPV/0npFSRym2oskoN0ip3q93XXtunbz5OBmWlYsvKnJuYK/UlIttgrJbrRFJlz4AKiHYUnJx7vaSAFvErAlhudPA1rhPEa64sARRGRQhrP1m/zffbSRl6uI7Wz1jsIsfiZAPg0nxqfxdDXh9Gklcp6DNHhf3phAx9pt8kyZKh4n8yhHV1+R+WU0c86YEgwQ7NHgA0CaryQPemkNRF06YrWEvE0meToeT08sm2A0bZJUiGGmj8dD9/b6KsESaQmfsF2JzdRvSq79gLO+Mn0swQS4wjOnbrgw7otvlYCZnDu4+xcfv+lGgMIc0YfG/jtT4VH6pboBtm1xCRs01N14SHB8pGryA=]]></Encrypt>
</xml>

解密后的消息:

<xml>
<ToUserName><![CDATA[gh_e1c44a3a9f81]]></ToUserName>
<FromUserName><![CDATA[oMffXwBl4N4F29vbH3UAbrdhMq4Y]]></FromUserName>
<CreateTime>1475129963</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[11]]></Content>
<MsgId>6335634948877288984</MsgId>
</xml>

二,识别消息

      1、消息类型:

           文本消息(text)
           图片消息(image)
           语音消息(voice)
           视频消息(video)
           小视频消息 (shortvideo)
           地理位置消息(location)
           链接消息(link)

创建一个实体类,用于接受消息(为了方便我是全部字段写到一个类中,也可以先判断类型:再指定接受的类型):

@XmlRootElement(name = "xml")
public class WxMsgRequest {
	
    /*** 开发者微信号 */
	private String ToUserName;
	/*** 发送方帐号(一个OpenID)*/
	private String FromUserName;
	/*** 消息创建时间 (整型)*/
	private String CreateTime;
	/*** 消息类型有:text ; event ; 语音为voice*/
	private String MsgType;
	/*** 消息id*/
	private String MsgId;
	/*** 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。*/
	private String MediaId;
	/*** 语音格式,如amr,speex等*/
	private String Format;
	/*** 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。*/
	private String ThumbMediaId;
	/*** 文本消息内容*/
	private String Content;
    /*** 图片消息URL*/
	private String picUrl;
	/*** 地理位置消息 地理位置纬度*/
	private String gpsX;
	/*** 地理位置消息 地理位置经度*/
	private String gpsY;
	/*** 地理位置消息 地图缩放大小*/
	private String scale;
	/*** 地理位置消息 地理位置信息*/
	private String label;
	/*** 链接消息 消息标题*/
	private String title;
	/*** 链接消息 消息描述*/
	private String description;
	/*** 链接消息 消息链接*/
	private String url;
    /**
	 * 事件类型,subscribe(订阅)、unsubscribe(取消订阅)、CLICK(自定义菜单点击事件)
	 * WeixinRequestMsgType#SUBSCRIBE_EVENT
	 */
	private String Event;
	/*** 事件KEY值,与自定义菜单接口中KEY值对应*/
	private String EventKey;
	/** 二维码的ticket,可用来换取二维码图片 **/
	private String Ticket;

	@XmlElement(name = "Ticket")
	public String getTicket() {
		return Ticket;
	}

	public void setTicket(String ticket) {
		Ticket = ticket;
	}
    //由于文章篇幅问题,下面的参数set方法和get方法就不展示了。。每个get方法加@XmlElement(name="参数名")
	}

将xml解析成对象:

private WxMsgRequest convertWxMesgToObj(String msg) throws JAXBException{
		JAXBContext context = JAXBContext.newInstance(WxMsgRequest.class);  
        Unmarshaller unmarshaller = context.createUnmarshaller();  
        return (WxMsgRequest)unmarshaller.unmarshal(new StringReader(msg));
	}

三,回复消息

        1、消息回复类型:

             文本消息(text)
             图片消息 ( image )
             语音消息 ( voice )
             视频消息 ( video )
             音乐消息 ( music )
             图文消息 ( picurl )

 此处栗子为文本消息回复。
 创建一个微信消息类型实体,用于判断消息类型:

public class WxRequestMsgType {

	/*** 请求的,应答的,文本推送消息 */
	public static final String MSG_TEXT = "text";

	/**** 请求的, 图片推送消息*/
	public static final String MSG_IMAGE = "image";

	/*** 请求的, 地理位置信息*/
	public static final String MSG_LOCATION = "location";

	/*** 请求的, 链接信息*/
	public static final String MSG_LINK = "link";

	/*** 请求的,事件推送消息*/
	public static final String MSG_EVENT = "event";

	/*** 应答的,图文消息体*/
	public static final String MSG_NEW = "news";

	/*** 请求的,语音推送消息*/
	public static final String MSG_VOICE = "voice";

    /*** 事件类型订阅*/
	public static final String EVENT_SUBSCRIBE = "subscribe";

	/*** 事件取消订阅*/
	public static final String EVENT_UNSUBSCRIBE = "unsubscribe";

	/*** 自定义菜单的点击事件*/
	public static final String EVENT_CLICK = "CLICK";

	public static final String EVENT_SCAN = "SCAN";
	/**
	 * 如果公众号处于开发模式,需要在接收到用户发送的消息时, 返回一个MsgType为transfer_customer_service的消息,
	 * 微信服务器在收到这条消息时,会把这次发送的消息转到多客服系统。 用户被客服接入以后,客服关闭会话以前,处于会话过程中,
	 * 用户发送的消息均会被直接转发至客服系统
	 */
	public static final String TRANSFER_CUSTOMER_SERVICE_MSG = "transfer_customer_service";
}

创建文本回复实体:

@XmlRootElement(name = "xml")
public class WxTextMsgResponse{
	/*** 开发者微信号*/
	private String ToUserName;
	/*** 发送方帐号(一个OpenID)*/
	private String FromUserName;
	/*** 消息创建时间 (整型)*/
	private String CreateTime;
	/*** 应答消息类型有: news ;text;*/
	private String MsgType;
	/*** 文本消息内容*/
	private String Content;
	/**
	 * 位0x0001被标志时,星标刚收到的消息。
	 */
	private String FuncFlag;

    @XmlElement(name = "Content")
	public String getContent() {
		return Content;
	}

	public void setContent(String content) {
		Content = content;
	}
   //省略其他get、set方法
}

           2,判断回复

JAXB2对象转为XML字符串:

public String convertObjToXml(Object obj) throws JAXBException{
		JAXBContext context = JAXBContext.newInstance(obj.getClass());  
        Marshaller marshaller = context.createMarshaller();  
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        StringWriter writer = new StringWriter();  
        marshaller.marshal(obj, writer);  
        String temp =  writer.toString();
        return  temp; 
	}

 在signature、POST方法中加入文本消息的判断进行回复:

if(wmr.getMsgType().equals(WxRequestMsgType.MSG_TEXT)){
		        	WxTextMsgResponse wtmr = new WxTextMsgResponse();
		        	wtmr.setContent("点点与麦兜的TEST");
		        	Long createTime = System.currentTimeMillis() / 1000;
		        	wtmr.setCreateTime(createTime.toString());
		        	wtmr.setFromUserName(wmr.getToUserName());
		        	wtmr.setToUserName(wmr.getFromUserName());
		        	wtmr.setMsgType(WxRequestMsgType.MSG_TEXT);
		        	
		        	String returnStr = this.convertObjToXml(wtmr);
		        	return returnStr;
         }

四,场景应用

此处只举例了消息接受和文本消息的回复,后面还有主动推送消息、还有其他事件,比如关注事件,取消关注事件等、这里就不一一举例了,其他事件接受和回复请查看微信开发文档(其实是大同小异)


1,这个回复其实可以做一个后台自动回复管理。比如后台设置关键字回复、被添加回复、自动回复,发送过来的消息进行内容识别,是否为关键字,或者自动回复等。

© 著作权归作者所有

共有 人打赏支持
点点与麦兜
粉丝 2
博文 5
码字总数 7305
作品 0
成都
程序员
C#开发微信门户及应用(2)--微信消息的处理和应答

微信应用如火如荼,很多公司都希望搭上信息快车,这个是一个商机,也是一个技术的方向,因此,有空研究下、学习下微信的相关开发,也就成为计划的安排事情之一了。本系列文章希望从一个循序渐...

walb呀 ⋅ 2017/12/04 ⋅ 0

C#开发微信门户及应用(8)-微信门户应用管理系统功能介绍

最近对微信接口进行深入的研究,通过把底层接口一步步进行封装后,逐步升级到自动化配置、自动化应答,以及后台处理界面的优化和完善上,力求搭建一个较为完善、适用的微信门户应用管理系统。...

walb呀 ⋅ 2017/12/04 ⋅ 0

C#开发微信门户及应用(25)-微信企业号的客户端管理功能

我们知道,微信公众号和企业号都提供了一个官方的Web后台,方便我们对微信账号的配置,以及相关数据的管理功能,对于微信企业号来说,有通讯录中的组织架构管理、标签管理、人员管理、以及消...

walb呀 ⋅ 2017/12/04 ⋅ 0

C#开发微信门户及应用(7)-微信多客服功能及开发集成

最近一直在弄微信的集成功能开发,发现微信给认证账户开通了一个多客服的功能,对于客户的咨询,可以切换至客服处理的方式,而且可以添加多个客服进行处理,这个在客户咨询比较多的时候,是一...

walb呀 ⋅ 2017/12/04 ⋅ 0

C#开发微信门户及应用(20)-微信企业号的菜单管理

前面几篇陆续介绍了很多微信企业号的相关操作,企业号和公众号一样都可以自定义菜单,因此他们也可以通过API进行菜单的创建、获取列表、删除的操作,因此本篇继续探讨这个主体,介绍企业号的...

walb呀 ⋅ 2017/12/04 ⋅ 0

C#开发微信门户及应用(16)-微信企业号的配置和使用

在本系列随笔的前面,主要就是介绍微信公众号的门户应用开发,最近把整个微信框架进行了扩展补充,增加了最新的企业号的API封装和开发,后续主要介绍如何利用C#进行微信企业号的开发工作,本...

walb呀 ⋅ 2017/12/04 ⋅ 0

JeeWx 捷微 2.3 发布,JAVA微信管家平台

JeeWx,敏捷微信开发,简称“捷微”,捷微是一款免费开源的JAVA微信管家平台 一、简介 Jeewx是一个开源、高效、敏捷的微信开发平台,采用JAVA语言基于Jeecg快速开发框架实现,Jeewx开源版实现...

Jeecg ⋅ 2016/03/24 ⋅ 0

C#开发微信门户及应用(24)-微信小店货架信息管理

在前面微信小店系列篇《C#开发微信门户及应用(22)-微信小店的开发和使用》里面介绍了一些微信小店的基础知识,以及《C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试》里面详细介...

walb呀 ⋅ 2017/12/04 ⋅ 0

C#开发微信门户及应用(26)-公众号微信素材管理

微信公众号最新修改了素材的管理模式,提供了两类素材的管理:临时素材和永久素材的管理,原先的素材管理就是临时素材管理,永久素材可以永久保留在微信服务器上,微信素材可以在上传后,进行...

walb呀 ⋅ 2017/12/04 ⋅ 0

Jeewx捷微 , 免费微信公众账号管家系统发布,采用JAVA语言

JeeWx, 微信管家平台,简称“捷微”. 捷微是一款免费开源的JAVA微信公众账号开发平台. 当前最新版本: 2.3(发布日期:20160323) 一、捷微Jeewx简介 Jeewx是一个开源、高效、敏捷的微信开发...

Jeecg ⋅ 2016/03/24 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 26分钟前 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 45分钟前 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 56分钟前 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 1

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

CentOS开机启动subversion

建立自启动脚本: vim /etc/init.d/subversion 输入如下内容: #!/bin/bash## subversion startup script for the server## chkconfig: 2345 90 10# description: start the subve......

随风而飘 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部