GitHub源码:https://github.com/shirayner/weixin_gz

一、本节要点

1.网页授权回调域名

登录微信公众平台后台, 开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息 - 修改,

这里填写的是域名(是一个字符串),而不是URL

2. 获取code

获取code的流程

(1)创建一个跳转按钮,链接为:

  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. //1.接收code和state
  2. String code= request.getParameter("code");
  3. String state=request.getParameter("state");

3.通过code换取网页授权access_token

  1. //3.通过code换取网页授权access_token
  2. 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";
  3.  
  4. /**
  5. * @desc : 3.通过code换取网页授权access_token
  6. *
  7. * @param appId 第三方用户唯一凭证
  8. * @param appSecret 第三方用户唯一凭证密钥,即appsecret
  9. * @param Code code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
  10. *
  11. * @return
  12. * access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
  13. * expires_in access_token接口调用凭证超时时间,单位(秒)
  14. * refresh_token 用户刷新access_token
  15. * openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
  16. * scope 用户授权的作用域,使用逗号(,)分隔
  17. *
  18. * @throws Exception String
  19. */
  20. public static JSONObject getAccessTokenByCode(String appId,String appSecret,String code) throws Exception {
  21. //1.获取请求url
  22. String url=GET_ACCESSTOKEN_BYCODE_URL.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);
  23.  
  24. //2.发起GET请求,获取返回结果
  25. JSONObject jsonObject=HttpHelper.doGet(url);
  26. logger.info("jsonObject:"+jsonObject.toJSONString());
  27.  
  28. //3.解析结果,获取accessToken
  29. JSONObject returnJsonObject=null;
  30. if (null != jsonObject) {
  31. //4.错误消息处理
  32. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  33. int errCode = jsonObject.getInteger("errcode");
  34. String errMsg = jsonObject.getString("errmsg");
  35. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  36. //5.成功获取accessToken
  37. }else {
  38. returnJsonObject=jsonObject;
  39. }
  40. }
  41.  
  42. return returnJsonObject;
  43. }

4.通过网页授权access_token 拉取用户信息

  1. //3. 拉取用户信息(需scope为 snsapi_userinfo)——网页授权时
  2. private static final String GET_SNS_USERINFO_URL="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
  3.  
  4. /**
  5. * @desc :3. 拉取用户信息(需scope为 snsapi_userinfo)——网页授权时
  6. *
  7. * @param accessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
  8. * @param openId 用户的唯一标识
  9. *
  10. * @return
  11. * openid 用户的唯一标识
  12. * nickname 用户昵称
  13. * sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
  14. * province 用户个人资料填写的省份
  15. * city 普通用户个人资料填写的城市
  16. * country 国家,如中国为CN
  17. * headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
  18. * privilege 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
  19. * unionid 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
  20. *
  21. * @throws Exception JSONObject
  22. */
  23. public static JSONObject getSNSUserInfo(String accessToken,String openId ) throws Exception {
  24. //1.获取请求url
  25. String url=GET_SNS_USERINFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
  26.  
  27. //2.发起GET请求,获取返回结果
  28. JSONObject jsonObject=HttpHelper.doGet(url);
  29. logger.info("jsonObject:"+jsonObject.toJSONString());
  30.  
  31. //3.解析结果,获取菜单数据
  32. JSONObject returnJsonObject=null;
  33. if (null != jsonObject) {
  34.  
  35. //4.错误消息处理
  36. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  37. int errCode = jsonObject.getInteger("errcode");
  38. String errMsg = jsonObject.getString("errmsg");
  39. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  40. //5.成功获取菜单数据
  41. } else {
  42. returnJsonObject= jsonObject;
  43. }
  44. }
  45.  
  46. return returnJsonObject;
  47.  
  48. }

二、代码实现

