微信小程序与公众号实现数据互通的方法
公司因小程序项目先上线,公众号后开发,接到上级的安排实现小程序打通任务,看文档后发现:同一开发者账号只要是在微信开放平台绑定小程序与公众号以后,会有一个唯一的unionid,这个unionid腾讯公司下产品共享。这个unionid就是我们进行打通的关键。
先说一下思路:
1.微信小程序与公众号进行绑定后,在小程序调用wx.login()方法后会自动获取unionid,公众号根据官方文档在获取用户基本信息后会拿到相同的unionid,openid,nickname。。。等相关信息;
2.将小程序拿到的unionid进行数据库的更新操作,公众号拿到的unionid等信息,新建数据库表A进行存储;(注:在这一步,因为我们公司的原因,我们的公众号之前就有人关注了,那么在这之前,我通过公众号获取关注用户列表获取openid的列表,进行循环openid列表,在调用公众号获取用户基本信息列表进行储存数据库表A,循环结束后之前关注的人的信息就储存在数据库A,然后在进行,这一步的操作)
3.通过公众号关注/取关的事件相应,来进行数据库表A的增删操作,维护数据的新鲜度;
4.进行关联查询,到这一步我们会发现,通过unionid进行表的关联后我们已经实现数据的互通了
洋洋洒洒的说了一大堆,其实就是公众号的两个接口至关重要(1.关注/取关的事件相应接口 2.获取用户的基本信息接口)
有关于公众号的安全域名配置,服务器域名配置以及获取token就不在这里说了,百度一下一大堆。
代码实现:
第一步,获取公众号用户的openid列表操作,根据opneid进进行用户的基本信息的查询,存入数据库操作(因为我们公司的公众号关注人数只有1000+,所以我只调用了一次获取关注列表的接口)
//主要代码逻辑 //获取token AccessTokenaccessToken=wxUtils.getAccessToken(); Stringurl="https://api.weixin.qq.com/cgi-bin/user/get?access_token="+accessToken.getAccessToken()+"&next_openid=";//获取所有用户openid JSONObjectjsonObject=httpRequest(url,"GET",null); try{ if(jsonObject.getString("errcode")!=null){ } }catch(Exceptione){ } WeixinUserListuserList=(WeixinUserList)JSONObject.toBean(jsonObject,WeixinUserList.class); if(null==userList){ return"无用户"; } userList.getTotal();//关注总人数 //用户openId列表 WxOpenidInfowxOpenidInfo=userList.getData(); ListopenIdList=null; if(null!=wxOpenidInfo){ openIdList=wxOpenidInfo.getOpenid();//公众号返回的openid列表数据 if(null!=openIdList&&openIdList.size()>0){ for(Stringopendid:openIdList){ //获取用户的基本信息(unionid机制) url="https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken.getAccessToken()+"&openid="+opendid+"&lang=zh_CN";//通过openid获取用户信息 jsonObject=httpRequest(url,"GET",null); WeixinUserwxUser=(WeixinUser)JSONObject.toBean(jsonObject,WeixinUser.class); //进行数据库表A的储存操作 introw=gzhService.addGZHUser(wxUser); } } } /** *用户列表 *@author一叶知秋plus * */ publicclassWeixinUserList{ privateIntegertotal;//关注该公众账号的总用户数 privateIntegercount;//拉取的OPENID个数,最大值为10000 privateWxOpenidInfodata;//列表数据,OPENID的列表 privateStringnext_openid;//拉取列表的最后一个用户的OPENID privateinterrcode;//错误编码 privateStringerrmsg="ok";//错误提示 publicIntegergetTotal(){ returntotal; } publicvoidsetTotal(Integertotal){ this.total=total; } publicIntegergetCount(){ returncount; } publicvoidsetCount(Integercount){ this.count=count; } publicStringgetNext_openid(){ returnnext_openid; } publicvoidsetNext_openid(Stringnext_openid){ this.next_openid=next_openid; } publicWxOpenidInfogetData(){ returndata; } publicvoidsetData(WxOpenidInfodata){ this.data=data; } publicintgetErrcode(){ returnerrcode; } publicvoidsetErrcode(interrcode){ this.errcode=errcode; } publicStringgetErrmsg(){ returnerrmsg; } publicvoidsetErrmsg(Stringerrmsg){ this.errmsg=errmsg; } } /** *用户基本信息 *@author一叶知秋plus * */ publicclassWeixinUser{ privateStringsubscribe;//用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 privateStringopenid;//用户的标识,对当前公众号唯一 privateStringnickname;//用户的昵称 privateStringsex;//用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 privateStringcity;//用户所在城市 privateStringcountry;//用户所在国家 privateStringprovince;//用户所在省份 privateStringlanguage;//用户的语言,简体中文为zh_CN privateList tagid_list;//用户被打上的标签ID列表 privateStringunionid;//用户的unionid privateStringheadimgurl;//用户的头像 publicStringgetHeadimgurl(){ returnheadimgurl; } publicvoidsetHeadimgurl(Stringheadimgurl){ this.headimgurl=headimgurl; } publicStringgetUnionid(){ returnunionid; } publicvoidsetUnionid(Stringunionid){ this.unionid=unionid; } publicStringgetSubscribe(){ returnsubscribe; } publicvoidsetSubscribe(Stringsubscribe){ this.subscribe=subscribe; } publicStringgetOpenid(){ returnopenid; } publicvoidsetOpenid(Stringopenid){ this.openid=openid; } publicStringgetNickname(){ returnnickname; } publicvoidsetNickname(Stringnickname){ this.nickname=nickname; } publicStringgetSex(){ returnsex; } publicvoidsetSex(Stringsex){ this.sex=sex; } publicStringgetCity(){ returncity; } publicvoidsetCity(Stringcity){ this.city=city; } publicStringgetCountry(){ returncountry; } publicvoidsetCountry(Stringcountry){ this.country=country; } publicStringgetProvince(){ returnprovince; } publicvoidsetProvince(Stringprovince){ this.province=province; } publicStringgetLanguage(){ returnlanguage; } publicvoidsetLanguage(Stringlanguage){ this.language=language; } publicList getTagid_list(){ returntagid_list; } publicvoidsetTagid_list(List tagid_list){ this.tagid_list=tagid_list; } } publicclassWxOpenidInfo{ privateList openid; publicList getOpenid(){ returnopenid; } publicvoidsetOpenid(List openid){ this.openid=openid; } }
步骤二:关注/取关的事件响应接口
/** *请求校验工具类 */ publicclassSignUtil{ //与接口配置信息中的Token要一致,我的是明文格式 privatestaticStringtoken="填写你服务器配置时写的token"; publicstaticbooleancheckSignature(Stringsignature,Stringtimestamp, Stringnonce){ //从请求中(也就是微信服务器传过来的)拿到的token,timestamp,nonce String[]arr=newString[]{token,timestamp,nonce}; //将token、timestamp、nonce三个参数进行字典序排序 sort(arr); StringBuildercontent=newStringBuilder(); for(inti=0;i>>4)&0X0F]; tempArr[1]=Digit[mByte&0X0F]; Strings=newString(tempArr); returns; } //用于字典排序 publicstaticvoidsort(Stringa[]){ for(inti=0;i map=XmlUtil.xmlToMap(request); StringfromUserName=map.get("FromUserName");//消息来源用户标识 StringtoUserName=map.get("ToUserName");//消息目的用户标识 StringmsgType=map.get("MsgType");//消息类型 Stringcontent=map.get("Content");//消息内容 StringeventType=map.get("Event"); WeixinUserweixinUser=newWeixinUser(); if(MessageUtil.MSGTYPE_EVENT.equals(msgType)){//如果为事件类型 if(MessageUtil.MESSAGE_SUBSCIBE.equals(eventType)){//处理订阅事件 //获取token Stringtoken=WXUtil.getGZHToken(); weixinUser=WXUtil.getUnionid(fromUserName,token); //进行数据库的操作 weixinUser.setNickname(weixinUser.getNickname()); introw=gzhService.addGZHUser(weixinUser); //通过openid获取用户的数据 message=MessageUtil.subscribeForText(toUserName,fromUserName); }elseif(MessageUtil.MESSAGE_UNSUBSCIBE.equals(eventType)){//处理取消订阅事件 message=MessageUtil.unsubscribe(toUserName,fromUserName); weixinUser.setOpenid(fromUserName); //进行数据库的操作 introw=gzhService.deleteGZHUser(weixinUser); } } }catch(DocumentExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); }finally{ out.close(); } out=null; } /* *消息处理工具类 */ publicclassMessageUtil{ publicstaticfinalStringMSGTYPE_EVENT="event";//消息类型--事件 publicstaticfinalStringMESSAGE_SUBSCIBE="subscribe";//消息事件类型--订阅事件 publicstaticfinalStringMESSAGE_UNSUBSCIBE="unsubscribe";//消息事件类型--取消订阅事件 publicstaticfinalStringMESSAGE_TEXT="text";//消息类型--文本消息 /* *组装文本消息 */ publicstaticStringtextMsg(StringtoUserName,StringfromUserName,Stringcontent){ TextMessagetext=newTextMessage(); text.setFromUserName(toUserName); text.setToUserName(fromUserName); text.setMsgType(MESSAGE_TEXT); text.setCreateTime(newDate().getTime()); text.setContent(content); returnXmlUtil.textMsgToxml(text); } /* *响应订阅事件--回复文本消息 */ publicstaticStringsubscribeForText(StringtoUserName,StringfromUserName){ returntextMsg(toUserName,fromUserName,"欢迎关注,精彩内容不容错过!!!"); } /* *响应取消订阅事件 */ publicstaticStringunsubscribe(StringtoUserName,StringfromUserName){ //TODO可以进行取关后的其他后续业务处理 System.out.println("用户:"+fromUserName+"取消关注~"); return""; } } /* *xml处理工具类 */ publicclassXmlUtil{ /* *xml转map */ publicstaticMap xmlToMap(HttpServletRequestrequest)throwsIOException,DocumentException{ HashMap map=newHashMap (); SAXReaderreader=newSAXReader(); InputStreamins=request.getInputStream(); Documentdoc=reader.read(ins); Elementroot=doc.getRootElement(); @SuppressWarnings("unchecked") List list=(List )root.elements(); for(Elemente:list){ map.put(e.getName(),e.getText()); } ins.close(); returnmap; } /* *文本消息对象转xml */ publicstaticStringtextMsgToxml(TextMessagetextMessage){ XStreamxstream=newXStream(); xstream.alias("xml",textMessage.getClass()); returnxstream.toXML(textMessage); } }
ok,到这一步数据库中有了小程序opneidunionid公众号opneid unionid等用户信息,进行关联后就可以进行数据的查询操作,当然小程序也可以发送公众号模板的相应操作了。如果有更好的实现方式,欢迎各位大佬不吝赐教~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。