GitHub源碼:https://github.com/shirayner/weixin_gz
一、本節要點
1.網頁授權回調域名
登錄微信公眾平台后台, 開發 - 接口權限 - 網頁服務 - 網頁帳號 - 網頁授權獲取用戶基本信息 - 修改,
這里填寫的是域名(是一個字符串),而不是URL
2. 獲取code
獲取code的流程
(1)創建一個跳轉按鈕,鏈接為:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxa0064ea657f80062&redirect_uri=http%3A%2F%2Frayner.nat300.top%2Fweixin_gz%2FIDAuthentication.jsp&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
(2)在jsp頁面 IDAuthentication.jsp 上接收code
//1.接收code和state String code= request.getParameter("code"); String state=request.getParameter("state");
3.通過code換取網頁授權access_token

//3.通過code換取網頁授權access_token private static final String GET_ACCESSTOKEN_BYCODE_URL="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; /** * @desc : 3.通過code換取網頁授權access_token * * @param appId 第三方用戶唯一憑證 * @param appSecret 第三方用戶唯一憑證密鑰,即appsecret * @param Code code作為換取access_token的票據,每次用戶授權帶上的code將不一樣,code只能使用一次,5分鍾未被使用自動過期。 * * @return * access_token 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同 * expires_in access_token接口調用憑證超時時間,單位(秒) * refresh_token 用戶刷新access_token * openid 用戶唯一標識,請注意,在未關注公眾號時,用戶訪問公眾號的網頁,也會產生一個用戶和公眾號唯一的OpenID * scope 用戶授權的作用域,使用逗號(,)分隔 * * @throws Exception String */ public static JSONObject getAccessTokenByCode(String appId,String appSecret,String code) throws Exception { //1.獲取請求url String url=GET_ACCESSTOKEN_BYCODE_URL.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取accessToken JSONObject returnJsonObject=null; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取accessToken }else { returnJsonObject=jsonObject; } } return returnJsonObject; }
4.通過網頁授權access_token 拉取用戶信息

//3. 拉取用戶信息(需scope為 snsapi_userinfo)——網頁授權時 private static final String GET_SNS_USERINFO_URL="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; /** * @desc :3. 拉取用戶信息(需scope為 snsapi_userinfo)——網頁授權時 * * @param accessToken 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同 * @param openId 用戶的唯一標識 * * @return * openid 用戶的唯一標識 * nickname 用戶昵稱 * sex 用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知 * province 用戶個人資料填寫的省份 * city 普通用戶個人資料填寫的城市 * country 國家,如中國為CN * headimgurl 用戶頭像,最后一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空。若用戶更換頭像,原有頭像URL將失效。 * privilege 用戶特權信息,json 數組,如微信沃卡用戶為(chinaunicom) * unionid 只有在用戶將公眾號綁定到微信開放平台帳號后,才會出現該字段。 * * @throws Exception JSONObject */ public static JSONObject getSNSUserInfo(String accessToken,String openId ) throws Exception { //1.獲取請求url String url=GET_SNS_USERINFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取菜單數據 JSONObject returnJsonObject=null; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取菜單數據 } else { returnJsonObject= jsonObject; } } return returnJsonObject; }
二、代碼實現
1.Token工具類—AuthHelper