1.Token工具类—AuthHelper

  1. package com.ray.weixin.gz.util;
  2.  
  3. import java.io.UnsupportedEncodingException;
  4. import java.net.URLDecoder;
  5. import java.security.MessageDigest;
  6. import java.security.NoSuchAlgorithmException;
  7. import java.util.Arrays;
  8. import java.util.Formatter;
  9. import java.util.UUID;
  10.  
  11. import javax.servlet.http.HttpServletRequest;
  12.  
  13. import org.apache.logging.log4j.LogManager;
  14. import org.apache.logging.log4j.Logger;
  15.  
  16. import com.alibaba.fastjson.JSONObject;
  17. import com.ray.weixin.gz.config.Env;
  18. import com.ray.weixin.gz.service.invoice.InvoiceService;
  19.  
  20. /**
  21. * 微信公众号 Token、配置工具类
  22. * @desc : AccessToken、Jsticket 、Jsapi
  23. *
  24. * @author: shirayner
  25. * @date : 2017年9月27日 下午5:00:25
  26. */
  27. public class AuthHelper {
  28. private static final Logger logger = LogManager.getLogger(AuthHelper.class);
  29.  
  30. //1.获取access_token的接口地址,有效期为7200秒
  31. private static final String GET_ACCESSTOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
  32. //2.获取getJsapiTicket的接口地址,有效期为7200秒
  33. private static final String GET_JSAPITICKET_URL="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
  34.  
  35. //3.通过code换取网页授权access_token
  36. 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";
  37.  
  38. /**
  39. * @desc :1.获取access_token
  40. *
  41. * @param appId 第三方用户唯一凭证
  42. * @param appSecret 第三方用户唯一凭证密钥,即appsecret
  43. *
  44. * @return
  45. * access_token 获取到的凭证
  46. * expires_in 凭证有效时间,单位:秒
  47. * @throws Exception String
  48. */
  49. public static String getAccessToken(String appId,String appSecret) throws Exception {
  50. //1.获取请求url
  51. String url=GET_ACCESSTOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecret);
  52.  
  53. //2.发起GET请求,获取返回结果
  54. JSONObject jsonObject=HttpHelper.doGet(url);
  55. logger.info("jsonObject:"+jsonObject.toJSONString());
  56.  
  57. //3.解析结果,获取accessToken
  58. String accessToken="";
  59. if (null != jsonObject) {
  60. //4.错误消息处理
  61. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  62. int errCode = jsonObject.getInteger("errcode");
  63. String errMsg = jsonObject.getString("errmsg");
  64. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  65. //5.成功获取accessToken
  66. }else {
  67. accessToken=jsonObject.getString("access_token");
  68. }
  69. }
  70.  
  71. return accessToken;
  72. }
  73.  
  74. /**
  75. * @desc :2.获取JsapiTicket
  76. *
  77. * @param accessToken 有效凭证
  78. * @return
  79. * @throws Exception String
  80. */
  81. public static String getJsapiTicket(String accessToken) throws Exception {
  82. //1.获取请求url
  83. String url=GET_JSAPITICKET_URL.replace("ACCESS_TOKEN", accessToken);
  84.  
  85. //2.发起GET请求,获取返回结果
  86. JSONObject jsonObject=HttpHelper.doGet(url);
  87. logger.info("jsonObject:"+jsonObject.toJSONString());
  88.  
  89. //3.解析结果,获取accessToken
  90. String jsapiTicket="";
  91. if (null != jsonObject) {
  92. //4.错误消息处理
  93. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  94. int errCode = jsonObject.getInteger("errcode");
  95. String errMsg = jsonObject.getString("errmsg");
  96. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  97. //5.成功获取jsapiTicket
  98. }else {
  99. jsapiTicket=jsonObject.getString("ticket");
  100. }
  101. }
  102.  
  103. return jsapiTicket;
  104. }
  105.  
  106. /**
  107. * @desc : 3.通过code换取网页授权access_token
  108. *
  109. * @param appId 第三方用户唯一凭证
  110. * @param appSecret 第三方用户唯一凭证密钥,即appsecret
  111. * @param Code code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
  112. *
  113. * @return
  114. * access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
  115. * expires_in access_token接口调用凭证超时时间,单位(秒)
  116. * refresh_token 用户刷新access_token
  117. * openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
  118. * scope 用户授权的作用域,使用逗号(,)分隔
  119. *
  120. * @throws Exception String
  121. */
  122. public static JSONObject getAccessTokenByCode(String appId,String appSecret,String code) throws Exception {
  123. //1.获取请求url
  124. String url=GET_ACCESSTOKEN_BYCODE_URL.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);
  125.  
  126. //2.发起GET请求,获取返回结果
  127. JSONObject jsonObject=HttpHelper.doGet(url);
  128. logger.info("jsonObject:"+jsonObject.toJSONString());
  129.  
  130. //3.解析结果,获取accessToken
  131. JSONObject returnJsonObject=null;
  132. if (null != jsonObject) {
  133. //4.错误消息处理
  134. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  135. int errCode = jsonObject.getInteger("errcode");
  136. String errMsg = jsonObject.getString("errmsg");
  137. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  138. //5.成功获取accessToken
  139. }else {
  140. returnJsonObject=jsonObject;
  141. }
  142. }
  143.  
  144. return returnJsonObject;
  145. }
  146.  
  147. /**
  148. * @desc :4.获取前端jsapi需要的配置参数
  149. *
  150. * @param request
  151. * @return String
  152. */
  153. public static String getJsapiConfig(HttpServletRequest request){
  154.  
  155. //1.准备好参与签名的字段
  156. //1.1 url
  157. /*
  158. *以http://localhost/test.do?a=b&c=d为例
  159. *request.getRequestURL的结果是http://localhost/test.do
  160. *request.getQueryString的返回值是a=b&c=d
  161. */
  162. String urlString = request.getRequestURL().toString();
  163. String queryString = request.getQueryString();
  164. String queryStringEncode = null;
  165. String url;
  166. if (queryString != null) {
  167. queryStringEncode = URLDecoder.decode(queryString);
  168. url = urlString + "?" + queryStringEncode;
  169. } else {
  170. url = urlString;
  171. }
  172.  
  173. //1.2 noncestr
  174. String nonceStr=UUID.randomUUID().toString(); //随机数
  175. //1.3 timestamp
  176. long timeStamp = System.currentTimeMillis() / 1000; //时间戳参数
  177.  
  178. String signedUrl = url;
  179.  
  180. String accessToken = null;
  181. String ticket = null;
  182.  
  183. String signature = null; //签名
  184.  
  185. try {
  186. //1.4 jsapi_ticket
  187. accessToken=getAccessToken(Env.APP_ID, Env.APP_SECRET);
  188. ticket=getJsapiTicket(accessToken);
  189.  
  190. //2.进行签名,获取signature
  191. signature=getSign(ticket,nonceStr,timeStamp,signedUrl);
  192.  
  193. } catch (Exception e) {
  194. // TODO Auto-generated catch block
  195. e.printStackTrace();
  196. }
  197.  
  198. logger.info("accessToken:"+accessToken);
  199. logger.info("ticket:"+ticket);
  200. logger.info("nonceStr:"+nonceStr);
  201. logger.info("timeStamp:"+timeStamp);
  202. logger.info("signedUrl:"+signedUrl);
  203. logger.info("signature:"+signature);
  204. logger.info("appId:"+Env.APP_ID);
  205.  
  206. String configValue = "{signature:'" + signature + "',nonceStr:'" + nonceStr + "',timeStamp:'"
  207. + timeStamp + "',appId:'" + Env.APP_ID + "'}";
  208. logger.info("configValue:"+configValue);
  209.  
  210. return configValue;
  211. }
  212.  
  213. /**
  214. * @desc : 4.1 生成签名的函数
  215. *
  216. * @param ticket jsticket
  217. * @param nonceStr 随机串,自己定义
  218. * @param timeStamp 生成签名用的时间戳
  219. * @param url 需要进行免登鉴权的页面地址,也就是执行dd.config的页面地址
  220. * @return
  221. * @throws Exception String
  222. */
  223.  
  224. public static String getSign(String jsTicket, String nonceStr, Long timeStamp, String url) throws Exception {
  225. String plainTex = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "&timestamp=" + timeStamp + "&url=" + url;
  226. System.out.println(plainTex);
  227. try {
  228. MessageDigest crypt = MessageDigest.getInstance("SHA-1");
  229. crypt.reset();
  230. crypt.update(plainTex.getBytes("UTF-8"));
  231. return byteToHex(crypt.digest());
  232. } catch (NoSuchAlgorithmException e) {
  233. throw new Exception(e.getMessage());
  234. } catch (UnsupportedEncodingException e) {
  235. throw new Exception(e.getMessage());
  236. }
  237. }
  238.  
  239. /**
  240. * @desc :4.2 将bytes类型的数据转化为16进制类型
  241. *
  242. * @param hash
  243. * @return
  244. * String
  245. */
  246. private static String byteToHex(byte[] hash) {
  247. Formatter formatter = new Formatter();
  248. for (byte b : hash) {
  249. formatter.format("%02x", new Object[] { Byte.valueOf(b) });
  250. }
  251. String result = formatter.toString();
  252. formatter.close();
  253. return result;
  254. }
  255.  
  256. /** 5.获取前端所需发票签名参数
  257. *
  258. * @desc :
  259. *(1)将 api_ticket、appid、timestamp、nonceStr、cardType的value值进行字符串的字典序排序。
  260. *(2)再将所有参数字符串拼接成一个字符串进行sha1加密,得到cardSign。
  261. *
  262. * @return String
  263. * timestamp :卡券签名时间戳
  264. nonceStr : 卡券签名随机串
  265. signType : 签名方式,默认'SHA1'
  266. cardSign : 卡券签名
  267. *
  268. */
  269. public static String getInvoiceConfig(){
  270. //1.准备好签名参数
  271. //1.1 api_ticket 授权页ticket
  272. String apiTicket=null;
  273. try {
  274. String accessToken = AuthHelper.getAccessToken(Env.APP_ID, Env.APP_SECRET);
  275. apiTicket=InvoiceService.getAuthPageTicket(accessToken);
  276. } catch (Exception e) {
  277. logger.info("获取授权页ticket失败");
  278. e.printStackTrace();
  279. }
  280.  
  281. //1.2 appid
  282. String appId=Env.APP_ID;
  283.  
  284. //1.3 timestamp 时间戳
  285. String timeStamp = System.currentTimeMillis() / 1000 +"";
  286.  
  287. //1.4 nonceStr 随机数
  288. String nonceStr=UUID.randomUUID().toString();
  289.  
  290. //1.5 cardType
  291. String cardType="INVOICE";
  292.  
  293. //2.获取签名
  294. String cardSign=null;
  295. try {
  296.  
  297. cardSign = AuthHelper.getCardSign(apiTicket, appId, timeStamp, nonceStr, cardType);
  298.  
  299. } catch (Exception e) {
  300. logger.info("获取发票签名失败");
  301. e.printStackTrace();
  302. }
  303.  
  304. String signType="SHA1";
  305.  
  306. logger.info("apiTicket:"+apiTicket);
  307. logger.info("appId:"+appId);
  308. logger.info("timeStamp:"+timeStamp);
  309. logger.info("nonceStr:"+nonceStr);
  310. logger.info("cardType:"+cardType);
  311. logger.info("cardSign:"+cardSign);
  312. logger.info("signType:"+signType);
  313.  
  314. //3.返回前端所需发票签名参数
  315. JSONObject jsonObject=new JSONObject();
  316. jsonObject.put("timestamp", timeStamp);
  317. jsonObject.put("nonceStr",nonceStr );
  318. jsonObject.put("signType",signType );
  319. jsonObject.put("cardSign", cardSign);
  320.  
  321. String configValue = jsonObject.toJSONString();
  322. logger.info("configValue:"+configValue);
  323.  
  324. return configValue;
  325. }
  326.  
  327. /**
  328. * @desc :5.1获取发票签名
  329. *
  330. * @param apiTicket 授权页ticket,见InvoiceService
  331. * @param appId
  332. * @param timeStamp 时间戳
  333. * @param nonceStr 随机串
  334. * @param cardType 填入INVOICE
  335. * @return
  336. * @throws Exception
  337. * String
  338. */
  339. public static String getCardSign(String apiTicket, String appId, String timeStamp, String nonceStr,String cardType) throws Exception {
  340. //1.将 api_ticket、appid、timestamp、nonceStr、cardType的value值进行字符串的字典序排序。
  341. //注意:是value值值
  342. String[] array = new String[] { apiTicket, appId, timeStamp, nonceStr,cardType};
  343. StringBuffer sb = new StringBuffer();
  344. // 字符串排序
  345. Arrays.sort(array);
  346. for (int i = 0; i < 5; i++) {
  347. sb.append(array[i]);
  348. }
  349. String plainTex = sb.toString();
  350.  
  351. //String plainTex = apiTicket+appId+cardType+nonceStr+timeStamp;
  352.  
  353. System.out.println("plainTex:"+plainTex);
  354. try {
  355. MessageDigest crypt = MessageDigest.getInstance("SHA-1");
  356. crypt.reset();
  357. crypt.update(plainTex.getBytes("UTF-8"));
  358. return byteToHex(crypt.digest());
  359. } catch (NoSuchAlgorithmException e) {
  360. throw new Exception(e.getMessage());
  361. } catch (UnsupportedEncodingException e) {
  362. throw new Exception(e.getMessage());
  363. }
  364. }
  365.  
  366. public static String getSHA1(String apiTicket, String appId, String timeStamp, String nonceStr,String cardType) throws Exception{
  367. System.out.println("getSHA1-----------");
  368. try {
  369. String[] array = new String[] { apiTicket, appId, timeStamp, nonceStr,cardType};
  370. StringBuffer sb = new StringBuffer();
  371. // 字符串排序
  372. Arrays.sort(array);
  373. for (int i = 0; i < 5; i++) {
  374. sb.append(array[i]);
  375. }
  376. String str = sb.toString();
  377. logger.info("str:"+str);
  378. // SHA1签名生成
  379. MessageDigest md = MessageDigest.getInstance("SHA-1");
  380. md.update(str.getBytes());
  381. byte[] digest = md.digest();
  382.  
  383. StringBuffer hexstr = new StringBuffer();
  384. String shaHex = "";
  385. for (int i = 0; i < digest.length; i++) {
  386. shaHex = Integer.toHexString(digest[i] & 0xFF);
  387. if (shaHex.length() < 2) {
  388. hexstr.append(0);
  389. }
  390. hexstr.append(shaHex);
  391. }
  392. return hexstr.toString();
  393. } catch (Exception e) {
  394. e.printStackTrace();
  395. throw new Exception("获取发票签名失败");
  396. }
  397. }
  398.  
  399. }

