springboot 解析微信小程序获取手机号

引用依赖包

 <dependency>
            <groupId>bouncycastlegroupId>
            <artifactId>bcprov-jdk14artifactId>
            <version>138version>
        dependency>

        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <version>1.2.80version>
        dependency>
        <dependency>
            <groupId>io.github.admin4jgroupId>
            <artifactId>httpartifactId>
            <version>0.4.6version>
        dependency>

        
        
        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-allartifactId>
            <version>5.4.0version>
        dependency>
        <dependency>
            <groupId>org.bouncycastlegroupId>
            <artifactId>bcprov-jdk15onartifactId>
            <version>1.70version>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <version>1.2.80version>
            <scope>compilescope>
        dependency>

AccountInfo


public class AccountInfo {

    public static  String grantType="client_credential";

    public static String appId="";  //

    public static String appSecret="";  //


    public static String accessTokenUrl="https://api.weixin.qq.com/cgi-bin/token" ;

    public static  String getPhoneNumberUrl="https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";

}

接口

  if (code == null || code.length() == 0) {
        
            return  null;
        }

        String wxAppid = AccountInfo.appId;
        // 小程序的 app secret (在微信小程序管理后台获取)
        String wxSecret = AccountInfo.appSecret;
        // 授权(必填)
        String grant_type = AccountInfo.grantType;


        // 请求参数
        String params = "appid=" + wxAppid + "&secret=" + wxSecret + "&grant_type="
                + grant_type;
        try {
            String sr = HttpRequest.sendGetSSL(AccountInfo.accessTokenUrl, params);
            JSONObject json = null;
            System.out.println("sr");
            System.out.println(sr);
            json = JSON.parseObject(sr);
            String access_token = (String) json.get("access_token");
            String jsonData = "{\"code\":\"" + telCode + "\"}";

            Object data = JSON.parse(jsonData);

            String sr1 = HttpRequest.sendPostSSl(AccountInfo.getPhoneNumberUrl + access_token, data);
            System.out.println("sr1");
            System.out.println(sr1);
            json = JSON.parseObject(sr1);
            Integer errcode = (Integer) json.get("errcode");
            if (errcode== 0) {
                String tel = (String) JSON.parseObject(json.get("phone_info").toString()).get("phoneNumber");

                //去数据库里面查询
                if (tel == null || tel.equals("")) {
                    return null;
                }
            } else {

            }
        } catch (Exception e) {
            return  null;
        }

HttpRequest

public class HttpRequest {

