微信小程序获取用户手机号码,Java后台servlet解密

本篇记录说明

微信小程序获取用户手机号码,Java后台servlet解密

(第一次写博客,写得不好的地方见谅,面向新手,大佬请无视,不喜勿喷)

一、前言:

微信小程序有一个获取用户手机号码很便捷的接口,通过getPhoneNumber获取用户的已经绑定微信的手机号码。

现在微信和注重用户体验,必须要用户主动触发才可以。必须使用***open-type="getPhoneNumber" ***的按钮来触发。

二、实现步骤:

1、通过wx.login获取【code】;

2、通过getPhoneNumber获取【encryptedData】 、【iv】;(ps:切记第1步和第2步的顺序不能颠倒,先调用wx.login,把wx.login写在onload方法里面;然后再通过getPhoneNumber获取【encryptedData】 、【iv】)

3、通过wx.request将【encryptedData】 、【iv】 、【code】发送到Java后台;

4、Java后台使用【code】,请求微信后台登录凭证校验接口auth.code2Session,获取【openid】和【sessionKey】返回Java后台;

5、Java后台使用【encryptedData】、【iv】、【sessionKey】解密获取用户手机号返回给微信小程序。(ps:微信给的后台解密示例代码里面没有Java,是的,你没有看错,没有Java。)

三、代码展示

1、小程序代码如下:

(1)getPhoneNumber.wxml

<view class='header'>

</view>


<view class='text_view'>

 <text>申请获取以下权限</text>
</view>


<view class='content'>
 <text>获得您的信息(手机号码等)</text>
</view>

<button class='bottom' type='primary' lang="zh_CN" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
 获取手机号码
</button>

<view class='problem'>
 <text>登陆遇到问题?点此联系客服</text>
 <button class='contact-btn' open-type='contact'>a</button>
</view>




<view bindtap="cooperate" class='cooperate-phonenumber'>
 
</view>

(2)getPhoneNumber.wxss

page {
  /* background-color: #eee; */
  height: 100%;
  overflow: hidden;
}
 
 
.header {
  margin: 90rpx 0 90rpx 50rpx;
  text-align: center;
  width: 650rpx;
  height: 300rpx;
  line-height: 450rpx;
}
 
.header image {
  width: 180rpx;
  height: 180rpx;
}
 