2.用户管理业务类—UserService

  1. package com.ray.weixin.gz.service.user;
  2.  
  3. import org.apache.logging.log4j.LogManager;
  4. import org.apache.logging.log4j.Logger;
  5.  
  6. import com.alibaba.fastjson.JSONObject;
  7. import com.ray.weixin.gz.util.HttpHelper;
  8.  
  9. /**@desc : 用户管理
  10. *
  11. * @author: shirayner
  12. * @date : 2017年10月31日 下午5:37:08
  13. */
  14. public class UserService {
  15. private static final Logger logger = LogManager.getLogger(UserService.class);
  16.  
  17. //1. 获取用户基本信息(UnionID机制)
  18. 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";
  19. //2.1 获取用户列表(从指定的next_openid的下一个开始获取)
  20. private static final String LIST_USER_URL="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";
  21. //2.2 获取所有用户列表
  22. private static final String LIST_ALLUSER_URL="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN";
  23. //3. 拉取用户信息(需scope为 snsapi_userinfo)——网页授权时
  24. private static final String GET_SNS_USERINFO_URL="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
  25.  
  26. /**
  27. * @desc :1.获取用户基本信息(UnionID机制)
  28. *
  29. * @param accessToken 有效凭证
  30. * @param openId 普通用户的标识,对当前公众号唯一
  31. *
  32. * @return 用户详细信息
  33. * subscribe 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
  34. * openid 用户的标识,对当前公众号唯一
  35. * nickname 用户的昵称
  36. * sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
  37. * city 用户所在城市
  38. * country 用户所在国家
  39. * province 用户所在省份
  40. * language 用户的语言,简体中文为zh_CN
  41. * headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),
  42. * 用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
  43. * subscribe_time 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
  44. * unionid 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
  45. * remark 公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
  46. * groupid 用户所在的分组ID(兼容旧的用户分组接口)
  47. * tagid_list 用户被打上的标签ID列表
  48. *
  49. * @throws Exception JSONObject
  50. */
  51. public static JSONObject getUserInfo(String accessToken,String openId ) throws Exception {
  52. //1.获取请求url
  53. String url=GET_USERINFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
  54.  
  55. //2.发起GET请求,获取返回结果
  56. JSONObject jsonObject=HttpHelper.doGet(url);
  57. logger.info("jsonObject:"+jsonObject.toJSONString());
  58.  
  59. //3.解析结果,获取菜单数据
  60. JSONObject returnJsonObject=null;
  61. if (null != jsonObject) {
  62.  
  63. //4.错误消息处理
  64. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  65. int errCode = jsonObject.getInteger("errcode");
  66. String errMsg = jsonObject.getString("errmsg");
  67. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  68. //5.成功获取菜单数据
  69. } else {
  70. returnJsonObject= jsonObject;
  71. }
  72. }
  73.  
  74. return returnJsonObject;
  75. }
  76.  
  77. /** 2.1 获取用户列表(从指定的next_openid的下一个开始获取)
  78. *
  79. * @desc :一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。
  80. *
  81. * @param accessToken 调用接口凭证
  82. * @param nextOpenId 从指定的next_openid的下一个开始获取
  83. *
  84. * @return
  85. * total 关注该公众账号的总用户数
  86. * count 拉取的OPENID个数,最大值为10000
  87. * data 列表数据,OPENID的列表
  88. * next_openid 拉取列表的最后一个用户的OPENID
  89. *
  90. * @throws Exception JSONObject
  91. */
  92. public static JSONObject listUser(String accessToken,String nextOpenId ) throws Exception {
  93. //1.获取请求url
  94. String url=LIST_USER_URL.replace("ACCESS_TOKEN", accessToken).replace("NEXT_OPENID", nextOpenId);
  95.  
  96. //2.发起GET请求,获取返回结果
  97. JSONObject jsonObject=HttpHelper.doGet(url);
  98. logger.info("jsonObject:"+jsonObject.toJSONString());
  99.  
  100. //3.解析结果,获取菜单数据
  101. JSONObject returnJsonObject=null;
  102. if (null != jsonObject) {
  103.  
  104. //4.错误消息处理
  105. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  106. int errCode = jsonObject.getInteger("errcode");
  107. String errMsg = jsonObject.getString("errmsg");
  108. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  109. //5.成功获取菜单数据
  110. } else {
  111. returnJsonObject= jsonObject;
  112. }
  113. }
  114.  
  115. return returnJsonObject;
  116. }
  117.  
  118. /**2.2获取所有用户列表
  119. *
  120. * @desc :一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。
  121. *
  122. * @param accessToken 调用接口凭证
  123. *
  124. * @return
  125. * total 关注该公众账号的总用户数
  126. * count 拉取的OPENID个数,最大值为10000
  127. * data 列表数据,OPENID的列表
  128. * next_openid 拉取列表的最后一个用户的OPENID
  129. *
  130. * @throws Exception JSONObject
  131. */
  132. public static JSONObject listAllUser(String accessToken) throws Exception {
  133. //1.获取请求url
  134. String url=LIST_ALLUSER_URL.replace("ACCESS_TOKEN", accessToken);
  135.  
  136. //2.发起GET请求,获取返回结果
  137. JSONObject jsonObject=HttpHelper.doGet(url);
  138. logger.info("jsonObject:"+jsonObject.toJSONString());
  139.  
  140. //3.解析结果,获取菜单数据
  141. JSONObject returnJsonObject=null;
  142. if (null != jsonObject) {
  143.  
  144. //4.错误消息处理
  145. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  146. int errCode = jsonObject.getInteger("errcode");
  147. String errMsg = jsonObject.getString("errmsg");
  148. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  149. //5.成功获取菜单数据
  150. } else {
  151. returnJsonObject= jsonObject;
  152. }
  153. }
  154.  
  155. return returnJsonObject;
  156. }
  157.  
  158. /**
  159. * @desc :3. 拉取用户信息(需scope为 snsapi_userinfo)——网页授权时
  160. *
  161. * @param accessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
  162. * @param openId 用户的唯一标识
  163. *
  164. * @return
  165. * openid 用户的唯一标识
  166. * nickname 用户昵称
  167. * sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
  168. * province 用户个人资料填写的省份
  169. * city 普通用户个人资料填写的城市
  170. * country 国家,如中国为CN
  171. * headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
  172. * privilege 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
  173. * unionid 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
  174. *
  175. * @throws Exception JSONObject
  176. */
  177. public static JSONObject getSNSUserInfo(String accessToken,String openId ) throws Exception {
  178. //1.获取请求url
  179. String url=GET_SNS_USERINFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
  180.  
  181. //2.发起GET请求,获取返回结果
  182. JSONObject jsonObject=HttpHelper.doGet(url);
  183. logger.info("jsonObject:"+jsonObject.toJSONString());
  184.  
  185. //3.解析结果,获取菜单数据
  186. JSONObject returnJsonObject=null;
  187. if (null != jsonObject) {
  188.  
  189. //4.错误消息处理
  190. if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
  191. int errCode = jsonObject.getInteger("errcode");
  192. String errMsg = jsonObject.getString("errmsg");
  193. throw new Exception("error code:"+errCode+", error message:"+errMsg);
  194. //5.成功获取菜单数据
  195. } else {
  196. returnJsonObject= jsonObject;
  197. }
  198. }
  199.  
  200. return returnJsonObject;
  201.  
  202. }
  203.  
  204. }