package com.ray.weixin.gz.util; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Formatter; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.alibaba.fastjson.JSONObject; import com.ray.weixin.gz.config.Env; import com.ray.weixin.gz.service.invoice.InvoiceService; /** * 微信公眾號 Token、配置工具類 * @desc : AccessToken、Jsticket 、Jsapi * * @author: shirayner * @date : 2017年9月27日 下午5:00:25 */ public class AuthHelper { private static final Logger logger = LogManager.getLogger(AuthHelper.class); //1.獲取access_token的接口地址,有效期為7200秒 private static final String GET_ACCESSTOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; //2.獲取getJsapiTicket的接口地址,有效期為7200秒 private static final String GET_JSAPITICKET_URL="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; //3.通過code換取網頁授權access_token private static final String GET_ACCESSTOKEN_BYCODE_URL="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; /** * @desc :1.獲取access_token * * @param appId 第三方用戶唯一憑證 * @param appSecret 第三方用戶唯一憑證密鑰,即appsecret * * @return * access_token 獲取到的憑證 * expires_in 憑證有效時間,單位:秒 * @throws Exception String */ public static String getAccessToken(String appId,String appSecret) throws Exception { //1.獲取請求url String url=GET_ACCESSTOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecret); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取accessToken String accessToken=""; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取accessToken }else { accessToken=jsonObject.getString("access_token"); } } return accessToken; } /** * @desc :2.獲取JsapiTicket * * @param accessToken 有效憑證 * @return * @throws Exception String */ public static String getJsapiTicket(String accessToken) throws Exception { //1.獲取請求url String url=GET_JSAPITICKET_URL.replace("ACCESS_TOKEN", accessToken); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取accessToken String jsapiTicket=""; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取jsapiTicket }else { jsapiTicket=jsonObject.getString("ticket"); } } return jsapiTicket; } /** * @desc : 3.通過code換取網頁授權access_token * * @param appId 第三方用戶唯一憑證 * @param appSecret 第三方用戶唯一憑證密鑰,即appsecret * @param Code code作為換取access_token的票據,每次用戶授權帶上的code將不一樣,code只能使用一次,5分鍾未被使用自動過期。 * * @return * access_token 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同 * expires_in access_token接口調用憑證超時時間,單位(秒) * refresh_token 用戶刷新access_token * openid 用戶唯一標識,請注意,在未關注公眾號時,用戶訪問公眾號的網頁,也會產生一個用戶和公眾號唯一的OpenID * scope 用戶授權的作用域,使用逗號(,)分隔 * * @throws Exception String */ public static JSONObject getAccessTokenByCode(String appId,String appSecret,String code) throws Exception { //1.獲取請求url String url=GET_ACCESSTOKEN_BYCODE_URL.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取accessToken JSONObject returnJsonObject=null; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取accessToken }else { returnJsonObject=jsonObject; } } return returnJsonObject; } /** * @desc :4.獲取前端jsapi需要的配置參數 * * @param request * @return String */ public static String getJsapiConfig(HttpServletRequest request){ //1.准備好參與簽名的字段 //1.1 url /* *以http://localhost/test.do?a=b&c=d為例 *request.getRequestURL的結果是http://localhost/test.do *request.getQueryString的返回值是a=b&c=d */ String urlString = request.getRequestURL().toString(); String queryString = request.getQueryString(); String queryStringEncode = null; String url; if (queryString != null) { queryStringEncode = URLDecoder.decode(queryString); url = urlString + "?" + queryStringEncode; } else { url = urlString; } //1.2 noncestr String nonceStr=UUID.randomUUID().toString(); //隨機數 //1.3 timestamp long timeStamp = System.currentTimeMillis() / 1000; //時間戳參數 String signedUrl = url; String accessToken = null; String ticket = null; String signature = null; //簽名 try { //1.4 jsapi_ticket accessToken=getAccessToken(Env.APP_ID, Env.APP_SECRET); ticket=getJsapiTicket(accessToken); //2.進行簽名,獲取signature signature=getSign(ticket,nonceStr,timeStamp,signedUrl); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } logger.info("accessToken:"+accessToken); logger.info("ticket:"+ticket); logger.info("nonceStr:"+nonceStr); logger.info("timeStamp:"+timeStamp); logger.info("signedUrl:"+signedUrl); logger.info("signature:"+signature); logger.info("appId:"+Env.APP_ID); String configValue = "{signature:'" + signature + "',nonceStr:'" + nonceStr + "',timeStamp:'" + timeStamp + "',appId:'" + Env.APP_ID + "'}"; logger.info("configValue:"+configValue); return configValue; } /** * @desc : 4.1 生成簽名的函數 * * @param ticket jsticket * @param nonceStr 隨機串,自己定義 * @param timeStamp 生成簽名用的時間戳 * @param url 需要進行免登鑒權的頁面地址,也就是執行dd.config的頁面地址 * @return * @throws Exception String */ public static String getSign(String jsTicket, String nonceStr, Long timeStamp, String url) throws Exception { String plainTex = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "×tamp=" + timeStamp + "&url=" + url; System.out.println(plainTex); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(plainTex.getBytes("UTF-8")); return byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { throw new Exception(e.getMessage()); } catch (UnsupportedEncodingException e) { throw new Exception(e.getMessage()); } } /** * @desc :4.2 將bytes類型的數據轉化為16進制類型 * * @param hash * @return * String */ private static String byteToHex(byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", new Object[] { Byte.valueOf(b) }); } String result = formatter.toString(); formatter.close(); return result; } /** 5.獲取前端所需發票簽名參數 * * @desc : *(1)將 api_ticket、appid、timestamp、nonceStr、cardType的value值進行字符串的字典序排序。 *(2)再將所有參數字符串拼接成一個字符串進行sha1加密,得到cardSign。 * * @return String * timestamp :卡券簽名時間戳 nonceStr : 卡券簽名隨機串 signType : 簽名方式,默認'SHA1' cardSign : 卡券簽名 * */ public static String getInvoiceConfig(){ //1.准備好簽名參數 //1.1 api_ticket 授權頁ticket String apiTicket=null; try { String accessToken = AuthHelper.getAccessToken(Env.APP_ID, Env.APP_SECRET); apiTicket=InvoiceService.getAuthPageTicket(accessToken); } catch (Exception e) { logger.info("獲取授權頁ticket失敗"); e.printStackTrace(); } //1.2 appid String appId=Env.APP_ID; //1.3 timestamp 時間戳 String timeStamp = System.currentTimeMillis() / 1000 +""; //1.4 nonceStr 隨機數 String nonceStr=UUID.randomUUID().toString(); //1.5 cardType String cardType="INVOICE"; //2.獲取簽名 String cardSign=null; try { cardSign = AuthHelper.getCardSign(apiTicket, appId, timeStamp, nonceStr, cardType); } catch (Exception e) { logger.info("獲取發票簽名失敗"); e.printStackTrace(); } String signType="SHA1"; logger.info("apiTicket:"+apiTicket); logger.info("appId:"+appId); logger.info("timeStamp:"+timeStamp); logger.info("nonceStr:"+nonceStr); logger.info("cardType:"+cardType); logger.info("cardSign:"+cardSign); logger.info("signType:"+signType); //3.返回前端所需發票簽名參數 JSONObject jsonObject=new JSONObject(); jsonObject.put("timestamp", timeStamp); jsonObject.put("nonceStr",nonceStr ); jsonObject.put("signType",signType ); jsonObject.put("cardSign", cardSign); String configValue = jsonObject.toJSONString(); logger.info("configValue:"+configValue); return configValue; } /** * @desc :5.1獲取發票簽名 * * @param apiTicket 授權頁ticket,見InvoiceService * @param appId * @param timeStamp 時間戳 * @param nonceStr 隨機串 * @param cardType 填入INVOICE * @return * @throws Exception * String */ public static String getCardSign(String apiTicket, String appId, String timeStamp, String nonceStr,String cardType) throws Exception { //1.將 api_ticket、appid、timestamp、nonceStr、cardType的value值進行字符串的字典序排序。 //注意:是value值值 String[] array = new String[] { apiTicket, appId, timeStamp, nonceStr,cardType}; StringBuffer sb = new StringBuffer(); // 字符串排序 Arrays.sort(array); for (int i = 0; i < 5; i++) { sb.append(array[i]); } String plainTex = sb.toString(); //String plainTex = apiTicket+appId+cardType+nonceStr+timeStamp; System.out.println("plainTex:"+plainTex); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(plainTex.getBytes("UTF-8")); return byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { throw new Exception(e.getMessage()); } catch (UnsupportedEncodingException e) { throw new Exception(e.getMessage()); } } public static String getSHA1(String apiTicket, String appId, String timeStamp, String nonceStr,String cardType) throws Exception{ System.out.println("getSHA1-----------"); try { String[] array = new String[] { apiTicket, appId, timeStamp, nonceStr,cardType}; StringBuffer sb = new StringBuffer(); // 字符串排序 Arrays.sort(array); for (int i = 0; i < 5; i++) { sb.append(array[i]); } String str = sb.toString(); logger.info("str:"+str); // SHA1簽名生成 MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(str.getBytes()); byte[] digest = md.digest(); StringBuffer hexstr = new StringBuffer(); String shaHex = ""; for (int i = 0; i < digest.length; i++) { shaHex = Integer.toHexString(digest[i] & 0xFF); if (shaHex.length() < 2) { hexstr.append(0); } hexstr.append(shaHex); } return hexstr.toString(); } catch (Exception e) { e.printStackTrace(); throw new Exception("獲取發票簽名失敗"); } } }
2.用戶管理業務類—UserService

package com.ray.weixin.gz.service.user; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.alibaba.fastjson.JSONObject; import com.ray.weixin.gz.util.HttpHelper; /**@desc : 用戶管理 * * @author: shirayner * @date : 2017年10月31日 下午5:37:08 */ public class UserService { private static final Logger logger = LogManager.getLogger(UserService.class); //1. 獲取用戶基本信息(UnionID機制) private static final String GET_USERINFO_URL="https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; //2.1 獲取用戶列表(從指定的next_openid的下一個開始獲取) private static final String LIST_USER_URL="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID"; //2.2 獲取所有用戶列表 private static final String LIST_ALLUSER_URL="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN"; //3. 拉取用戶信息(需scope為 snsapi_userinfo)——網頁授權時 private static final String GET_SNS_USERINFO_URL="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; /** * @desc :1.獲取用戶基本信息(UnionID機制) * * @param accessToken 有效憑證 * @param openId 普通用戶的標識,對當前公眾號唯一 * * @return 用戶詳細信息 * subscribe 用戶是否訂閱該公眾號標識,值為0時,代表此用戶沒有關注該公眾號,拉取不到其余信息。 * openid 用戶的標識,對當前公眾號唯一 * nickname 用戶的昵稱 * sex 用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知 * city 用戶所在城市 * country 用戶所在國家 * province 用戶所在省份 * language 用戶的語言,簡體中文為zh_CN * headimgurl 用戶頭像,最后一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像), * 用戶沒有頭像時該項為空。若用戶更換頭像,原有頭像URL將失效。 * subscribe_time 用戶關注時間,為時間戳。如果用戶曾多次關注,則取最后關注時間 * unionid 只有在用戶將公眾號綁定到微信開放平台帳號后,才會出現該字段。 * remark 公眾號運營者對粉絲的備注,公眾號運營者可在微信公眾平台用戶管理界面對粉絲添加備注 * groupid 用戶所在的分組ID(兼容舊的用戶分組接口) * tagid_list 用戶被打上的標簽ID列表 * * @throws Exception JSONObject */ public static JSONObject getUserInfo(String accessToken,String openId ) throws Exception { //1.獲取請求url String url=GET_USERINFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取菜單數據 JSONObject returnJsonObject=null; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取菜單數據 } else { returnJsonObject= jsonObject; } } return returnJsonObject; } /** 2.1 獲取用戶列表(從指定的next_openid的下一個開始獲取) * * @desc :一次拉取調用最多拉取10000個關注者的OpenID,可以通過多次拉取的方式來滿足需求。 * * @param accessToken 調用接口憑證 * @param nextOpenId 從指定的next_openid的下一個開始獲取 * * @return * total 關注該公眾賬號的總用戶數 * count 拉取的OPENID個數,最大值為10000 * data 列表數據,OPENID的列表 * next_openid 拉取列表的最后一個用戶的OPENID * * @throws Exception JSONObject */ public static JSONObject listUser(String accessToken,String nextOpenId ) throws Exception { //1.獲取請求url String url=LIST_USER_URL.replace("ACCESS_TOKEN", accessToken).replace("NEXT_OPENID", nextOpenId); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取菜單數據 JSONObject returnJsonObject=null; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取菜單數據 } else { returnJsonObject= jsonObject; } } return returnJsonObject; } /**2.2獲取所有用戶列表 * * @desc :一次拉取調用最多拉取10000個關注者的OpenID,可以通過多次拉取的方式來滿足需求。 * * @param accessToken 調用接口憑證 * * @return * total 關注該公眾賬號的總用戶數 * count 拉取的OPENID個數,最大值為10000 * data 列表數據,OPENID的列表 * next_openid 拉取列表的最后一個用戶的OPENID * * @throws Exception JSONObject */ public static JSONObject listAllUser(String accessToken) throws Exception { //1.獲取請求url String url=LIST_ALLUSER_URL.replace("ACCESS_TOKEN", accessToken); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取菜單數據 JSONObject returnJsonObject=null; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取菜單數據 } else { returnJsonObject= jsonObject; } } return returnJsonObject; } /** * @desc :3. 拉取用戶信息(需scope為 snsapi_userinfo)——網頁授權時 * * @param accessToken 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同 * @param openId 用戶的唯一標識 * * @return * openid 用戶的唯一標識 * nickname 用戶昵稱 * sex 用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知 * province 用戶個人資料填寫的省份 * city 普通用戶個人資料填寫的城市 * country 國家,如中國為CN * headimgurl 用戶頭像,最后一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空。若用戶更換頭像,原有頭像URL將失效。 * privilege 用戶特權信息,json 數組,如微信沃卡用戶為(chinaunicom) * unionid 只有在用戶將公眾號綁定到微信開放平台帳號后,才會出現該字段。 * * @throws Exception JSONObject */ public static JSONObject getSNSUserInfo(String accessToken,String openId ) throws Exception { //1.獲取請求url String url=GET_SNS_USERINFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId); //2.發起GET請求,獲取返回結果 JSONObject jsonObject=HttpHelper.doGet(url); logger.info("jsonObject:"+jsonObject.toJSONString()); //3.解析結果,獲取菜單數據 JSONObject returnJsonObject=null; if (null != jsonObject) { //4.錯誤消息處理 if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); //5.成功獲取菜單數據 } else { returnJsonObject= jsonObject; } } return returnJsonObject; } }
3.IDAuthentication.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page language="java" import="com.ray.weixin.gz.config.*"%> <%@page language="java" import="com.alibaba.fastjson.JSONObject"%> <%@page language="java" import="com.ray.weixin.gz.util.*"%> <%@page language="java" import="com.ray.weixin.gz.service.user.*"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>身份認證</title> <script src="js/jquery-3.2.1.min.js"></script> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> </head> <body> <% //1.接收code和state String code= request.getParameter("code"); String state=request.getParameter("state"); //2.獲取網頁授權時的accessToken 以及 openId JSONObject jsonObject = AuthHelper.getAccessTokenByCode(Env.APP_ID,Env.APP_SECRET, code); String accessToken=jsonObject.getString("access_token"); String openId=jsonObject.getString("openid"); //3.拉取用戶信息 JSONObject userInfoJsonObject =UserService.getSNSUserInfo(accessToken, openId); %> hello,這里是第三方應用 code=<%= code%> <br> state=<%= state%> <br> nickname=<%= userInfoJsonObject.getString("nickname") %> <br><br> sex=<%= userInfoJsonObject.getString("sex") %> <br><br> headimgurl=<%= userInfoJsonObject.getString("headimgurl") %> <br><br> </body> </html>