.text_view {
  width: 750rpx;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
 
.content {
  margin-bottom: 90rpx;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
 
.content text {
  display: block;
  color: #9d9d9d;
  margin-top: 40rpx;
}
 
.bottom {
  border-radius: 80rpx;
  margin: 30rpx 20rpx;
  font-size: 35rpx;
}
 
 
 
.problem {
  width: 50%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items:center;
  margin-left: 50%;
}
 
.problem text {
  font-size: 28rpx;
  /* display: block; */
  color: #576B95; 
}
 
.contact-btn {
  position: absolute;
  width: 100%;
  opacity: 0;
}
 
 
.cooperate-phonenumber {
  width: 100%;
  position: fixed;
  bottom:20rpx;
  display: flex;
  /* margin-top: 30%; */
  flex-direction: column;
  justify-content: center;
  align-items:center;
  /* margin-left: 50%; */
}
 
.cooperate-phonenumber text {
  font-size: 28rpx;
  /* display: block; */
  color: #576B95; 
}

(3)getPhoneNumber.js

// src/pages/getPhoneNumber/getPhoneNumber.js
Page({
 
  /**
   * 页面的初始数据
   */
  data: {
 
  },
 
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
 
    //获取openid
    wx.login({
      success(res) {
        //获取登录凭证
        console.log("res.conde:" + res.code)
 
 
        try {
          wx.setStorageSync('code', res.code)
        } catch (e) {}
 
 
 
      }
 
    })
 
 
 
 
  },
 
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {
 
  },
 
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {
 
  },
 
 
 
  getPhoneNumber(e) {
    console.log(e)
    console.log("e.detail.errMsg:" + e.detail.errMsg)
    console.log("e.detail.iv:" + e.detail.iv)
    console.log("e.detail.encryptedData:" + e.detail.encryptedData)
 
    var code = wx.getStorageSync('code')
    console.log("conde:" + code)
 
    wx.request({
      url: 'java后台servlet链接',
      //这里要改成post方法,很危险,用get方法的话_20_2_1
      method: "POST",
      data: {
        encryptedData: e.detail.encryptedData,
        iv: e.detail.iv,
        code: code,
      },
      header: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      success: function(data) {
        console.log('data:' + data.data)
 
      },
      fail: function() {
        console.log('request请求错误')
      },
    })
 
 
  },
 
 
 
 
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function() {
 
  },
 
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {
 
  },
 
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function() {
 
  },
 
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function() {
 
  },
 
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function() {
 
  }
 
 
 
 
 
 
 
 
 
 
})

2、Java后台servlet代码如下:

(1) getPhoneNumberServlet,网络请求用okhttp3

 
package servlet;
 
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.MessageDigest;
 
import javax.security.sasl.SaslException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import tools.WXCore;
 
 
public class getPhoneNumberServlet extends HttpServlet {
 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        String selStr;
        InputStream is = null;
 
        try {
            is = request.getInputStream();
            StringBuilder sb = new StringBuilder();
            byte[] b = new byte[4096];
            for (int n; (n = is.read(b)) != -1;) {
                sb.append(new String(b, 0, n));
            }
 
            selStr = java.net.URLDecoder.decode(sb.toString(), "UTF-8");
 
        } catch (IOException e) {
 
            e.printStackTrace();
            return;
 
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        System.out.println("selStr:" + selStr);
 
        String encryptedData = selStr.substring(selStr.lastIndexOf("encryptedData=") + 14, selStr.lastIndexOf("&iv="));
        System.out.println("encryptedData:" + encryptedData);
 
        String iv = selStr.substring(selStr.lastIndexOf("iv=") + 3, selStr.lastIndexOf("&code="));
        System.out.println("iv:" + iv);
 
        String code = selStr.substring(selStr.lastIndexOf("code=") + 5);
        System.out.println("code:" + code);
 
        OkHttpClient client = new OkHttpClient();
        Request okrequest = new Request.Builder()
 
                .url("https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code")
 
                .build();
        try {
 
            Response okresponse = client.newCall(okrequest).execute();
 
            String responsedata = okresponse.body().string();
            System.out.println("responsedata:" + responsedata);
 
            String openid = responsedata.substring(responsedata.lastIndexOf(":") + 2,
                    responsedata.lastIndexOf("\""));
            String session_key = responsedata.substring(responsedata.indexOf(":") + 2,
                    responsedata.indexOf("==") + 2);
 
 
            System.out.println("原始的openid:" + openid);
            System.out.println("原始的session_key:" + session_key);
 
 
            String appId = "wx7xxxxxxxxxxxxxxxxxxxx";
            WXCore wxcore = new WXCore();
            String phonenumber = wxcore.decrypt(appId, encryptedData,                         responsedata_session_key, iv);
 
            System.out.println("手机号码:" + phonenumber);
 
            response.getWriter().write(openid + "&" + phonenumber);
 
        } catch (IOException e) {
 
            e.printStackTrace();
        }
 
    }
 
 
 
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        doGet(request, response);
 
    }
 
}

(2) AES类、WxPKCS7Encoder类、WXCore类,用于解密,用到的包有:bcprov-jdk15on-1.52.jar,commons-codec-1.6.jar,fastjson-1.2.56.jar

<dependency>  
    <groupId>org.bouncycastle</groupId>  
    <artifactId>bcprov-jdk16</artifactId>  
    <version>1.46</version>  
</dependency>
 
<dependency>  
    <groupId>commons-codec</groupId>  
    <artifactId>commons-codec</artifactId>  
    <version>1.10</version>  
</dependency>  
  
<dependency>  
    <groupId>com.alibaba</groupId>  
    <artifactId>fastjson</artifactId>  
    <version>1.2.29</version>  
</dependency>  

 
  
import java.security.AlgorithmParameters;  
import java.security.InvalidAlgorithmParameterException;  
import java.security.InvalidKeyException;  
import java.security.Key;  
import java.security.NoSuchAlgorithmException;  
import java.security.NoSuchProviderException;  
import java.security.Security;  
   