3.IDAuthentication.jsp

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@page language="java" import="com.ray.weixin.gz.config.*"%>
  4. <%@page language="java" import="com.alibaba.fastjson.JSONObject"%>
  5. <%@page language="java" import="com.ray.weixin.gz.util.*"%>
  6. <%@page language="java" import="com.ray.weixin.gz.service.user.*"%>
  7. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  8. <html>
  9. <head>
  10. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  11. <title>身份认证</title>
  12. <script src="js/jquery-3.2.1.min.js"></script>
  13. <script type="text/javascript"
  14. src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
  15.  
  16. </head>
  17. <body>
  18.  
  19. <%
  20. //1.接收code和state
  21. String code= request.getParameter("code");
  22. String state=request.getParameter("state");
  23.  
  24. //2.获取网页授权时的accessToken 以及 openId
  25. JSONObject jsonObject = AuthHelper.getAccessTokenByCode(Env.APP_ID,Env.APP_SECRET, code);
  26. String accessToken=jsonObject.getString("access_token");
  27. String openId=jsonObject.getString("openid");
  28.  
  29. //3.拉取用户信息
  30. JSONObject userInfoJsonObject =UserService.getSNSUserInfo(accessToken, openId);
  31.  
  32. %>
  33.  
  34. hello,这里是第三方应用
  35.  
  36. code=<%= code%> <br>
  37. state=<%= state%> <br>
  38. nickname=<%= userInfoJsonObject.getString("nickname") %> <br><br>
  39. sex=<%= userInfoJsonObject.getString("sex") %> <br><br>
  40. headimgurl=<%= userInfoJsonObject.getString("headimgurl") %> <br><br>
  41.  
  42. </body>
  43. </html>