    public static void main(String[] args) {
        //发送 GET 请求
        String s=HttpRequest.sendGet("http://v.qq.com/x/cover/kvehb7okfxqstmc.html?vid=e01957zem6o", "");
        System.out.println(s);

//        //发送 POST 请求
//        String sr=HttpRequest.sendPost("http://www.toutiao.com/stream/widget/local_weather/data/?city=%E4%B8%8A%E6%B5%B7", "");
//        JSONObject json = JSONObject.fromObject(sr);
//        System.out.println(json.get("data"));
    }

    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        System.out.println("result");
        System.out.println(result);
        return result;
    }



    /**
     *  http get请求 请求参数在url后面拼接
     *  @throws Exception
     */
    public static String sendGetSSl(String requestUrl, String param,Map<String,String> header) throws Exception{
        HttpsURLConnection conn = null;
        InputStream input = null;
        BufferedReader br = null;
        StringBuffer buffer = null;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            String urlNameString = requestUrl + "?" + param;
            URL url = new URL(urlNameString);
            conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());

            conn.setDoOutput(false);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setConnectTimeout(1000 * 100);
            conn.setReadTimeout(1000 * 100);
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Accept", "*/*");
            conn.setRequestProperty("Connection", "keep-alive");
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            //添加header
            if(header != null){
                for(Map.Entry<String, String> entry : header.entrySet()){
                    String mapKey = entry.getKey();
                    String mapValue = entry.getValue();
                    conn.setRequestProperty(mapKey, mapValue);
                }
            }
            conn.connect();
            // 读取服务器端返回的内容
            System.out.println("======================响应体=========================");
            System.out.println("ResponseCode:" + conn.getResponseCode() + ",ResponseMessage:" + conn.getResponseMessage());
            if(conn.getResponseCode()==200){
                input = conn.getInputStream();
            }else{
                input = conn.getErrorStream();
            }
            br = new BufferedReader(new InputStreamReader(input, "UTF-8"));
            buffer = new StringBuffer();
            String line = null;
            while ((line = br.readLine()) != null) {
                buffer.append(line);
            }
            System.out.println("返回报文:" + buffer.toString());
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.disconnect();
                    conn = null;
                }
                if (br != null) {
                    br.close();
                    br = null;
                }
            } catch (IOException ex) {

                throw new Exception(ex);
            }
        }
        return buffer.toString();
    }


    public static String sendGetSSL(String requestUrl,String param){
        String urlNameString = requestUrl + "?" + param;
        Response response = HttpUtil.get(urlNameString);
        ResponseBody responseBody = response.body();
        okio.BufferedSource source = responseBody.source();
        try {
            source.request(Long.MAX_VALUE); // Buffer the entire body.
            okio.Buffer buffer = source.buffer();

            Charset charset = StandardCharsets.UTF_8;
            MediaType contentType = responseBody.contentType();
            if (contentType != null) {
                charset = contentType.charset(StandardCharsets.UTF_8);
            }
            return buffer.clone().readString(charset);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }

    public static String sendPostSSl(String requestUrl,Object body){
        Response response= HttpUtil.post(requestUrl, body);
        ResponseBody responseBody = response.body();
        okio.BufferedSource source = responseBody.source();
        try {
            source.request(Long.MAX_VALUE); // Buffer the entire body.
            okio.Buffer buffer = source.buffer();

            Charset charset = StandardCharsets.UTF_8;
            MediaType contentType = responseBody.contentType();
            if (contentType != null) {
                charset = contentType.charset(StandardCharsets.UTF_8);
            }
            return buffer.clone().readString(charset);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }
}

TrustAnyHostnameVerifier

public class TrustAnyHostnameVerifier implements HostnameVerifier {
    public boolean verify(String hname, SSLSession session) {
        return true;
    }
}

TrustAnyTrustManager

public class TrustAnyTrustManager implements X509TrustManager {
    public  void checkClientTrusted(java.security.cert.X509Certificate[] var1, String var2) throws java.security.cert.CertificateException{

    }

    public void checkServerTrusted(java.security.cert.X509Certificate[] var1, String var2) throws java.security.cert.CertificateException{

    }

    public java.security.cert.X509Certificate[] getAcceptedIssuers(){
        return null;
    }
}

WeChatUtil

public class WeChatUtil {
    /**
     * 请求微信接口服务,获取 openid,session_key,unionid,errcode,errmsg
     * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
     *
     * @param jscode
     * @return
     */
    public static JSONObject getSessionByCode(String jscode) {
        // jscode是前端请求wx.login()方法获取的code;不是getPhoneNumber接口获取的code
        // wx.login()方法,需要最先调用,否则可能会报错:pad block corrupted,获取不到解密的信息
        String baseUrl = "https://api.weixin.qq.com/sns/jscode2session";
        HashMap<String, Object> requestParam = new HashMap<>();
        // 小程序 appId
        requestParam.put("appid",  AccountInfo.appId);
        // 小程序 appSecret
        requestParam.put("secret",  AccountInfo.appSecret);
        // 登录时获取的 code(小程序端返回的code)
        requestParam.put("js_code", jscode);
        // 默认参数,填“authorization_code”
        requestParam.put("grant_type", "authorization_code");
        // 发送post请求读取调用微信接口获取openid用户唯一标识
        String result = HttpUtil.get(baseUrl, requestParam);
        return JSONUtil.parseObj(result);
    }

    /**
     * 解密:通过加密密钥,iv偏移量来解密 encryptedData
     * 根据encryptedData的不同,解密出来的json数据结构不同(数据结构的详情需要看前端调用的是哪个微信的接口,获取用户哪些信息)
     *
     * @param encryptData
     * @param sessionKey
     * @param iv
     * @return
     */
    public static JSONObject getUserInfo(String encryptData, String sessionKey, String iv) {
        // 解密:被加密的数据
        byte[] dataByte = Base64.decode(encryptData);
        // 解密:加密密钥
        byte[] keyByte = Base64.decode(sessionKey);
        // 解密:偏移量
        byte[] ivByte = Base64.decode(iv);

        try {
            // 如果密钥不足16位,那么就补足。
            // 这个if中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            KeyGenerator.getInstance("AES").init(128);
            // 生成iv
            AlgorithmParameters iv1 = AlgorithmParameters.getInstance("AES");
            iv1.init(new IvParameterSpec(ivByte));
            // 生成解密
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyByte, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv1);// 设置为解密模式
            byte[] decryptByte = cipher.doFinal(dataByte);

            if (null != decryptByte && decryptByte.length > 0) {
                String result = new String(decryptByte, "UTF-8");
                return JSONUtil.parseObj(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

你可能感兴趣的:(spring实战,spring,boot,微信小程序,后端)