1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 微信公众号的二次开发(三 接收事件推送获取用户信息)

微信公众号的二次开发(三 接收事件推送获取用户信息)

时间:2022-07-08 19:10:06

相关推荐

微信公众号的二次开发(三 接收事件推送获取用户信息)

在上篇《微信公众号的二次开发(二 自定义菜单的创建)》中我们介绍了自定义菜单的创建。本篇文章将介绍如何通过接收事件推送来获取用户信息。首先我们阅读官方文档:

根据官方文档的介绍 微信公众号会将时间推送到开发者填写的URL上,这个URL就是我们在

微信公众号的二次开发(一 订阅号没有获取网页授权的解决方法) 中配置的服务器配置的地址。这里还有一点要注意,在配置服务器地址时,官方文档上明确注明接口为GET方法。

而在接受推送事件时,我们就要用POST方法来接受微信后台传递的数据。

@ApiOperation("Used to Verify the Signature of Wechat Public Platform")@RequestMapping(value = "checkSignature", method = RequestMethod.POST)public void responseEvent(HttpServletRequest req, HttpServletResponse resp,HttpSession session) throws Exception {req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");PrintWriter out = resp.getWriter();String message = "success";try {//把微信返回的xml信息转义成mapMap<String, String> map = XmlUtil.xmlToMap(req);String fromUserName = map.get("FromUserName");//消息来源用户标识 发送方帐号(一个OpenID)String toUserName = map.get("ToUserName");//消息目的用户标识String msgType = map.get("MsgType");//消息类型String content = map.get("Content");//消息内容String eventType = map.get("Event");String key=map.get("EventKey");MessageUtil messageUtil=new MessageUtil();if(MessageUtil.MSGTYPE_EVENT.equals(msgType)){//如果为事件类型if(MessageUtil.MESSAGE_SUBSCIBE.equals(eventType)){//处理订阅事件message = messageUtil.subscribeForText(toUserName, fromUserName,session);}else if(MessageUtil.MESSAGE_UNSUBSCIBE.equals(eventType)){//处理取消订阅事件message = messageUtil.unsubscribe(fromUserName);}else if(MessageUtil.MESSAGE_CLICK.equals(eventType)){//根据自定义菜单中的key来进行业务处理if(key.equals("32")){content="<a href=''>健康档案</a>";message = messageUtil.textMsg(toUserName, fromUserName,content);}}}else{//微信消息分为事件推送消息和普通消息,非事件即为普通消息类型switch (msgType) {case "text":{//文本消息if(content.equals("测试")){content ="这是开发测试";}else{content ="未能识别,详情访问:";}message = messageUtil.textMsg(toUserName, fromUserName,content);break;}default:{//其他类型的普通消息break;}}}} catch (DocumentException e) {e.printStackTrace();}finally{out.println(message);if(out!=null){out.close();}}}

下面是处理订阅事件即关注公众号时的方法:

/** 响应订阅事件--回复文本消息*/public String subscribeForText(String toUserName,String fromUserName,HttpSession session){//订阅成功后,根据openId获取用户信息 并注册。 fromUserName即为该用户的openid。//因为订阅号没有获取用户信息授权的权限,code获取不到。无法用code换取openid。因此获取openid后直接调用获取用户信息的方法// 获取基础刷新的接口访问凭证(目前还没明白为什么用authInfo.get("AccessToken");这里面的access_token就不行)String accessToken = WeiXinUtils.getAccessToken().getToken();try {messageUtil.userService.getUserInfo(accessToken,fromUserName,session);} catch (IOException e) {e.printStackTrace();}return textMsg(toUserName, fromUserName, "欢迎关注,精彩内容不容错过!!!,详情请访问网址:");}

在这里 因为springboot无法扫描到工具类中的userService 所以我们要在工具类中添加下面的代码来将其注册到bean中。

@Autowiredprivate UserService userService;public static MessageUtil messageUtil ;@PostConstructpublic void init() {messageUtil = this;messageUtil.userService=this.userService;//初使化时将已静态化的accessTokenOcrRepository实例化}

这样我们就可以在工具类中调用userService的方法。

@Overridepublic User getUserInfo(String accessToken, String openId,HttpSession session) throws IOException {User weixinUserInfo = null;// 拼接获取用户信息接口的请求地址String requestUrl = ProjectConst.GET_WEIXIN_USER_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);// 获取用户信息(返回的是Json格式内容)JSONObject jsonObject = WeiXinUtils.doGetStr(requestUrl);if (null != jsonObject) {try {//封装获取到的用户信息weixinUserInfo = new User();// 用户的标识weixinUserInfo.setOpenId(jsonObject.getString("openid"));// 昵称weixinUserInfo.setNickName(jsonObject.getString("nickname"));// 用户的性别(1是男性,2是女性,0是未知)weixinUserInfo.setSex(jsonObject.getInteger("sex"));weixinUserInfo.setLanguage(jsonObject.getString("zh_CN"));weixinUserInfo.setSubscribeTime(jsonObject.getString("subscribe_time"));// 用户所在国家weixinUserInfo.setCountry(jsonObject.getString("country"));// 用户所在省份weixinUserInfo.setProvince(jsonObject.getString("province"));// 用户所在城市weixinUserInfo.setCity(jsonObject.getString("city"));// 用户头像weixinUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));} catch (Exception e) {int errorCode = jsonObject.getInteger("errcode");String errorMsg = jsonObject.getString("errmsg");System.out.println("由于"+errorCode +"错误码;错误信息为:"+errorMsg+";导致获取用户信息失败");}}//获取用户信息后,可以存入数据库User user = userDao.save(weixinUserInfo);session.setAttribute(weixinUserInfo.getOpenId(),user);return user;}

除了响应关注事件,还可以对click等事件进行回复。

根据官方文档需要我们将回复的消息以xml的形式发送给微信后台。 下面我将用到的工具类贴在下面

XmlUtil类:

import com.hbrc.hbrcpublicserver.entity.wxmenu.TextMessage;import com.thoughtworks.xstream.XStream;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import javax.servlet.http.HttpServletRequest;import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.List;import java.util.Map;/*** @ClassName XmlUtil* @Description TODO* @Author Administrator* @Date /6/11 15:49* @Version 1.0**/public class XmlUtil {/** xml转map*/public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException {HashMap<String, String> map = new HashMap<String,String>();SAXReader reader = new SAXReader();InputStream ins = request.getInputStream();Document doc = reader.read(ins);Element root = doc.getRootElement();@SuppressWarnings("unchecked")List<Element> list = (List<Element>)root.elements();for(Element e:list){map.put(e.getName(), e.getText());}ins.close();return map;}/** 文本消息对象转xml*/public static String textMsgToxml(TextMessage textMessage){XStream xstream = new XStream();xstream.alias("xml", textMessage.getClass());return xstream.toXML(textMessage);}}

MessageUtil类:

import com.hbrc.hbrcpublicserver.entity.User;import com.hbrc.hbrcpublicserver.entity.wxmenu.TextMessage;import com.hbrc.hbrcpublicserver.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.ponent;import javax.annotation.PostConstruct;import javax.servlet.http.HttpSession;import java.io.IOException;import java.util.Date;/*** @ClassName MessageUtil* @Description TODO* @Author Administrator* @Date /6/11 16:13* @Version 1.0* @Description: 消息处理工具类**/@Componentpublic class MessageUtil {public static final String MSGTYPE_EVENT = "event";//消息类型--事件public static final String MESSAGE_SUBSCIBE = "subscribe";//消息事件类型--订阅事件public static final String MESSAGE_UNSUBSCIBE = "unsubscribe";//消息事件类型--取消订阅事件public static final String MESSAGE_TEXT = "text";//消息类型--文本消息public static final String MESSAGE_CLICK = "CLICK";//消息类型-点击事件@Autowiredprivate UserService userService;public static MessageUtil messageUtil ;@PostConstructpublic void init() {messageUtil = this;messageUtil.userService=this.userService;//初使化时将已静态化的accessTokenOcrRepository实例化}/** 组装文本消息*/public String textMsg(String toUserName,String fromUserName,String content){TextMessage text = new TextMessage();text.setFromUserName(toUserName);text.setToUserName(fromUserName);text.setMsgType(MESSAGE_TEXT);text.setCreateTime(new Date().getTime());text.setContent(content);return XmlUtil.textMsgToxml(text);}/** 响应订阅事件--回复文本消息*/public String subscribeForText(String toUserName,String fromUserName,HttpSession session){//订阅成功后,根据openId获取用户信息 并注册。 fromUserName即为该用户的openid。//因为订阅号没有获取用户信息授权的权限,code获取不到。无法用code换取openid。因此获取openid后直接调用获取用户信息的方法// 获取基础刷新的接口访问凭证(目前还没明白为什么用authInfo.get("AccessToken");这里面的access_token就不行)String accessToken = WeiXinUtils.getAccessToken().getToken();try {messageUtil.userService.getUserInfo(accessToken,fromUserName,session);} catch (IOException e) {e.printStackTrace();}return textMsg(toUserName, fromUserName, "欢迎关注,精彩内容不容错过!!!,详情请访问网址:");}/** 响应取消订阅事件*/public String unsubscribe(String fromUserName){//取关后 删除数据库中的用户信息,后期如有关联删除失败再做处理。如有关联如 oneToMany 级联属性设置为Cascade.ALL。messageUtil.userService.deleteByOpenid(fromUserName);System.out.println("用户:"+ fromUserName +"取消关注~");return "";}}

TextMessage类:

// 文本内容private String Content;// 消息id,64位整型private String MsgId;

BaseMessage类:

//开发者微信号private String ToUserName;//发送方帐号(一个OpenID)private String FromUserName;//消息创建时间 (整型)private long CreateTime;/*** 消息类型* text 文本消息* image 图片消息* voice 语音消息* video 视频消息* music 音乐消息* event 事件推送*/private String MsgType;private String Event;

这里只是文本消息,如果需要回复图文语音等消息可以自行封装。

到这里,订阅号获取用户信息的功能已经基本实现了。

另外多说一句,在接收微信发送给我们的xml包的方法里 我们定义了 String message = “success”;并在finally中返回给微信服务器。

理由参考官方文档入门指引。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。