Java微信公众平台开发_05_微信网页授权的更多相关文章

  1. 微信公众平台开发-OAuth2.0网页授权(含源码)

    微信公众平台开发-OAuth2.0网页授权接口.网页授权接口详解(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 在微信开发的高级应用中,几乎都会使用到该接口,因为通过该接口,可以获 ...

  2. 黄聪:微信公众平台开发OAuth2.0网页授权(转)

    微信公众平台开发 OAuth2.0网页授权认证 网页授权获取用户基本信息 作者:方倍工作室 微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友在使 ...

  3. 微信公众平台开发 OAuth2.0网页授权认证

    一.什么是OAuth2.0 官方网站:http://oauth.NET/   http://oauth.Net/2/ 权威定义:OAuth is An open protocol to allow s ...

  4. php 微信公众平台开发之微信群发信息

    这篇文章主要为大家详细介绍了php微信公众平台开发之微信群发信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.目的 完成在微信公众号中群发消息.这里只是完成简单的文字发送.也可以发送语音图片 ...

  5. Java微信公众平台开发(十)--微信用户信息的获取

    前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信用户的信息,在上一篇我们有说道微信用户和微信公众账号之间的联系可以通过Openid关 ...

  6. 微信公众平台开发(110) 微信连Wi-Fi

    关键字:微信公众平台 微信连Wi-Fi 微信 WiFi 硬件鉴权作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/weixin-wifi.html 微信连Wi- ...

  7. Java微信公众平台开发(十三)--微信JSSDK中Config配置

    转自:http://www.cuiyongzhi.com/post/57.html 前端开发工程师和关注前端开发的开发者们在2015年中肯定被腾讯的JSSDk引爆过,搞APP的.搞前端的甚至是是搞后端 ...

  8. Java微信公众平台开发(十)--微信自定义菜单的创建实现

    转自:http://www.cuiyongzhi.com/post/48.html 自定义菜单这个功能在我们普通的编辑模式下是可以直接在后台编辑的,但是一旦我们进入开发模式之后我们的自定义菜单就需要自 ...

  9. Java微信公众平台开发(十一)--微信JSSDK中Config配置

    JSSDK曾经引爆前端以及后端的工程师,其魔性的力量毋庸置疑,在我们的技术眼里它的实现原理和根本是不能够被改变的,这篇文章就不对其js的实现做任何评价和解说了(因为我也不是很懂,哈哈),这里要说的是它 ...

随机推荐

  1. vs 已经加入了引用,编译还是提示没有加入引用

    已经加入了引用,可是.编译还是通只是. 原因:项目总体框架是.Net FramWork4.5,nep中的框架也是4.5.而编译只是的project是4.0. 解决的方法:将编译只是的项目框架改为4.5

  2. C++一元多项式相加

    实验名称:一元多项式相加 // multiply.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream& ...

  3. ubuntu 安装 rpm 软件包

    1.首先安装alien和fakeroot这两个软件,alien可以将rpm转换为deb包.命令sudo apt-get install alien fakeroot 2.使用alien将rpm包转为d ...

  4. 【甘道夫】Ubuntu14 server + Hadoop2.2.0环境下Sqoop1.99.3部署记录

    第一步.下载.解压.配置环境变量: 官网下载sqoop1.99.3 http://mirrors.cnnic.cn/apache/sqoop/1.99.3/ 将sqoop解压到目标文件夹,我的是 /h ...

  5. HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程

    在<HDFS源码分析心跳汇报之数据结构初始化>一文中,我们了解到HDFS心跳相关的BlockPoolManager.BPOfferService.BPServiceActor三者之间的关系 ...

  6. iptables简易使用教程

    iptables是linux里比较常用的防火墙,也是centos7.0之前的版本默认自带的防火墙. 配置防火墙需特别注意一件事情:如果服务器在异地机房,需要谨慎配置端口,以免造成新配置生效后无法远程登 ...

  7. iOS程序自动检测更新的实现

      本文转载至 http://blog.csdn.net/davidsph/article/details/8931718 App Store自动更新itunes     之前项目需要用到app自动更 ...

  8. UITableView使用指南

    本文转载至 http://blog.csdn.net/yu0089/article/details/8227402 一.概述 UITableView是iOS开发比不可少也是最重要的一个控件类.可以说任 ...

  9. @Bean 和@ Component的区别

    @Component auto detects and configures the beans using classpath scanning whereas @Bean explicitly d ...

  10. Unix环境高级编程第三版中实例代码如何在自己的linux上运行的问题

    学习Linux已经有2个月了,最近被期末考试把进度耽误了,前几天把Unix环境高级编程看了两章,感觉对Linux的整体有了一些思路,今天尝试着对第一章涉及到的一个简单的交互式shell编译运行一下,结 ...