五、獲取微信用戶信息

**好久沒更新了~~~~隨緣作者。。**
獻上官方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;
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章