zoukankan      html  css  js  c++  java
  • Java微信公众平台开发_05_微信网页授权

    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;
        }
    View Code

    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;
    
    
        }
    View Code

    二、代码实现

    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 + "&timestamp=" + 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("获取发票签名失败");
            }
        }
    
    
    }
    View Code

    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;
    
    
        }
    
    
    
    }
    View Code

    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>
    View Code
  • 相关阅读:
    VMware给虚拟机绑定物理网卡
    Chrome插件开发教程收集
    Linux文本过滤常用命令(转)
    Linux文本过滤命令grep、awk、sed
    Chromium和Chrome的区别
    MyBatis参数为Integer型并赋值为0时判断失误的问题解决
    Java中使用HttpRequest调用RESTfull的DELETE方法接口提示:How to fix HTTP method DELETE doesn't support output
    Ubuntu 16.04服务器版查看IP、网关、DNS(非DHCP)
    CentOS 6.9设置IP、网关、DNS
    Ubuntu 16.04服务器版查看DHCP自动分配的IP、网关、DNS
  • 原文地址:https://www.cnblogs.com/shirui/p/7826021.html
Copyright © 2011-2022 走看看