import javax.crypto.BadPaddingException;  
import javax.crypto.Cipher;  
import javax.crypto.IllegalBlockSizeException;  
import javax.crypto.NoSuchPaddingException;  
import javax.crypto.spec.IvParameterSpec;  
import javax.crypto.spec.SecretKeySpec;  
import org.bouncycastle.jce.provider.BouncyCastleProvider;  
   
/** 
 * AES加密 
 */  
public class AES {  
      
    public static boolean initialized = false;  
   
    /** 
     * AES解密 
     *  
     * @param content 
     *            密文 
     * @return 
     * @throws InvalidAlgorithmParameterException 
     * @throws NoSuchProviderException 
     */  
    public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {  
        initialize();  
        try {  
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");  
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");  
            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化  
            byte[] result = cipher.doFinal(content);  
            return result;  
        } catch (NoSuchAlgorithmException e) {  
            e.printStackTrace();  
        } catch (NoSuchPaddingException e) {  
            e.printStackTrace();  
        } catch (InvalidKeyException e) {  
            e.printStackTrace();  
        } catch (IllegalBlockSizeException e) {  
            e.printStackTrace();  
        } catch (BadPaddingException e) {  
            e.printStackTrace();  
        } catch (NoSuchProviderException e) {  
            e.printStackTrace();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  
   
    public static void initialize() {  
        if (initialized)  
            return;  
        Security.addProvider(new BouncyCastleProvider());  
        initialized = true;  
    }  
   
    // 生成iv  
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception {  
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");  
        params.init(new IvParameterSpec(iv));  
        return params;  
    }  
} 


 
import java.nio.charset.Charset;
import java.util.Arrays;
 
/**
 * 微信小程序加解密
 */
public class WxPKCS7Encoder {
    private static final Charset CHARSET = Charset.forName("utf-8");
    private static final int BLOCK_SIZE = 32;
 
    /**
     * 获得对明文进行补位填充的字节.
     * 
     * @param count 需要进行填充补位操作的明文字节个数
     * @return 补齐用的字节数组
     */
    public static byte[] encode(int count) {
        // 计算需要填充的位数
        int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
        if (amountToPad == 0) {
            amountToPad = BLOCK_SIZE;
        }
        // 获得补位所用的字符
        char padChr = chr(amountToPad);
        String tmp = new String();
        for (int index = 0; index < amountToPad; index++) {
            tmp += padChr;
        }
        return tmp.getBytes(CHARSET);
    }
 
    /**
     * 删除解密后明文的补位字符
     * 
     * @param decrypted 解密后的明文
     * @return 删除补位字符后的明文
     */
    public static byte[] decode(byte[] decrypted) {
        int pad = decrypted[decrypted.length - 1];
        if (pad < 1 || pad > 32) {
            pad = 0;
        }
        return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
    }
 
    /**
     * 将数字转化成ASCII码对应的字符,用于对明文进行补码
     * 
     * @param a 需要转化的数字
     * @return 转化得到的字符
     */
    public static char chr(int a) {
        byte target = (byte) (a & 0xFF);
        return (char) target;
    }
}



 
import org.apache.commons.codec.binary.Base64;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
 
/**
 * 封装对外访问方法
 */
public class WXCore {
 
    private static final String WATERMARK = "watermark";
    private static final String APPID = "appid";
 
    /**
     * 解密数据
     * 
     * @return
     * @throws Exception
     */
    public static String decrypt(String appId, String encryptedData, String sessionKey, String iv) {
        String result = "";
        try {
            AES aes = new AES();
            byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey),
                    Base64.decodeBase64(iv));
            if (null != resultByte && resultByte.length > 0) {
                result = new String(WxPKCS7Encoder.decode(resultByte));
                JSONObject jsonObject = JSON.parseObject(result);
                String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString(APPID);
                if (!appId.equals(decryptAppid)) {
                    result = "";
                }
            }
        } catch (Exception e) {
            result = "";
            e.printStackTrace();
        }
        return result;
    }
 
    
}

四、步骤详解:

1、通过wx.login获取【code】;

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
 
    //获取openid
    wx.login({
      success(res) {
        //获取登录凭证
        console.log("res.conde:" + res.code)
 
 
        try {
          wx.setStorageSync('code', res.code)
        } catch (e) {}
 
 
 
      }
 
    })
 
 
 
 
  },

2、通过getPhoneNumber获取【encryptedData】 、【iv】;(ps:切记第1步和第2步的顺序不能颠倒,先调用wx.login,把wx.login写在onload方法里面;然后再通过getPhoneNumber获取【encryptedData】 、【iv】)

  getPhoneNumber(e) {
 
    console.log(e)
    console.log("e.detail.errMsg:" + e.detail.errMsg)
    console.log("e.detail.iv:" + e.detail.iv)
    console.log("e.detail.encryptedData:" + e.detail.encryptedData)
    
  },

3、通过wx.request将【encryptedData】 、【iv】 、【code】发送到Java后台;

 getPhoneNumber(e) {
    console.log(e)
    console.log("e.detail.errMsg:" + e.detail.errMsg)
    console.log("e.detail.iv:" + e.detail.iv)
    console.log("e.detail.encryptedData:" + e.detail.encryptedData)
 
    var code = wx.getStorageSync('code')
    console.log("conde:" + code)
 
    wx.request({
      url: 'Java后台servlet链接',
      method: "POST",
      data: {
        encryptedData: e.detail.encryptedData,
        iv: e.detail.iv,
        code: code,
      },
      header: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      success: function(data) {
        console.log('data:' + data.data)
 
      },
      fail: function() {
        console.log('request请求错误')
      },
    })
 
 
  },

4、Java后台使用【code】,请求微信后台登录凭证校验接口auth.code2Session,获取【openid】和【sessionKey】返回Java后台;(ps:本篇中不用到【openid】,后续微信小程序调用微信支付时用到)

(1)新建getPhoneNumberServlet类,获取【encryptedData】 、【iv】 、【code】

 
package servlet;
 
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.MessageDigest;
 
import javax.security.sasl.SaslException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import tools.WXCore;
 
public class getPhoneNumberServlet extends HttpServlet {
 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        String selStr;
        InputStream is = null;
 
        try {
            is = request.getInputStream();
            StringBuilder sb = new StringBuilder();
            byte[] b = new byte[4096];
            for (int n; (n = is.read(b)) != -1;) {
                sb.append(new String(b, 0, n));
            }
 
            selStr = java.net.URLDecoder.decode(sb.toString(), "UTF-8");
 
        } catch (IOException e) {
 
            e.printStackTrace();
            return;
 
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        System.out.println("selStr:" + selStr);
 
        String encryptedData = selStr.substring(selStr.lastIndexOf("encryptedData=") + 14, selStr.lastIndexOf("&iv="));
        System.out.println("encryptedData:" + encryptedData);
 
        String iv = selStr.substring(selStr.lastIndexOf("iv=") + 3, selStr.lastIndexOf("&code="));
        System.out.println("iv:" + iv);
 
        String code = selStr.substring(selStr.lastIndexOf("code=") + 5);
        System.out.println("code:" + code);
 
        
 
    
 
    }
 
 
 
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        doGet(request, response);
 
    }
 
}

(2)将【code】、【小程序 appId】、【小程序 appSecret】、作为参数,使用okhttp请求微信后台登录凭证校验接口auth.code2Session,获取获取【openid】和【sessionKey】。(ps:本篇中不用到【openid】,后续微信小程序调用微信支付时用到)

 
package servlet;
 
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.MessageDigest;
 
import javax.security.sasl.SaslException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import tools.WXCore;
 
 
public class getPhoneNumberServlet extends HttpServlet {
 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        String selStr;
        InputStream is = null;
 
