在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。
请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。
UnionID机制说明:
开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。
获取用户基本信息(包括UnionID机制)
开发者可通过OpenID来获取用户基本信息。请使用https协议。
接口调用请求说明
http请求方式: GET https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
参数说明
参数
是否必须
说明
access_token
是
调用接口凭证
openid
是
普通用户的标识,对当前公众号唯一
lang
否
返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
或者是批量获取用户基本信息
批量获取用户基本信息
开发者可通过该接口来批量获取用户基本信息。最多支持一次拉取100条。
接口调用请求说明
http请求方式: POST
https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN
POST数据示例
{
"user_list": [
{
"openid": "otvxTs4dckWG7imySrJd6jSi0CWE",
"lang": "zh_CN"
},
{
"openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg",
"lang": "zh_CN"
}
]
}
参数说明
参数
是否必须
说明
openid
是
用户的标识,对当前公众号唯一
lang
否
国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN
通过这2个接口,可以发现要获取用户信息必要要获取用户关注公众号的 openid,那么首先要获取对应的openid,涉及到另外一个接口:
获取用户列表
公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。
接口调用请求说明
http请求方式: GET(请使用https协议)
https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
参数
是否必须
说明
access_token
是
调用接口凭证
next_openid
是
第一个拉取的OPENID,不填默认从头开始拉取
返回说明
正确时返回JSON数据包:
{"total":2,"count":2,"data":{"openid":["","OPENID1","OPENID2"]},"next_openid":"NEXT_OPENID"}
参数
说明
total
关注该公众账号的总用户数
count
拉取的OPENID个数,最大值为10000
data
列表数据,OPENID的列表
next_openid
拉取列表的最后一个用户的OPENID
这样可以获取到公众号的关注着列表. 获取到openid后即可获取用户的明细信息。
功能实现
分析完接口参数及调用方式,下面就来进行实现吧~
可以定义一个用户信息类,这样后续处理用户信息或存储到数据库均较方便,主要属性可按接口返回字段进行定义:
1 /**
2 * 微信用户信息类3 *@authorDamon4 */
5 public classUserInfo6 {7
8 //用户的标识
9 privateString openId;10
11 //关注状态(1是关注,0是未关注),未关注时获取不到其余信息
12 private intsubscribe;13
14 //用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
15 private intsubscribetime;16
17 //昵称
18 privateString nickname;19
20 //用户的性别(1是男性,2是女性,0是未知)
21 private intsex;22
23 //用户所在国家
24 privateString country;25
26 //用户所在省份
27 privateString province;28
29 //用户所在城市
30 privateString city;31
32 //用户的语言,简体中文为zh_CN
33 privateString language;34
35 //用户头像
36 privateString headimgurl;37
38 privateString remark;39
40 private intgroupid;41
42 publicString getOpenId()43 {44 returnopenId;45 }46
47 public voidsetOpenId(String openId)48 {49 this.openId =openId;50 }51
52 public intgetSubscribe()53 {54 returnsubscribe;55 }56
57 public void setSubscribe(intsubscribe)58 {59 this.subscribe =subscribe;60 }61
62
63 public intgetSubscribetime()64 {65 returnsubscribetime;66 }67
68 public void setSubscribetime(intsubscribetime)69 {70 this.subscribetime =subscribetime;71 }72
73 publicString getNickname()74 {75 returnnickname;76 }77
78 public voidsetNickname(String nickname)79 {80 this.nickname =nickname;81 }82
83 public intgetSex()84 {85 returnsex;86 }87
88 public void setSex(intsex)89 {90 this.sex =sex;91 }92
93 publicString getCountry()94 {95 returncountry;96 }97
98 public voidsetCountry(String country)99 {100 this.country =country;101 }102
103 publicString getProvince()104 {105 returnprovince;106 }107
108 public voidsetProvince(String province)109 {110 this.province =province;111 }112
113 publicString getCity()114 {115 returncity;116 }117
118 public voidsetCity(String city)119 {120 this.city =city;121 }122
123 publicString getLanguage()124 {125 returnlanguage;126 }127
128 public voidsetLanguage(String language)129 {130 this.language =language;131 }132
133 publicString getHeadimgurl()134 {135 returnheadimgurl;136 }137
138 public voidsetHeadimgurl(String headimgurl)139 {140 this.headimgurl =headimgurl;141 }142
143 publicString getRemark()144 {145 returnremark;146 }147
148 public voidsetRemark(String remark)149 {150 this.remark =remark;151 }152
153 public intgetGroupid()154 {155 returngroupid;156 }157
158 public void setGroupid(intgroupid)159 {160 this.groupid =groupid;161 }162
163
164 }
View Code
然后就是具体的实现方法了,其实很简单,就是先后调用2次接口就行了:
首先的要调用获取用户openid的列表:
1 /**
2 * 获取公众号关注的用户openid3 *@return
4 */
5 public ListgetUserOpenId(String access_token, String nextOpenid)6 {7 String path = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";8 path = path.replace("ACCESS_TOKEN", access_token).replace("NEXT_OPENID", nextOpenid);9 System.out.println("path:" +path);10
11 List result = null;12 try
13 {14 String strResp = WeChatUtil.doHttpsGet(path, "");15 System.out.println(strResp);16
17 Map map =WeChatUtil.jsonToMap(strResp);18 Map tmapMap = (Map) map.get("data");19
20 result = (List) tmapMap.get("openid");21
22 System.out.println(result.toString());23
24 }25 catch(HttpException e)26 {27 //TODO Auto-generated catch block
28 e.printStackTrace();29 }30 catch(IOException e)31 {32 //TODO Auto-generated catch block
33 e.printStackTrace();34 }35
36 returnresult;37 }
View Code
获取到openi的信息后,也可以先存储起来(具体看项目需要了),或再等详细信息后才存储,
对应的调用方法如下:
1 /**
2 * 通过用户openid 获取用户信息3 *@paramuserOpenids4 *@return
5 */
6 public List getUserInfo(ListuserOpenids)7 {8 //1、获取access_token9 //使用测试 wx9015ccbcccf8d2f5 02e3a6877fa5fdeadd78d0f6f3048245
10 WeChatTokenService tWeChatTokenService = newWeChatTokenService();11 String tAccess_Token = tWeChatTokenService.getToken("wx9015ccbcccf8d2f5", "02e3a6877fa5fdeadd78d0f6f3048245").getToken();12
13 //2、封装请求数据
14 List user_list = new ArrayList();15 for (int i = 0; i < userOpenids.size(); i++)16 {17 String openid =userOpenids.get(i);18 Map tUserMap = new HashMap();19 tUserMap.put("openid", openid);20 tUserMap.put("lang", "zh_CN");21 user_list.add(tUserMap);22 }23 System.out.println(user_list.toString());24 Map requestMap = new HashMap();25 requestMap.put("user_list", user_list);26 String tUserJSON =JSONObject.fromObject(requestMap).toString();27
28 //3、请求调用
29 String result =getUserInfobyHttps(tAccess_Token, tUserJSON);30 System.out.println(result);31
32 //4、解析返回将结果
33 returnparseUserInfo(result);34 }
View Code
其中详细方法实现如下:
1 /**
2 * 解析返回用户信息数据3 *@paramuserInfoJSON4 *@return
5 */
6 private ListparseUserInfo(String userInfoJSON)7 {8 List user_info_list = new ArrayList();9
10 Map tMapData =WeChatUtil.jsonToMap(userInfoJSON);11
12 List tUserMaps = (List) tMapData.get("user_info_list");13
14 for (int i = 0; i < tUserMaps.size(); i++)15 {16 UserInfo tUserInfo = newUserInfo();17 tUserInfo.setSubscribe((Integer) tUserMaps.get(i).get("subscribe"));18 tUserInfo.setSex((Integer) tUserMaps.get(i).get("sex"));19 tUserInfo.setOpenId((String) tUserMaps.get(i).get("openid"));20 tUserInfo.setNickname((String) tUserMaps.get(i).get("nickname"));21 tUserInfo.setLanguage((String) tUserMaps.get(i).get("language"));22 tUserInfo.setCity((String) tUserMaps.get(i).get("city"));23 tUserInfo.setProvince((String) tUserMaps.get(i).get("province"));24 tUserInfo.setCountry((String) tUserMaps.get(i).get("country"));25 tUserInfo.setHeadimgurl((String) tUserMaps.get(i).get("headimgurl"));26 tUserInfo.setSubscribetime((Integer) tUserMaps.get(i).get("subscribe_time"));27 tUserInfo.setRemark((String) tUserMaps.get(i).get("remark"));28 tUserInfo.setGroupid((Integer) tUserMaps.get(i).get("groupid"));29 user_info_list.add(tUserInfo);30 }31
32 returnuser_info_list;33 }34
35 /**
36 * 调用HTTPS接口,获取用户详细信息37 *@paramaccess_token38 *@paramrequestData39 *@return
40 */
41 privateString getUserInfobyHttps(String access_token, String requestData)42 {43 //返回报文
44 String strResp = "";45 String path = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN";46 path = path.replace("ACCESS_TOKEN", access_token);47
48 try
49 {50 strResp =WeChatUtil.doHttpsPost(path, requestData);51 }52 catch(HttpException e)53 {54 //发生致命的异常,可能是协议不对或者返回的内容有问题
55 System.out.println("Please check your provided http address!" +e);56 e.printStackTrace();57 }58 catch(IOException e)59 {60 //发生网络异常
61 }62 catch(Exception e)63 {64 System.out.println(e);65 }66 finally
67 {}68 returnstrResp;69 }
View Code
测试方法如下:
1 public static voidmain(String[] args)2 {3 WeChatUserService tChatUserService = newWeChatUserService();4 tChatUserService.getUserInfo(tChatUserService.getUserOpenId(new WeChatTokenService().getToken("appid", "appSceret").getToken(), ""));5 }
View Code
最终获取数据结果:
可用把最终过去的用户信息存到数据库,后面的就由大家去发挥啦!