在關(guān)注者與公眾號產(chǎn)生消息交互后,公眾號可獲得關(guān)注者的OpenID(加密后的微信號,每個用戶對每個公眾號的OpenID是唯一的。對于不同公眾號,同一用戶的openid不同)。
公眾號可通過本接口來根據(jù)OpenID獲取用戶基本信息,包括昵稱、頭像、性別、所在城市、語言和關(guān)注時間。
開發(fā)者可通過OpenID來獲取用戶基本信息。請使用https協(xié)議。
我們可以看看官方的文檔:獲取用戶的基本信息。
接口調(diào)用請求說明
http請求方式: GET
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
參數(shù)說明
參數(shù) | 是否必須 | 說明 |
---|---|---|
access_token | 是 | 調(diào)用接口憑證 |
openid | 是 | 普通用戶的標識,對當前公眾號唯一 |
lang | 否 | 返回國家地區(qū)語言版本,zh_CN 簡體,zh_TW 繁體,en 英語 |
返回說明
正常情況下,微信會返回下述JSON數(shù)據(jù)包給公眾號:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
{ "subscribe" : 1 , "openid" : "o6_bmjrPTlm6_2sgVt7hMZOPfL2M" , "nickname" : "Band" , "sex" : 1 , "language" : "zh_CN" , "city" : "廣州" , "province" : "廣東" , "country" : "中國" , "headimgurl" : "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0" , "subscribe_time" : 1382694957 , "unionid" : " o6_bmasdasdsad6_2sgVt7hMZOPfL" "remark" : "" , "groupid" : 0 } |
參數(shù)說明
參數(shù) | 說明 |
---|---|
subscribe | 用戶是否訂閱該公眾號標識,值為0時,代表此用戶沒有關(guān)注該公眾號,拉取不到其余信息。 |
openid | 用戶的標識,對當前公眾號唯一 |
nickname | 用戶的昵稱 |
sex | 用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知 |
city | 用戶所在城市 |
country | 用戶所在國家 |
province | 用戶所在省份 |
language | 用戶的語言,簡體中文為zh_CN |
headimgurl | 用戶頭像,最后一個數(shù)值代表正方形頭像大小(有0、46、64、96、132數(shù)值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空。若用戶更換頭像,原有頭像URL將失效。 |
subscribe_time | 用戶關(guān)注時間,為時間戳。如果用戶曾多次關(guān)注,則取最后關(guān)注時間 |
unionid | 只有在用戶將公眾號綁定到微信開放平臺帳號后,才會出現(xiàn)該字段。詳見:獲取用戶個人信息(UnionID機制) |
remark | 公眾號運營者對粉絲的備注,公眾號運營者可在微信公眾平臺用戶管理界面對粉絲添加備注 |
groupid | 用戶所在的分組ID |
錯誤時微信會返回錯誤碼等信息,JSON數(shù)據(jù)包示例如下(該示例為AppID無效錯誤):
1
|
{ "errcode" : 40013 , "errmsg" : "invalid appid" } |
根據(jù)上面的信息,我們定義一個用戶信息類來存放用戶的基本信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
package com.souvc.weixin.pojo; /** * 類名: WeixinUserInfo </br> * 描述: 微信用戶的基本信息 </br> * 開發(fā)人員: souvc </br> * 創(chuàng)建時間: 2015-11-27 </br> * 發(fā)布版本:V1.0 </br> */ public class WeixinUserInfo { // 用戶的標識 private String openId; // 關(guān)注狀態(tài)(1是關(guān)注,0是未關(guān)注),未關(guān)注時獲取不到其余信息 private int subscribe; // 用戶關(guān)注時間,為時間戳。如果用戶曾多次關(guān)注,則取最后關(guān)注時間 private String subscribeTime; // 昵稱 private String nickname; // 用戶的性別(1是男性,2是女性,0是未知) private int sex; // 用戶所在國家 private String country; // 用戶所在省份 private String province; // 用戶所在城市 private String city; // 用戶的語言,簡體中文為zh_CN private String language; // 用戶頭像 private String headImgUrl; public String getOpenId() { return openId; } public void setOpenId(String openId) { this .openId = openId; } public int getSubscribe() { return subscribe; } public void setSubscribe( int subscribe) { this .subscribe = subscribe; } public String getSubscribeTime() { return subscribeTime; } public void setSubscribeTime(String subscribeTime) { this .subscribeTime = subscribeTime; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this .nickname = nickname; } public int getSex() { return sex; } public void setSex( int sex) { this .sex = sex; } public String getCountry() { return country; } public void setCountry(String country) { this .country = country; } public String getProvince() { return province; } public void setProvince(String province) { this .province = province; } public String getCity() { return city; } public void setCity(String city) { this .city = city; } public String getLanguage() { return language; } public void setLanguage(String language) { this .language = language; } public String getHeadImgUrl() { return headImgUrl; } public void setHeadImgUrl(String headImgUrl) { this .headImgUrl = headImgUrl; } } |
我們先來看看獲取用戶信息的接口:
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
根據(jù)分析,獲取用戶的基本信息需要一個token。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package com.souvc.weixin.pojo; /** * 類名: Token </br> * 描述: 憑證 </br> * 開發(fā)人員: souvc </br> * 創(chuàng)建時間: 2015-11-27 </br> * 發(fā)布版本:V1.0 </br> */ public class Token { // 接口訪問憑證 private String accessToken; // 憑證有效期,單位:秒 private int expiresIn; public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this .accessToken = accessToken; } public int getExpiresIn() { return expiresIn; } public void setExpiresIn( int expiresIn) { this .expiresIn = expiresIn; } } |
https請求,需要的信任管理器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.souvc.weixin.util; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; /** * 類名: MyX509TrustManager </br> * 描述:信任管理器 </br> * 開發(fā)人員: souvc </br> * 創(chuàng)建時間: 2015-11-27 </br> * 發(fā)布版本:V1.0 </br> */ public class MyX509TrustManager implements X509TrustManager { // 檢查客戶端證書 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } // 檢查服務(wù)器端證書 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } // 返回受信任的X509證書數(shù)組 public X509Certificate[] getAcceptedIssuers() { return null ; } } |
封裝了一個公共類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
package com.souvc.weixin.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.ConnectException; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import net.sf.json.JSONException; import net.sf.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.souvc.weixin.pojo.Token; /** * 類名: CommonUtil </br> * 描述: 通用工具類 </br> * 開發(fā)人員: souvc </br> * 創(chuàng)建時間: 2015-11-27 </br> * 發(fā)布版本:V1.0 </br> */ public class CommonUtil { private static Logger log = LoggerFactory.getLogger(CommonUtil. class ); // 憑證獲取(GET) public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET" ; /** * 發(fā)送https請求 * * @param requestUrl 請求地址 * @param requestMethod 請求方式(GET、POST) * @param outputStr 提交的數(shù)據(jù) * @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值) */ public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null ; try { // 創(chuàng)建SSLContext對象,并使用我們指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance( "SSL" , "SunJSSE" ); sslContext.init( null , tm, new java.security.SecureRandom()); // 從上述SSLContext對象中得到SSLSocketFactory對象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); conn.setDoOutput( true ); conn.setDoInput( true ); conn.setUseCaches( false ); // 設(shè)置請求方式(GET/POST) conn.setRequestMethod(requestMethod); // 當outputStr不為null時向輸出流寫數(shù)據(jù) if ( null != outputStr) { OutputStream outputStream = conn.getOutputStream(); // 注意編碼格式 outputStream.write(outputStr.getBytes( "UTF-8" )); outputStream.close(); } // 從輸入流讀取返回內(nèi)容 InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8" ); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null ; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null ) { buffer.append(str); } // 釋放資源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null ; conn.disconnect(); jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { log.error( "連接超時:{}" , ce); } catch (Exception e) { log.error( "https請求異常:{}" , e); } return jsonObject; } /** * 獲取接口訪問憑證 * * @param appid 憑證 * @param appsecret 密鑰 * @return */ public static Token getToken(String appid, String appsecret) { Token token = null ; String requestUrl = token_url.replace( "APPID" , appid).replace( "APPSECRET" , appsecret); // 發(fā)起GET請求獲取憑證 JSONObject jsonObject = httpsRequest(requestUrl, "GET" , null ); if ( null != jsonObject) { try { token = new Token(); token.setAccessToken(jsonObject.getString( "access_token" )); token.setExpiresIn(jsonObject.getInt( "expires_in" )); } catch (JSONException e) { token = null ; // 獲取token失敗 log.error( "獲取token失敗 errcode:{} errmsg:{}" , jsonObject.getInt( "errcode" ), jsonObject.getString( "errmsg" )); } } return token; } /** * URL編碼(utf-8) * * @param source * @return */ public static String urlEncodeUTF8(String source) { String result = source; try { result = java.net.URLEncoder.encode(source, "utf-8" ); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } /** * 根據(jù)內(nèi)容類型判斷文件擴展名 * * @param contentType 內(nèi)容類型 * @return */ public static String getFileExt(String contentType) { String fileExt = "" ; if ( "image/jpeg" .equals(contentType)) fileExt = ".jpg" ; else if ( "audio/mpeg" .equals(contentType)) fileExt = ".mp3" ; else if ( "audio/amr" .equals(contentType)) fileExt = ".amr" ; else if ( "video/mp4" .equals(contentType)) fileExt = ".mp4" ; else if ( "video/mpeg4" .equals(contentType)) fileExt = ".mp4" ; return fileExt; } } |
獲取用戶基本信息的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
/** * 獲取用戶信息 * * @param accessToken 接口訪問憑證 * @param openId 用戶標識 * @return WeixinUserInfo */ public static WeixinUserInfo getUserInfo(String accessToken, String openId) { WeixinUserInfo weixinUserInfo = null ; // 拼接請求地址 String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID" ; requestUrl = requestUrl.replace( "ACCESS_TOKEN" , accessToken).replace( "OPENID" , openId); // 獲取用戶信息 JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET" , null ); if ( null != jsonObject) { try { weixinUserInfo = new WeixinUserInfo(); // 用戶的標識 weixinUserInfo.setOpenId(jsonObject.getString( "openid" )); // 關(guān)注狀態(tài)(1是關(guān)注,0是未關(guān)注),未關(guān)注時獲取不到其余信息 weixinUserInfo.setSubscribe(jsonObject.getInt( "subscribe" )); // 用戶關(guān)注時間 weixinUserInfo.setSubscribeTime(jsonObject.getString( "subscribe_time" )); // 昵稱 weixinUserInfo.setNickname(jsonObject.getString( "nickname" )); // 用戶的性別(1是男性,2是女性,0是未知) weixinUserInfo.setSex(jsonObject.getInt( "sex" )); // 用戶所在國家 weixinUserInfo.setCountry(jsonObject.getString( "country" )); // 用戶所在省份 weixinUserInfo.setProvince(jsonObject.getString( "province" )); // 用戶所在城市 weixinUserInfo.setCity(jsonObject.getString( "city" )); // 用戶的語言,簡體中文為zh_CN weixinUserInfo.setLanguage(jsonObject.getString( "language" )); // 用戶頭像 weixinUserInfo.setHeadImgUrl(jsonObject.getString( "headimgurl" )); } catch (Exception e) { if ( 0 == weixinUserInfo.getSubscribe()) { log.error( "用戶{}已取消關(guān)注" , weixinUserInfo.getOpenId()); } else { int errorCode = jsonObject.getInt( "errcode" ); String errorMsg = jsonObject.getString( "errmsg" ); log.error( "獲取用戶信息失敗 errcode:{} errmsg:{}" , errorCode, errorMsg); } } } return weixinUserInfo; } |
測試的方法:注意將以下替換為自己的appid和秘鑰。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public static void main(String args[]) { // 獲取接口訪問憑證 String accessToken = CommonUtil.getToken( "xxxx" , "xxxx" ).getAccessToken(); /** * 獲取用戶信息 */ WeixinUserInfo user = getUserInfo(accessToken, "ooK-yuJvd9gEegH6nRIen-gnLrVw" ); System.out.println( "OpenID:" + user.getOpenId()); System.out.println( "關(guān)注狀態(tài):" + user.getSubscribe()); System.out.println( "關(guān)注時間:" + user.getSubscribeTime()); System.out.println( "昵稱:" + user.getNickname()); System.out.println( "性別:" + user.getSex()); System.out.println( "國家:" + user.getCountry()); System.out.println( "省份:" + user.getProvince()); System.out.println( "城市:" + user.getCity()); System.out.println( "語言:" + user.getLanguage()); System.out.println( "頭像:" + user.getHeadImgUrl()); } |
效果如下:
OpenID:ooK-yuJvd9gEegH6nRIen-gnLrVw
關(guān)注狀態(tài):1
關(guān)注時間:1449021142
昵稱:風(fēng)少
性別:1
國家:中國
省份:廣東
城市:廣州
語言:zh_CN
頭像:http://wx.qlogo.cn/mmopen/lOZIEvyfCa7aZQ7CkiamdpQicUDnGDEC0nzb7ZALjdl3TzFVFEHWM1AFqEXnicNIDeh0IQYTt0NrIP06ibg4W5WflASfFfX9qqib0/0
以上內(nèi)容給大家介紹了微信公眾平臺開發(fā)實戰(zhàn)Java版之微信獲取用戶基本信息,希望本文分享對大家今后的工作學(xué)習(xí)有所幫助,同時感謝大家一直以來對服務(wù)器之家網(wǎng)站的支持。