在關注者與公眾號產生消息交互后,公眾號可獲得關注者的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 * @author Damon 4 */ 5 public class UserInfo 6 { 7 8 // 用戶的標識 9 private String openId; 10 11 // 關注狀態(1是關注,0是未關注),未關注時獲取不到其余信息 12 private int subscribe; 13 14 // 用戶關注時間,為時間戳。如果用戶曾多次關注,則取最后關注時間 15 private int subscribetime; 16 17 // 昵稱 18 private String nickname; 19 20 // 用戶的性別(1是男性,2是女性,0是未知) 21 private int sex; 22 23 // 用戶所在國家 24 private String country; 25 26 // 用戶所在省份 27 private String province; 28 29 // 用戶所在城市 30 private String city; 31 32 // 用戶的語言,簡體中文為zh_CN 33 private String language; 34 35 // 用戶頭像 36 private String headimgurl; 37 38 private String remark; 39 40 private int groupid; 41 42 public String getOpenId() 43 { 44 return openId; 45 } 46 47 public void setOpenId(String openId) 48 { 49 this.openId = openId; 50 } 51 52 public int getSubscribe() 53 { 54 return subscribe; 55 } 56 57 public void setSubscribe(int subscribe) 58 { 59 this.subscribe = subscribe; 60 } 61 62 63 public int getSubscribetime() 64 { 65 return subscribetime; 66 } 67 68 public void setSubscribetime(int subscribetime) 69 { 70 this.subscribetime = subscribetime; 71 } 72 73 public String getNickname() 74 { 75 return nickname; 76 } 77 78 public void setNickname(String nickname) 79 { 80 this.nickname = nickname; 81 } 82 83 public int getSex() 84 { 85 return sex; 86 } 87 88 public void setSex(int sex) 89 { 90 this.sex = sex; 91 } 92 93 public String getCountry() 94 { 95 return country; 96 } 97 98 public void setCountry(String country) 99 { 100 this.country = country; 101 } 102 103 public String getProvince() 104 { 105 return province; 106 } 107 108 public void setProvince(String province) 109 { 110 this.province = province; 111 } 112 113 public String getCity() 114 { 115 return city; 116 } 117 118 public void setCity(String city) 119 { 120 this.city = city; 121 } 122 123 public String getLanguage() 124 { 125 return language; 126 } 127 128 public void setLanguage(String language) 129 { 130 this.language = language; 131 } 132 133 public String getHeadimgurl() 134 { 135 return headimgurl; 136 } 137 138 public void setHeadimgurl(String headimgurl) 139 { 140 this.headimgurl = headimgurl; 141 } 142 143 public String getRemark() 144 { 145 return remark; 146 } 147 148 public void setRemark(String remark) 149 { 150 this.remark = remark; 151 } 152 153 public int getGroupid() 154 { 155 return groupid; 156 } 157 158 public void setGroupid(int groupid) 159 { 160 this.groupid = groupid; 161 } 162 163 164 }

然后就是具體的實現方法了,其實很簡單,就是先后調用2次接口就行了:

首先的要調用獲取用戶openid的列表:

1 /** 2 * 獲取公眾號關注的用戶openid 3 * @return 4 */ 5 public List<String> getUserOpenId(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<String> 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<String>) 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 return result; 37 }
獲取到openi的信息后,也可以先存儲起來(具體看項目需要了),或再等詳細信息后才存儲,
對應的調用方法如下:

1 /** 2 * 通過用戶openid 獲取用戶信息 3 * @param userOpenids 4 * @return 5 */ 6 public List<UserInfo> getUserInfo(List<String> userOpenids) 7 { 8 // 1、獲取access_token 9 // 使用測試 wx9015ccbcccf8d2f5 02e3a6877fa5fdeadd78d0f6f3048245 10 WeChatTokenService tWeChatTokenService = new WeChatTokenService(); 11 String tAccess_Token = tWeChatTokenService.getToken("wx9015ccbcccf8d2f5", "02e3a6877fa5fdeadd78d0f6f3048245").getToken(); 12 13 // 2、封裝請求數據 14 List user_list = new ArrayList<Map>(); 15 for (int i = 0; i < userOpenids.size(); i++) 16 { 17 String openid = userOpenids.get(i); 18 Map tUserMap = new HashMap<String, String>(); 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<String, List>(); 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 return parseUserInfo(result); 34 }
其中詳細方法實現如下:

1 /** 2 * 解析返回用戶信息數據 3 * @param userInfoJSON 4 * @return 5 */ 6 private List<UserInfo> parseUserInfo(String userInfoJSON) 7 { 8 List user_info_list = new ArrayList<UserInfo>(); 9 10 Map tMapData = WeChatUtil.jsonToMap(userInfoJSON); 11 12 List<Map> tUserMaps = (List<Map>) tMapData.get("user_info_list"); 13 14 for (int i = 0; i < tUserMaps.size(); i++) 15 { 16 UserInfo tUserInfo = new UserInfo(); 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 return user_info_list; 33 } 34 35 /** 36 * 調用HTTPS接口,獲取用戶詳細信息 37 * @param access_token 38 * @param requestData 39 * @return 40 */ 41 private String 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 return strResp; 69 }
測試方法如下:

1 public static void main(String[] args) 2 { 3 WeChatUserService tChatUserService = new WeChatUserService(); 4 tChatUserService.getUserInfo(tChatUserService.getUserOpenId(new WeChatTokenService().getToken("appid", "appSceret").getToken(), "")); 5 }
最終獲取數據結果:

可用把最終過去的用戶信息存到數據庫,后面的就由大家去發揮啦!