用户向公众号发送的消息是通过我们的那个路径的post方法,发送到我们的项目的。
微信通过get的方法将发送给我们以上信息。用户通过这个路径的post方法向公众号发送消息
成为开发者后,用户每次向公众号发送消息、或者产生自定义菜单、或产生微信支付订单等情况时,开发者填写的服务器配置URL将得到微信服务器推送过来的消息和事件,开发者可以依据自身业务逻辑进行响应,如回复消息。 公众号调用各接口时,一般会获得正确的结果,具体结果可见对应接口的说明。返回错误时,可根据返回码来查询错误原因。全局返回码说明 用户向公众号发送消息时,公众号方收到的消息发送者是一个OpenID,是使用用户微信号加密后的结果,每个用户对每个公众号有一个唯一的OpenID。 此外,由于开发者经常有需在多个平台(移动应用、网站、公众帐号)之间共通用户帐号,统一帐号体系的需求,微信开放平台(open.weixin.qq.com)提供了UnionID机制。开发者可通过OpenID来获取用户基本信息,而如果开发者拥有多个应用(移动应用、网站应用和公众帐号,公众帐号只有在被绑定到微信开放平台帐号下后,才会获取UnionID),可通过获取用户基本信息中的UnionID来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的UnionID是唯一的。换句话说,同一用户,对同一个微信开放平台帐号下的不同应用,UnionID是相同的。详情请在微信开放平台的资源中心-移动应用开发-微信登录-授权关系接口调用指引-获取用户个人信息(UnionID机制)中查看。 另请注意,微信公众号接口必须以http://或https://开头,分别支持80端口和443端口。
注意 使用dom4j可以将这个xml包解析成一个Map
<dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> /** * 使用dom4j包 解析xml数据包 成Map形式 * @param inputStream * @return */ @Override public Map<String, String> parseRequest(ServletInputStream inputStream) { HashMap<String, String> hashMap = new HashMap<>(); SAXReader reader = new SAXReader(); try { //读取输入流 回去文档对象 Document document = reader.read(inputStream); //根据文档对象 回去根节点 Element rootElement = document.getRootElement(); //根据根节点获取所有的子节点 List<Element> elements = rootElement.elements(); for (Element element : elements) { hashMap.put(element.getName(), element.getStringValue()); } } catch (DocumentException e) { e.printStackTrace(); } return hashMap; } {Content=你好, CreateTime=1602226910, ToUserName=gh_f7a997c7d45c, FromUserName=oCV_T6IutImdnwuD658EyIMM_goU, MsgType=text, MsgId=22938375251956865}各种消息的xml数据包的格式
文本消息 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> </xml> 图片消息 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[image]]></MsgType> <PicUrl><![CDATA[this is a url]]></PicUrl> <MediaId><![CDATA[media_id]]></MediaId> <MsgId>1234567890123456</MsgId> </xml> 语音消息 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[voice]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <Format><![CDATA[Format]]></Format> <MsgId>1234567890123456</MsgId> </xml> 视频消息 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[video]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId> <MsgId>1234567890123456</MsgId> </xml> 小视频消息 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[shortvideo]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId> <MsgId>1234567890123456</MsgId> </xml> 位置消息 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1351776360</CreateTime> <MsgType><![CDATA[location]]></MsgType> <Location_X>23.134521</Location_X> <Location_Y>113.358803</Location_Y> <Scale>20</Scale> <Label><![CDATA[位置信息]]></Label> <MsgId>1234567890123456</MsgId> </xml> 链接消息 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1351776360</CreateTime> <MsgType><![CDATA[link]]></MsgType> <Title><![CDATA[公众平台官网链接]]></Title> <Description><![CDATA[公众平台官网链接]]></Description> <Url><![CDATA[url]]></Url> <MsgId>1234567890123456</MsgId> </xml>我们需要创建对应的实体类对象来接收这些xml数据包的数据。因为这些不同形式的xml数据包都有一些相同的属性:ToUserName 接收方微信号、FromUserName 发送方微信号,若为普通用户,则是一个OpenID、CreateTime 消息创建时间、MsgType 消息类型,链接为link。所以我们将这些作为基础属性,其他的对象直接继承这个基础类即可。
注意 使用xstream包将Map转化成xml数据包的形式发送会微信服务器。实现回复消息的功能。
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.11.1</version> </dependency> /** * 用于处理所有的事件和消息de 回复 * 将Map解析成xml数据包 回复消息 * @param map * @return 返回的是xml数据包 */ @Override public String getRespose(Map<String, String> map) { String msgType = map.get("MsgType"); BaseMessage msg = null; XStream stream = new XStream(); switch (msgType){ case "text": msg = dealText(map); stream.processAnnotations(TextMessage.class); break; case "image": break; case "voice": break; case "video": break; case "shortvideo": break; case "location": break; case "link": break; default: break; } String msgXML = stream.toXML(msg); System.out.println(msg); System.out.println(msgXML); return stream.toXML(msg); } /** * 处理文本消息 * @param map * @return */ private BaseMessage dealText(Map<String, String> map) { TextMessage textMessage =null; if (map.get("Content").matches(".*尚祥光.*")){ textMessage = new TextMessage(map,"不好意思,我不认识那个沙雕~~"); }else if (map.get("Content").matches(".*刘世豪.*")){ textMessage = new TextMessage(map,"百度百科:刘世豪是一个聪明能干有吃苦耐劳的好孩子~~"); }else if (map.get("Content").matches(".*王宝智.*")){ textMessage = new TextMessage(map,"保智我知道,你找他有什么事情吗"); }else if (map.get("Content").matches(".*薛亚飞.*")){ textMessage = new TextMessage(map,"大飞哥,可以,月薪过万,光电班领头羊,黄科院之光!"); }else if (map.get("Content").matches(".*王艺曈.*")){ textMessage = new TextMessage(map,"温柔善良可爱美丽,是刘世豪的女朋友~~"); }else if (map.get("Content").matches(".*刘明珠.*")){ textMessage = new TextMessage(map,"一个湖南人,懂得都懂~~"); }else { textMessage = new TextMessage(map,"尊敬的会员,您好,很高兴为您服务!"); } return textMessage; }注意 这样解析出来的xml包的根节点是包名。这样是无法使用的。 解决方法:
注意 标签是小写这样即使解析了也无法使用, 解决方法: 在属性上也加上@XStreamAlias注解。
