微信小程序与公众号实现数据互通的方法
公司因小程序项目先上线,公众号后开发,接到上级的安排实现小程序打通任务,看文档后发现:同一开发者账号只要是在微信开放平台绑定小程序与公众号以后,会有一个唯一的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
privateListtagid_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;
}
publicListgetTagid_list(){
returntagid_list;
}
publicvoidsetTagid_list(Listtagid_list){
this.tagid_list=tagid_list;
}
}
publicclassWxOpenidInfo{
privateListopenid;
publicListgetOpenid(){
returnopenid;
}
publicvoidsetOpenid(Listopenid){
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;imap=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
*/
publicstaticMapxmlToMap(HttpServletRequestrequest)throwsIOException,DocumentException{
HashMapmap=newHashMap();
SAXReaderreader=newSAXReader();
InputStreamins=request.getInputStream();
Documentdoc=reader.read(ins);
Elementroot=doc.getRootElement();
@SuppressWarnings("unchecked")
Listlist=(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等用户信息,进行关联后就可以进行数据的查询操作,当然小程序也可以发送公众号模板的相应操作了。如果有更好的实现方式,欢迎各位大佬不吝赐教~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。