        try {
            is = request.getInputStream();
            StringBuilder sb = new StringBuilder();
            byte[] b = new byte[4096];
            for (int n; (n = is.read(b)) != -1;) {
                sb.append(new String(b, 0, n));
            }
 
            selStr = java.net.URLDecoder.decode(sb.toString(), "UTF-8");
 
        } catch (IOException e) {
 
            e.printStackTrace();
            return;
 
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        System.out.println("selStr:" + selStr);
 
        String encryptedData = selStr.substring(selStr.lastIndexOf("encryptedData=") + 14, selStr.lastIndexOf("&iv="));
        System.out.println("encryptedData:" + encryptedData);
 
        String iv = selStr.substring(selStr.lastIndexOf("iv=") + 3, selStr.lastIndexOf("&code="));
        System.out.println("iv:" + iv);
 
        String code = selStr.substring(selStr.lastIndexOf("code=") + 5);
        System.out.println("code:" + code);
 
        OkHttpClient client = new OkHttpClient();
        Request okrequest = new Request.Builder()
 
                .url("https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code")
 
                .build();
        try {
 
            Response okresponse = client.newCall(okrequest).execute();
 
            String responsedata = okresponse.body().string();
            System.out.println("responsedata:" + responsedata);
 
            String openid = responsedata.substring(responsedata.lastIndexOf(":") + 2,
                    responsedata.lastIndexOf("\""));
            String session_key = responsedata.substring(responsedata.indexOf(":") + 2,
                    responsedata.indexOf("==") + 2);
 
 
            System.out.println("原始的openid:" + openid);
            System.out.println("原始的session_key:" + session_key);
 
 
        } catch (IOException e) {
 
            e.printStackTrace();
        }
 
    }
 
 
 
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        doGet(request, response);
 
    }
 
}

3、调用WXCore类的decrypt方法,将【appId】、【iv】、【sessionKey】作为参数,对【encryptedData】进行解密,获取手机号码。

 
package servlet;
 
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.MessageDigest;
 
import javax.security.sasl.SaslException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import tools.WXCore;
 
 
public class getPhoneNumberServlet extends HttpServlet {
 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        String selStr;
        InputStream is = null;
 
        try {
            is = request.getInputStream();
            StringBuilder sb = new StringBuilder();
            byte[] b = new byte[4096];
            for (int n; (n = is.read(b)) != -1;) {
                sb.append(new String(b, 0, n));
            }
 
            selStr = java.net.URLDecoder.decode(sb.toString(), "UTF-8");
 
        } catch (IOException e) {
 
            e.printStackTrace();
            return;
 
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        System.out.println("selStr:" + selStr);
 
        String encryptedData = selStr.substring(selStr.lastIndexOf("encryptedData=") + 14, selStr.lastIndexOf("&iv="));
        System.out.println("encryptedData:" + encryptedData);
 
        String iv = selStr.substring(selStr.lastIndexOf("iv=") + 3, selStr.lastIndexOf("&code="));
        System.out.println("iv:" + iv);
 
        String code = selStr.substring(selStr.lastIndexOf("code=") + 5);
        System.out.println("code:" + code);
 
        OkHttpClient client = new OkHttpClient();
        Request okrequest = new Request.Builder()
 
                .url("https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code")
 
                .build();
        try {
 
            Response okresponse = client.newCall(okrequest).execute();
 
            String responsedata = okresponse.body().string();
            System.out.println("responsedata:" + responsedata);
 
            String openid = responsedata.substring(responsedata.lastIndexOf(":") + 2,
                    responsedata.lastIndexOf("\""));
            String session_key = responsedata.substring(responsedata.indexOf(":") + 2,
                    responsedata.indexOf("==") + 2);
 
 
            System.out.println("原始的openid:" + openid);
            System.out.println("原始的session_key:" + session_key);
 
 
            String appId = "wx7xxxxxxxxxxxxxxxxxxxx";
            WXCore wxcore = new WXCore();
            String phonenumber = wxcore.decrypt(appId, encryptedData,                         responsedata_session_key, iv);
 
            System.out.println("手机号码:" + phonenumber);
 
            response.getWriter().write(openid + "&" + phonenumber);
 
        } catch (IOException e) {
 
            e.printStackTrace();
        }
 
    }
 
 
 
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        doGet(request, response);
 
    }
 
}

4、大功告成。

五、运行效果截图:

image.png

六、结语

以上就是微信小程序获取用户手机号码,Java后台servlet解密的流程和注意事项,第一次写博客,写得不好的地方见谅,面向新手,大佬请无视,不喜勿喷。

如果没有解决您的问题,可以添加微信交流:very2cc

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容