本例中有些引用的类与方法不做过多介绍,之后会提供完整源码下载,请自行查看。
本篇根据开发者文档-接收事件推送编写。请对照查看,一些传入与返回参数就不过多介绍。地址为:https://mp.weixin.qq.com/wiki/14/f79bdec63116f376113937e173652ba2.html
在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息。其中,某些事件推送在发生后,是允许开发者回复用户的,某些则不允许
关注/取消关注事件
用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑。
微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次
关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。
假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
/* * 接收事件推送消息 * http://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html */ @XmlRootElement public class MsgBaseEvent { @XmlElement(name = "ToUserName") private String ToUserName; //开发者微信号 @XmlElement(name = "FromUserName") private String FromUserName; //发送方帐号(一个OpenID) @XmlElement(name = "CreateTime") private long CreateTime; //消息创建时间 (整型) @XmlElement(name = "MsgType") private String MsgType; //消息类型,event @XmlElement(name = "Event") private String Event; //事件类型 }
扫描带参数二维码事件
用户扫描带场景值二维码时,可能推送以下两种事件:
- 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
- 如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。
/* * 用户未关注时,进行关注后的事件推送 * Event 事件类型,subscribe * EventKey 事件KEY值,qrscene_为前缀,后面为二维码的参数值 * * 用户已关注时的事件推送 * Event 事件类型,SCAN * EventKey 事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id */ @XmlRootElement public class MsgScanCodeEvent extends MsgBaseEvent { @XmlElement(name = "EventKey") private String EventKey; //事件KEY值,qrscene_为前缀,后面为二维码的参数值 @XmlElement(name = "Ticket") private String Ticket; //二维码的ticket,可用来换取二维码图片 public String getEventKey() { return EventKey; } public void setEventKey(String eventKey) { EventKey = eventKey; } public String getTicket() { return Ticket; } public void setTicket(String ticket) { Ticket = ticket; } /* * 接收到的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[FromUser]]></FromUserName> * <CreateTime>123456789</CreateTime> * <MsgType><![CDATA[event]]></MsgType> * <Event><![CDATA[subscribe|SCAN]]></Event> * <EventKey><![CDATA[qrscene_123123|SCENE_VALUE]]></EventKey> * <Ticket><![CDATA[TICKET]]></Ticket> * </xml> */ public static MsgScanCodeEvent requestMessage(String xmlStr) throws JAXBException { xmlStr = xmlStr.replace("xml", "msgScanCodeEvent"); JAXBContext context = JAXBContext.newInstance(MsgScanCodeEvent.class); Unmarshaller unmarshaller = context.createUnmarshaller(); return (MsgScanCodeEvent)unmarshaller.unmarshal(new StringReader(xmlStr)); } }
上报地理位置事件
用户同意上报地理位置后,每次进入公众号会话时,都会在进入时上报地理位置,或在进入会话后每5秒上报一次地理位置,公众号可以在公众平台网站中修改以上设置。上报地理位置时,微信会将上报地理位置事件推送到开发者填写的URL。
/* * Event---> * LOCATION */ @XmlRootElement public class MsgLocationEvent extends MsgBaseEvent { @XmlElement(name = "Latitude") private float Latitude; //地理位置纬度 @XmlElement(name = "Longitude") private float Longitude; //地理位置经度 @XmlElement(name = "Precision") private float Precision; //地理位置精度 public float getLatitude() { return Latitude; } public void setLatitude(float latitude) { Latitude = latitude; } public float getLongitude() { return Longitude; } public void setLongitude(float longitude) { Longitude = longitude; } public float getPrecision() { return Precision; } public void setPrecision(float precision) { Precision = precision; } /* * 接收到的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>1348831860</CreateTime> * <MsgType><![CDATA[event]]></MsgType> * <Event><![CDATA[LOCATION]]></Event> * <Latitude>23.137466</Latitude> * <Longitude>113.352425</Longitude> * <Precision>119.385040</Precision> * </xml> */ public static MsgLocationEvent requestMessage(String xmlStr) throws JAXBException { xmlStr = xmlStr.replace("xml", "msgLocationEvent"); JAXBContext context = JAXBContext.newInstance(MsgLocationEvent.class); Unmarshaller unmarshaller = context.createUnmarshaller(); return (MsgLocationEvent)unmarshaller.unmarshal(new StringReader(xmlStr)); } }
自定义菜单事件
用户点击自定义菜单后,微信会把点击事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报。
点击菜单拉取消息时的事件推送
/* * Event---> * click:点击菜单拉取消息时的事件推送 */ @XmlRootElement public class MenuClickEvent extends MenuBaseEvent { /* * 接收到的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[FromUser]]></FromUserName> * <CreateTime>123456789</CreateTime> * <MsgType><![CDATA[event]]></MsgType> * <Event><![CDATA[CLICK]]></Event> * <EventKey><![CDATA[EVENTKEY]]></EventKey> * </xml> */ public static MenuClickEvent requestMessage(String xmlStr) throws JAXBException { xmlStr = xmlStr.replace("xml", "menuClickEvent"); JAXBContext context = JAXBContext.newInstance(MenuClickEvent.class); Unmarshaller unmarshaller = context.createUnmarshaller(); return (MenuClickEvent)unmarshaller.unmarshal(new StringReader(xmlStr)); } }
点击菜单跳转链接时的事件推送
/* * Event---> * view:点击菜单跳转链接时的事件推送 */ @XmlRootElement public class MenuViewEvent extends MenuBaseEvent { @XmlElement(name = "MenuId") private String MenuId ; //指菜单ID,如果是个性化菜单,则可以通过这个字段,知道是哪个规则的菜单被点击了。 public String getMenuId() { return MenuId; } public void setMenuId(String menuId) { MenuId = menuId; } /* * 接收到的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[FromUser]]></FromUserName> * <CreateTime>123456789</CreateTime> * <MsgType><![CDATA[event]]></MsgType> * <Event><![CDATA[VIEW]]></Event> * <EventKey><![CDATA[www.qq.com]]></EventKey> * <MenuId>MENUID</MenuId> * </xml> */ public static MenuViewEvent requestMessage(String xmlStr) throws JAXBException { xmlStr = xmlStr.replace("xml", "menuViewEvent"); JAXBContext context = JAXBContext.newInstance(MenuViewEvent.class); Unmarshaller unmarshaller = context.createUnmarshaller(); return (MenuViewEvent)unmarshaller.unmarshal(new StringReader(xmlStr)); } }