• JAVA微信公众号网页开发 —— 用户授权获取openid和用户微信信息


    官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

    HttpClientUtil.java
    package com.test;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.MalformedURLException;
    import java.net.URI;
    import java.net.URL;
    import java.net.URLConnection;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    import org.apache.commons.lang.StringUtils;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.StatusLine;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.HttpResponseException;
    import org.apache.http.client.ResponseHandler;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    
    
    public class HttpClientUtil {
    
        private static class SingletonHolder{
            private final static  HttpClientUtil INSTANCE=new HttpClientUtil();
        }
    
        private HttpClientUtil(){}
    
        public static HttpClientUtil getInstance(){
            return SingletonHolder.INSTANCE;
        }
    
        public  String get(String url){
            CharsetHandler handler = new CharsetHandler("UTF-8");
            CloseableHttpClient client = null;
            try {
                HttpGet httpget = new HttpGet(new URI(url));
                HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
                client= httpClientBuilder.build();
                client = (CloseableHttpClient) wrapClient(client);
                return client.execute(httpget, handler);
            } catch (Exception e) {
                //e.printStackTrace();
                return "";
            }finally {
                try {
                    if(client!=null){
                        client.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static String post(String url, String params,String contentType)
        {
    
            //创建HttpClientBuilder
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            //HttpClient
            CloseableHttpClient client = httpClientBuilder.build();
            client = (CloseableHttpClient) wrapClient(client);
    
    
            HttpPost post = new HttpPost(url);
            CloseableHttpResponse res = null;
            try
            {
                StringEntity s = new StringEntity(params,"UTF-8");
                if(StringUtils.isBlank(contentType)){
                    s.setContentType("application/json");
                }
                s.setContentType(contentType);
                s.setContentEncoding("utf-8");
                post.setEntity(s);
                res = client.execute(post);
                HttpEntity entity = res.getEntity();
                return EntityUtils.toString(entity, "utf-8");
            }
            catch (Exception e)
            {
                e.printStackTrace();
            } finally {
                try {
                    res.close();
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return "";
        }
    
        public static String post(String urlStr,String xmlInfo) {
            String line1 = "";
            try {
                URL url = new URL(urlStr);
                URLConnection con = url.openConnection();
                con.setDoOutput(true);
                //con.setRequestProperty("Pragma:", "no-cache");
                con.setRequestProperty("Cache-Control", "no-cache");
                con.setRequestProperty("Content-Type", "text/xml");
    
                OutputStreamWriter out = new OutputStreamWriter(con
                        .getOutputStream());
                out.write(new String(xmlInfo.getBytes("utf-8")));
                out.flush();
                out.close();
                BufferedReader br = new BufferedReader(new InputStreamReader(con
                        .getInputStream()));
                String line = "";
                for (line = br.readLine(); line != null; line = br.readLine()) {
                    line1+=line;
                }
                return new String(line1.getBytes(),"utf-8");
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        private class CharsetHandler implements ResponseHandler<String> {
            private String charset;
    
            public CharsetHandler(String charset) {
                this.charset = charset;
            }
    
            public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() >= 300) {
                    throw new HttpResponseException(statusLine.getStatusCode(),
                            statusLine.getReasonPhrase());
                }
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    if (!StringUtils.isBlank(charset)) {
                        return EntityUtils.toString(entity, charset);
                    } else {
                        return EntityUtils.toString(entity);
                    }
                } else {
                    return null;
                }
            }
        }
    
        private static  HttpClient wrapClient(HttpClient base) {
            try {
                SSLContext ctx = SSLContext.getInstance("TLSv1");
                X509TrustManager tm = new X509TrustManager() {
                    public void checkClientTrusted(X509Certificate[] xcs,
                                                   String string) throws CertificateException {
                    }
    
                    public void checkServerTrusted(X509Certificate[] xcs,
                                                   String string) throws CertificateException {
                    }
    
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                };
                ctx.init(null, new TrustManager[] { tm }, null);
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
                        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
                CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
                return httpclient;
    
            } catch (Exception ex) {
                return null;
            }
        }
    
    }
    

     

    (注:获取到的code只能使用一次,每次请求都要重新获取一次code,因此以下方法,如果用户重新刷新了页面,就会报错,建议把使用过的code放在缓存中,每次请求接口前判断code是否已经使用,如果使用了就重新获取code去请求接口) 

     

    MessageAct.java
    package com.test;
    
    import org.apache.commons.lang.StringUtils;
    import org.json.JSONException;
    import org.json.JSONObject;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    public class MessageAct {
    
         private String appid="公众号的APP_ID";
    
         private String secret="公众号的APP_SECRET";
    
        /**
         * 微信登录
         *
         * @param code
         * @param redirectUrl 返回用户的登录地址
         * @param request
         * @param response
         * @param model
         * @return
         * @throws IOException
         */
        @RequestMapping(value = "/weixinLogin")
        public String weixinLogin(String code, String redirectUrl, HttpServletRequest request, HttpServletResponse response, ModelMap model) throws IOException {
            String redirect_uri = "redirectUrl是授权登录后要进行跳转的链接“
         
    //-----在这里判断code是否已经存在于缓存中,如果存在,说明code已经使用过,需要重新获取code------  
            List list = (List) request.getSession().getAttribute("openid_list");
            if (StringUtils.isNotBlank(code) && list != null && list.contains(code)) {
                //用过了
                code = "";
            }
           //获取code
            if (StringUtils.isBlank(code)) {
                try {
                    PrintWriter out = response.getWriter();
                    out.println("<script>window.location.href='" + getCodeUrl(redirect_uri) + "'</script>");
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    
                return null;
            }
            String[] s = getOpenId(code);
            String openId = s[0];
            String accessToken = s[1];
            String[] userInfo = getUserInfo(openId, accessToken);//获取用户信息
            System.out.println("手机登录openId=================================>" + openId);
            User user = userMng.findById(openId); //查询用户是否存在,openId 作为查询条件
            if (user != null) {
                //用户已经存在
                
            } else {
                //用户不存在,进行注册操作
            }
        return "redirect:" + redirectUrl;
        }
    
    
        /**
         * 获取用户授权 得到openId,accessToken
         *
         * @param code
         * @return
         */
        public String[] getOpenId(String code) {
            String tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?grant_type=authorization_code";
            tokenUrl = tokenUrl + "&appid=" + appid + "&secret=" + secret + "&code=" + code;
            JSONObject json = null;
            try {
                json = new JSONObject(HttpClientUtil.getInstance().get(tokenUrl));  
                        
              //------------在这里把使用过的code存入到缓存中--------   
           
            } catch (JSONException e2) {
                e2.printStackTrace();
            }
            String openId = "";
            String accessToken = "";
            String[] s = new String[2];
            if (json != null) {
                try {
                    openId = json.getString("openid");
                    accessToken = json.getString("access_token");
                    s[0] = openId;
                    s[1] = accessToken;
                } catch (JSONException e) {
                    String errcode = null;
                    try {
                        errcode = json.getString("errcode");
                        System.out.println("errcode================>手机登录 获取用户授权失败" + errcode);
                    } catch (JSONException e1) {
                        e1.printStackTrace();
                    }
                }
            }
            return s;
        }
    
    
        /**
         * 获取用户信息 拉取用户信息(需scope为 snsapi_userinfo)
         * 只有在用户将公众号绑定到微信开放平台帐号后,可以获取unionid
         *
         * @param
         * @param
         * @return
         */
        public String[] getUserInfo(String openid, String accessToken) {
            String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?lang=zh_CN";
            userInfoUrl = userInfoUrl + "&access_token=" + accessToken + "&openid=" + openid;
            JSONObject json = null;
            try {
                json = new JSONObject(HttpClientUtil.getInstance().get(userInfoUrl));
            } catch (JSONException e2) {
                e2.printStackTrace();
            }
            String nickname = ""; //用户昵称
            String sex = "";  //用户的性别
            String province = ""; //用户个人资料填写的省份
            String city = "";  //普通用户个人资料填写的城市
            String country = ""; //国家,如中国为CN
            String headimgurl = ""; //用户头像,
            String unionid = ""; //
            String[] s = new String[6];
            if (json != null) {
                try {
                    nickname = json.getString("nickname");
                    sex = json.getString("sex");
                    province = json.getString("province");
                    city = json.getString("city");
                    country = json.getString("country");
                    headimgurl = json.getString("headimgurl");
                    s[0] = nickname;
                    s[1] = sex;
                    s[2] = province;
                    s[3] = city;
                    s[4] = country;
                    s[5] = headimgurl;
                } catch (JSONException e) {
                    String errcode = null;
                    try {
                        errcode = json.getString("errcode");
                        System.out.println("errcode================>获取用户信息失败" + errcode);
                    } catch (JSONException e1) {
                        e1.printStackTrace();
                    }
                }
            }
            return s;
        }
    
        /**
         * 获取code请求地址
         *
         * @param redirect_uri  回调地址  这个回调地址需要在微信公众号后台也进行配置 不然会显示"redirect_uri域名还是与后台配置不一致" 
         * @param
         * @return
         */
        public String getCodeUrl(String redirect_uri) {     
            redirect_uri=URLEncoder.encode(redirect_uri);   //使用 urlEncode 对链接进行处理 
            String codeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize";
            codeUrl = codeUrl + "?appid=" + appid + "&redirect_uri=" + redirect_uri
                    + "&response_type=code&scope=snsapi_userinfo&state=jetcms#wechat_redirect";
    
            return codeUrl;
        }
    }
    

      

  • 相关阅读:
    ProtoBuf开发者指南(转)
    kafka的c/c++高性能客户端librdkafka简介
    SQL的执行顺序:
    zookeeper与卡夫卡集群搭建
    记一次ping: unknown host错误
    nginx服务器的rewrite功能
    nginx做http向https的自动跳转
    jQuery数据缓存
    jQuery的无new构建
    位操作符的计算优势
  • 原文地址:https://www.cnblogs.com/pxblog/p/10542698.html
Copyright © 2020-2023  润新知