在微信公众号开发(1)中,我们进行了GET请求方法的开发编写,能够使微信与我们的服务器进行了关系的绑定,接下来我们进行开发接收用户消息与一些事件的回复;
开发必要了解:在我们微信与我们的服务器进行了关系的绑定后,微信会将用户所发过来的消息以及事件会以XML的格式以POST请求的方式发送给我们的服务器,所以我们需要开发POST请求的接口,接收用户的消息,我们可以根据用户的消息进行一些关键字回复,以及关注后的回复推送,微信事件里有很多功能,这里只进行开发关键字回复以及关注事件,其他的顺藤摸瓜按照微信文档完全可以开发出来,一样的套路----
1.为了方便开发,我先引入进来微信常用的接口和事件的常量,以及Xml转Map的工具类代码附上(红色部分我们需要配置成我们后台的参数):
package com.wx.project.util; public class WxParamConfig { public static final String TOKEN="chenyuesong";//为微信后台配置的token public static final String APPID="wx426aad126775582c";//为微信后台的appid public static final String ACCESS_TOKEN="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";//微信获取TOKEN地址 public static final String SEND_TEMPLATE="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";//模板发送地址 public static final String USER_INFO="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";//获取用户信息 public static final String MENU="https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";//微信菜单管理创建 public static final String LOGIN="https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";//微信公众号login地址,获取code public static final String USER_TOKEN="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";//通过code获取token票据 /* * 微信提供的事件类型 */ public static final String MESSAGE_TEXT="text"; public static final String MESSAGE_IMAGE="image"; public static final String MESSAGE_NEWS="news";//图文消息 public static final String MESSAGE_VIDEO="video"; public static final String MESSAGE_VOICE="voice"; public static final String MESSAGE_LINK="link"; public static final String MESSAGE_LOCATION="location"; public static final String MESSAGE_EVENT="event"; public static final String MESSAGE_SUBSCRIBE="subscribe";//消息关注 public static final String MESSAGE_UNSUBSCRIBE="unsubscribe";//取消关注 public static final String MESSAGE_CLICK="click";//菜单点击 public static final String MESSAGE_VIEW="view";//view菜单点击 }
xml转Map 工具类(在我的常用工具类中有这个工具类):---> https://www.cnblogs.com/iscys/p/9501155.html
2.进行POST方法的编写---->接收到微信的XML数据流---->xml转Map工具类进行数据的读取判断----->开发者自己的逻辑---->返回给微信数据----->发送成功
<1> Controller层的代码,我将业务逻辑的判断回复放在了Service层,来更加真实模拟开发环境
/* * 微信消息事件配置逻辑,微信公众号用户发出的请求都会进入POST方法进行接收,我们可以进行消息的回复,以及图文消息等等 * 需要注意的是数据的接收与回复都是XML的数据格式 */ @RequestMapping(value="/wxopen",method=RequestMethod.POST) public void MsgResponse(HttpServletRequest request,HttpServletResponse response) throws Exception { /* * 可以以来数据库内容进行动态的回复判断 */ //接收消息,将微信XML数据流消息转换为MAP数据格式 Map<String,String> map=WxParseXmlUtil.xmlTOMap(request); String ToUserName =map.get("ToUserName"); String FromUserName =map.get("FromUserName");//获取发送消息方的微信号 String MsgType =map.get("MsgType");//消息的类型 String Content =map.get("Content");//消息内容,我们根据消息的内容与消息的类型进行动态的实现自己的业务逻辑 //业务逻辑的实现在Service层,返回XML字符串 String contentXml=msgResponse.autoResponse(map); System.out.println(contentXml); PrintWriter writer=null; try { writer=response.getWriter(); writer.write(contentXml); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(writer !=null) { writer.close(); } } }
<2>.service 层代码,为了方便我们这里不进行数据库内容的获取
public String autoResponse(Map<String,String> map) { String ToUserName =map.get("ToUserName");//接收方的微信公众号; String FromUserName =map.get("FromUserName");//获取发送消息方的微信号 String MsgType =map.get("MsgType");//消息的类型 String Content =map.get("Content");//消息内容 String xmlStr =null; //用户关注时候的事件,用户关注时候微信或给我们XML中带有<MsgType>event</MsgType><Event></Event> if(WxParamConfig.MESSAGE_EVENT.equals(MsgType)) { if(WxParamConfig.MESSAGE_SUBSCRIBE.equals(map.get("Event"))) { //List<Map> content= msgmapper.getContentByWxType(WxParamConfig.MESSAGE_SUBSCRIBE); if(StringUtils.isEmpty(content)) { return xmlStr; } if("1".equals(content.get(0).get("type")+"")) { xmlStr=textMessage(content.get(0).get("digest"),ToUserName,FromUserName); } else if("0".equals(content.get(0).get("type")+"")) { xmlStr=newsMessage(content,FromUserName); } } } return xmlStr; }