**好久沒更新了~~~~隨緣作者。。**
獻上官方bug祕籍:[微信公衆號官方文檔] PS:充滿了錯誤
藍色:官方部分 || 紫色:PS部分
獲取用戶基本信息(UnionID機制)
在關注者與公衆號產生消息交互後,公衆號可獲得關注者的OpenID(加密後的微信號,每個用戶對每個公衆號的OpenID是唯一的。對於不同公衆號,同一用戶的openid不同)。公衆號可通過本接口來根據OpenID獲取用戶基本信息,包括暱稱、頭像、性別、所在城市、語言和關注時間。
請注意,如果開發者有在多個公衆號,或在公衆號、移動應用之間統一用戶帳號的需求,需要前往微信開放平臺(open.weixin.qq.com)綁定公衆號後,纔可利用UnionID機制來滿足上述需求。
**UnionID機制說明:**
開發者可通過OpenID來獲取用戶基本信息。特別需要注意的是,如果開發者擁有多個移動應用、網站應用和公衆帳號,可通過獲取用戶基本信息中的unionid來區分用戶的唯一性,因爲只要是同一個微信開放平臺帳號下的移動應用、網站應用和公衆帳號,用戶的unionid是唯一的。換句話說,同一用戶,對同一個微信開放平臺下的不同應用,unionid是相同的。
PS:openid在同一公衆號下具有唯一性,每個用戶都會有一個openid。
如果需要關聯多個公衆號,可以通過UnionID關聯, 用戶在被關聯的公衆號下unionid唯一。如果公衆號未關聯其他公衆號的帳號,用戶uniondid爲空
一、步入正題~~請求微信接口 ~~微信要求使用HTTPS協議,請求方式GET。
請求方式比較簡單,連接後拼接AccessToken即可,獲取AccessToken建議 全局授權AccessToken,集中處理保存AccessToken,微信每天的調用次數是有限的。
String postValue = HttpUtils.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN");
接口比較簡單,不做詳細贅述,附上工具類,和返回結果的簡單處理代碼
返回代碼實體類: toString是調用工具類進行json字符串化實體,可以自行刪除,用戶名有些特殊字符,編碼後存儲
import com.ibc.utils.format.ObjectFormatUtil;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Encoder;
import java.io.Serializable;
import java.util.List;
@Getter@Setter@NoArgsConstructor
public class UserInfoWechatDto implements Serializable {
private static final long serialVersionUID = 18565694651231L;
private String subscribe;//subscribe 用戶是否訂閱該公衆號標識,值爲0時,代表此用戶沒有關注該公衆號,拉取不到其餘信息。
private String openid;//openid 用戶的標識,對當前公衆號唯一
private String nickname;//nickname 用戶的暱稱
private String sex;//sex 用戶的性別,值爲1時是男性,值爲2時是女性,值爲0時是未知
private String city;//city 用戶所在城市
private String country;//country 用戶所在國家
private String province;//province 用戶所在省份
private String language;//language 用戶的語言,簡體中文爲zh_CN
private String headimgurl;//headimgurl 用戶頭像,最後一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項爲空。若用戶更換頭像,原有頭像URL將失效。
private String subscribe_time;//subscribe_time 用戶關注時間,爲時間戳。如果用戶曾多次關注,則取最後關注時間
private String unionid;//unionid 只有在用戶將公衆號綁定到微信開放平臺帳號後,纔會出現該字段。
private String remark;//remark 公衆號運營者對粉絲的備註,公衆號運營者可在微信公衆平臺用戶管理界面對粉絲添加備註
private String groupid;//groupid 用戶所在的分組ID(兼容舊的用戶分組接口)
private List<String> tagid_list;//tagid_list 用戶被打上的標籤ID列表
private String subscribe_scene;//subscribe_scene 返回用戶關注的渠道來源,ADD_SCENE_SEARCH 公衆號搜索,ADD_SCENE_ACCOUNT_MIGRATION 公衆號遷移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 掃描二維碼,ADD_SCENEPROFILE LINK 圖文頁內名稱點擊,ADD_SCENE_PROFILE_ITEM 圖文頁右上角菜單,ADD_SCENE_PAID 支付後關注,ADD_SCENE_OTHERS 其他
private String qr_scene;//qr_scene 二維碼掃碼場景(開發者自定義)
private String qr_scene_str;//qr_scene_str 二維碼掃碼場景描述(開發者自定義)
@Override
public String toString() {
try {
return ObjectFormatUtil.bean2JSON(this);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* ture 關注 false取關或其他狀態
*/
public static boolean isSubscribe(UserInfoWechatDto userInfoWechatDto) {
if (null == userInfoWechatDto || org.apache.commons.lang3.StringUtils.isBlank(userInfoWechatDto.getSubscribe())) {
return false;
}
if ("1".equals(userInfoWechatDto.getSubscribe())) {
return true;
} else {
return false;
}
}
/**
* 對微信的用戶名做編碼
*/
public String nicknameEncodeBase64() {
if (StringUtils.isBlank(nickname)) {
return null;
}
return new BASE64Encoder().encode(nickname.getBytes());
}
}
獲取微信數據方法
PS:key緩存用戶數據用的RedisKey; sequence,隨機序列可以忽略;
lockService緩存鎖可以忽略;
文中token是調用的公共方法,詳見上面的跳轉地址
/**
* 去微信獲取用戶數據
*
* @param openid
* @param key
* @return
*/
private synchronized UserInfoWechatDto getUserWhchatInfo(String openid, String key, long sequence) {
logger.info("getUserWhchatInfo----傳入參數:openid = [" + openid + "], key = [" + key + "], sequence = [" + sequence + "]" + "請求序列:" + sequence);
try {
UserInfoWechatDto wechatInfo = wechatInfo(key, sequence);
if (null != wechatInfo) {
return wechatInfo;
}
String accessToken = wechatTokenService.getAccessToken();
String postValue = HttpUtils.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN");
if (StringUtils.isBlank(postValue)) {
logger.info("返回值爲 = NULL 請求序列:" + sequence);
return null;
}
JSONObject jsonObject = JSONObject.parseObject(postValue);
if (!jsonObject.containsKey("errcode") || !"ok".equals(String.valueOf(jsonObject.get("errcode")).toLowerCase())) {
logger.warn("getUserWhchatInfo:jsonObject = " + jsonObject + "請求序列:" + sequence);
return null;
}
return JsonFormatUtil.json2Bean(String.valueOf(postValue), UserInfoWechatDto.class);
} catch (Exception e) {
logger.error("getUserWhchatInfo--系統異常: 請求序列:" + sequence, e);
}
return null;
}
發送請求工具方法
/**
* 發送 GET 請求(HTTP),不帶輸入數據
*
* @param url
* @return
*/
public static String get(String url) {
return get(url, new HashMap<String, Object>());
}
/**
* 發送 GET 請求(HTTP),K-V形式
*
* @param url
* @param params
* @return
*/
public static String get(String url, Map<String, Object> params) {
String apiUrl = url;
StringBuffer param = new StringBuffer();
int i = 0;
for (String key : params.keySet()) {
if (i == 0) {
param.append("?");
} else {
param.append("&");
}
param.append(key).append("=").append(params.get(key));
i++;
}
apiUrl += param;
String result = null;
HttpClient httpclient = new DefaultHttpClient();
try {
HttpGet httpPost = new HttpGet(apiUrl);
HttpResponse response = httpclient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("執行狀態碼 : " + statusCode);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = IOUtils.toString(instream, "UTF-8");
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}