当前位置:   article > 正文

微信小程序获取用户手机号码,Java后台servlet解密(微信小程序调用微信支付也是大致的流程)_{ code, encrypteddata, iv }

{ code, encrypteddata, iv }

本篇记录说明

微信小程序获取用户手机号码,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

  1. <view class='header'>
  2. </view>
  3. <view class='text_view'>
  4. <text>申请获取以下权限</text>
  5. </view>
  6. <view class='content'>
  7. <text>获得您的信息(手机号码等)</text>
  8. </view>
  9. <button class='bottom' type='primary' lang="zh_CN" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
  10. 获取手机号码
  11. </button>
  12. <view class='problem'>
  13. <text>登陆遇到问题?点此联系客服</text>
  14. <button class='contact-btn' open-type='contact'>a</button>
  15. </view>
  16. <view bindtap="cooperate" class='cooperate-phonenumber'>
  17. </view>

(2)getPhoneNumber.wxss

  1. page {
  2. /* background-color: #eee; */
  3. height: 100%;
  4. overflow: hidden;
  5. }
  6. .header {
  7. margin: 90rpx 0 90rpx 50rpx;
  8. text-align: center;
  9. width: 650rpx;
  10. height: 300rpx;
  11. line-height: 450rpx;
  12. }
  13. .header image {
  14. width: 180rpx;
  15. height: 180rpx;
  16. }
  17. .text_view {
  18. width: 750rpx;
  19. display: flex;
  20. flex-direction: column;
  21. justify-content: center;
  22. align-items: center;
  23. }
  24. .content {
  25. margin-bottom: 90rpx;
  26. display: flex;
  27. flex-direction: column;
  28. justify-content: center;
  29. align-items: center;
  30. }
  31. .content text {
  32. display: block;
  33. color: #9d9d9d;
  34. margin-top: 40rpx;
  35. }
  36. .bottom {
  37. border-radius: 80rpx;
  38. margin: 30rpx 20rpx;
  39. font-size: 35rpx;
  40. }
  41. .problem {
  42. width: 50%;
  43. display: flex;
  44. flex-direction: column;
  45. justify-content: center;
  46. align-items:center;
  47. margin-left: 50%;
  48. }
  49. .problem text {
  50. font-size: 28rpx;
  51. /* display: block; */
  52. color: #576B95;
  53. }
  54. .contact-btn {
  55. position: absolute;
  56. width: 100%;
  57. opacity: 0;
  58. }
  59. .cooperate-phonenumber {
  60. width: 100%;
  61. position: fixed;
  62. bottom:20rpx;
  63. display: flex;
  64. /* margin-top: 30%; */
  65. flex-direction: column;
  66. justify-content: center;
  67. align-items:center;
  68. /* margin-left: 50%; */
  69. }
  70. .cooperate-phonenumber text {
  71. font-size: 28rpx;
  72. /* display: block; */
  73. color: #576B95;
  74. }

(3)getPhoneNumber.js

  1. // src/pages/getPhoneNumber/getPhoneNumber.js
  2. Page({
  3. /**
  4. * 页面的初始数据
  5. */
  6. data: {
  7. },
  8. /**
  9. * 生命周期函数--监听页面加载
  10. */
  11. onLoad: function(options) {
  12. //获取openid
  13. wx.login({
  14. success(res) {
  15. //获取登录凭证
  16. console.log("res.conde:" + res.code)
  17. try {
  18. wx.setStorageSync('code', res.code)
  19. } catch (e) {}
  20. }
  21. })
  22. },
  23. /**
  24. * 生命周期函数--监听页面初次渲染完成
  25. */
  26. onReady: function() {
  27. },
  28. /**
  29. * 生命周期函数--监听页面显示
  30. */
  31. onShow: function() {
  32. },
  33. getPhoneNumber(e) {
  34. console.log(e)
  35. console.log("e.detail.errMsg:" + e.detail.errMsg)
  36. console.log("e.detail.iv:" + e.detail.iv)
  37. console.log("e.detail.encryptedData:" + e.detail.encryptedData)
  38. var code = wx.getStorageSync('code')
  39. console.log("conde:" + code)
  40. wx.request({
  41. url: 'java后台servlet链接',
  42. method: "POST",
  43. data: {
  44. encryptedData: e.detail.encryptedData,
  45. iv: e.detail.iv,
  46. code: code,
  47. },
  48. header: {
  49. "Content-Type": "application/x-www-form-urlencoded"
  50. },
  51. success: function(data) {
  52. console.log('data:' + data.data)
  53. },
  54. fail: function() {
  55. console.log('request请求错误')
  56. },
  57. })
  58. },
  59. /**
  60. * 生命周期函数--监听页面隐藏
  61. */
  62. onHide: function() {
  63. },
  64. /**
  65. * 生命周期函数--监听页面卸载
  66. */
  67. onUnload: function() {
  68. },
  69. /**
  70. * 页面相关事件处理函数--监听用户下拉动作
  71. */
  72. onPullDownRefresh: function() {
  73. },
  74. /**
  75. * 页面上拉触底事件的处理函数
  76. */
  77. onReachBottom: function() {
  78. },
  79. /**
  80. * 用户点击右上角分享
  81. */
  82. onShareAppMessage: function() {
  83. }
  84. })

2、Java后台servlet代码如下:

(1) getPhoneNumberServlet,网络请求用okhttp3

  1. package servlet;
  2. import java.io.DataOutputStream;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.math.BigInteger;
  7. import java.net.Socket;
  8. import java.net.UnknownHostException;
  9. import java.security.MessageDigest;
  10. import javax.security.sasl.SaslException;
  11. import javax.servlet.ServletException;
  12. import javax.servlet.http.HttpServlet;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import okhttp3.OkHttpClient;
  16. import okhttp3.Request;
  17. import okhttp3.Response;
  18. import tools.WXCore;
  19. public class getPhoneNumberServlet extends HttpServlet {
  20. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  21. String selStr;
  22. InputStream is = null;
  23. try {
  24. is = request.getInputStream();
  25. StringBuilder sb = new StringBuilder();
  26. byte[] b = new byte[4096];
  27. for (int n; (n = is.read(b)) != -1;) {
  28. sb.append(new String(b, 0, n));
  29. }
  30. selStr = java.net.URLDecoder.decode(sb.toString(), "UTF-8");
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. return;
  34. } finally {
  35. if (null != is) {
  36. try {
  37. is.close();
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }
  43. System.out.println("selStr:" + selStr);
  44. String encryptedData = selStr.substring(selStr.lastIndexOf("encryptedData=") + 14, selStr.lastIndexOf("&iv="));
  45. System.out.println("encryptedData:" + encryptedData);
  46. String iv = selStr.substring(selStr.lastIndexOf("iv=") + 3, selStr.lastIndexOf("&code="));
  47. System.out.println("iv:" + iv);
  48. String code = selStr.substring(selStr.lastIndexOf("code=") + 5);
  49. System.out.println("code:" + code);
  50. OkHttpClient client = new OkHttpClient();
  51. Request okrequest = new Request.Builder()
  52. .url("https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code")
  53. .build();
  54. try {
  55. Response okresponse = client.newCall(okrequest).execute();
  56. String responsedata = okresponse.body().string();
  57. System.out.println("responsedata:" + responsedata);
  58. String openid = responsedata.substring(responsedata.lastIndexOf(":") + 2,
  59. responsedata.lastIndexOf("\""));
  60. String session_key = responsedata.substring(responsedata.indexOf(":") + 2,
  61. responsedata.indexOf("==") + 2);
  62. System.out.println("原始的openid:" + openid);
  63. System.out.println("原始的session_key:" + session_key);
  64. String appId = "wx7xxxxxxxxxxxxxxxxxxxx";
  65. WXCore wxcore = new WXCore();
  66. String phonenumber = wxcore.decrypt(appId, encryptedData, responsedata_session_key, iv);
  67. System.out.println("手机号码:" + phonenumber);
  68. response.getWriter().write(openid + "&" + phonenumber);
  69. } catch (IOException e) {
  70. e.printStackTrace();
  71. }
  72. }
  73. public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  74. doGet(request, response);
  75. }
  76. }

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

  1. <dependency>
  2. <groupId>org.bouncycastle</groupId>
  3. <artifactId>bcprov-jdk16</artifactId>
  4. <version>1.46</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>commons-codec</groupId>
  8. <artifactId>commons-codec</artifactId>
  9. <version>1.10</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.alibaba</groupId>
  13. <artifactId>fastjson</artifactId>
  14. <version>1.2.29</version>
  15. </dependency>

  1. import java.security.AlgorithmParameters;
  2. import java.security.InvalidAlgorithmParameterException;
  3. import java.security.InvalidKeyException;
  4. import java.security.Key;
  5. import java.security.NoSuchAlgorithmException;
  6. import java.security.NoSuchProviderException;
  7. import java.security.Security;
  8. import javax.crypto.BadPaddingException;
  9. import javax.crypto.Cipher;
  10. import javax.crypto.IllegalBlockSizeException;
  11. import javax.crypto.NoSuchPaddingException;
  12. import javax.crypto.spec.IvParameterSpec;
  13. import javax.crypto.spec.SecretKeySpec;
  14. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  15. /**
  16. * AES加密
  17. */
  18. public class AES {
  19. public static boolean initialized = false;
  20. /**
  21. * AES解密
  22. *
  23. * @param content
  24. * 密文
  25. * @return
  26. * @throws InvalidAlgorithmParameterException
  27. * @throws NoSuchProviderException
  28. */
  29. public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
  30. initialize();
  31. try {
  32. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
  33. Key sKeySpec = new SecretKeySpec(keyByte, "AES");
  34. cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
  35. byte[] result = cipher.doFinal(content);
  36. return result;
  37. } catch (NoSuchAlgorithmException e) {
  38. e.printStackTrace();
  39. } catch (NoSuchPaddingException e) {
  40. e.printStackTrace();
  41. } catch (InvalidKeyException e) {
  42. e.printStackTrace();
  43. } catch (IllegalBlockSizeException e) {
  44. e.printStackTrace();
  45. } catch (BadPaddingException e) {
  46. e.printStackTrace();
  47. } catch (NoSuchProviderException e) {
  48. e.printStackTrace();
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. return null;
  53. }
  54. public static void initialize() {
  55. if (initialized)
  56. return;
  57. Security.addProvider(new BouncyCastleProvider());
  58. initialized = true;
  59. }
  60. // 生成iv
  61. public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
  62. AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
  63. params.init(new IvParameterSpec(iv));
  64. return params;
  65. }
  66. }
  1. import java.nio.charset.Charset;
  2. import java.util.Arrays;
  3. /**
  4. * 微信小程序加解密
  5. */
  6. public class WxPKCS7Encoder {
  7. private static final Charset CHARSET = Charset.forName("utf-8");
  8. private static final int BLOCK_SIZE = 32;
  9. /**
  10. * 获得对明文进行补位填充的字节.
  11. *
  12. * @param count 需要进行填充补位操作的明文字节个数
  13. * @return 补齐用的字节数组
  14. */
  15. public static byte[] encode(int count) {
  16. // 计算需要填充的位数
  17. int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
  18. if (amountToPad == 0) {
  19. amountToPad = BLOCK_SIZE;
  20. }
  21. // 获得补位所用的字符
  22. char padChr = chr(amountToPad);
  23. String tmp = new String();
  24. for (int index = 0; index < amountToPad; index++) {
  25. tmp += padChr;
  26. }
  27. return tmp.getBytes(CHARSET);
  28. }
  29. /**
  30. * 删除解密后明文的补位字符
  31. *
  32. * @param decrypted 解密后的明文
  33. * @return 删除补位字符后的明文
  34. */
  35. public static byte[] decode(byte[] decrypted) {
  36. int pad = decrypted[decrypted.length - 1];
  37. if (pad < 1 || pad > 32) {
  38. pad = 0;
  39. }
  40. return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
  41. }
  42. /**
  43. * 将数字转化成ASCII码对应的字符,用于对明文进行补码
  44. *
  45. * @param a 需要转化的数字
  46. * @return 转化得到的字符
  47. */
  48. public static char chr(int a) {
  49. byte target = (byte) (a & 0xFF);
  50. return (char) target;
  51. }
  52. }
  1. import org.apache.commons.codec.binary.Base64;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. /**
  5. * 封装对外访问方法
  6. */
  7. public class WXCore {
  8. private static final String WATERMARK = "watermark";
  9. private static final String APPID = "appid";
  10. /**
  11. * 解密数据
  12. *
  13. * @return
  14. * @throws Exception
  15. */
  16. public static String decrypt(String appId, String encryptedData, String sessionKey, String iv) {
  17. String result = "";
  18. try {
  19. AES aes = new AES();
  20. byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey),
  21. Base64.decodeBase64(iv));
  22. if (null != resultByte && resultByte.length > 0) {
  23. result = new String(WxPKCS7Encoder.decode(resultByte));
  24. JSONObject jsonObject = JSON.parseObject(result);
  25. String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString(APPID);
  26. if (!appId.equals(decryptAppid)) {
  27. result = "";
  28. }
  29. }
  30. } catch (Exception e) {
  31. result = "";
  32. e.printStackTrace();
  33. }
  34. return result;
  35. }
  36. }

四、步骤详解:

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

  1. /**
  2. * 生命周期函数--监听页面加载
  3. */
  4. onLoad: function(options) {
  5. //获取openid
  6. wx.login({
  7. success(res) {
  8. //获取登录凭证
  9. console.log("res.conde:" + res.code)
  10. try {
  11. wx.setStorageSync('code', res.code)
  12. } catch (e) {}
  13. }
  14. })
  15. },

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

  1. getPhoneNumber(e) {
  2. console.log(e)
  3. console.log("e.detail.errMsg:" + e.detail.errMsg)
  4. console.log("e.detail.iv:" + e.detail.iv)
  5. console.log("e.detail.encryptedData:" + e.detail.encryptedData)
  6. },

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

  1. getPhoneNumber(e) {
  2. console.log(e)
  3. console.log("e.detail.errMsg:" + e.detail.errMsg)
  4. console.log("e.detail.iv:" + e.detail.iv)
  5. console.log("e.detail.encryptedData:" + e.detail.encryptedData)
  6. var code = wx.getStorageSync('code')
  7. console.log("conde:" + code)
  8. wx.request({
  9. url: 'Java后台servlet链接',
  10. method: "POST",
  11. data: {
  12. encryptedData: e.detail.encryptedData,
  13. iv: e.detail.iv,
  14. code: code,
  15. },
  16. header: {
  17. "Content-Type": "application/x-www-form-urlencoded"
  18. },
  19. success: function(data) {
  20. console.log('data:' + data.data)
  21. },
  22. fail: function() {
  23. console.log('request请求错误')
  24. },
  25. })
  26. },

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

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

  1. package servlet;
  2. import java.io.DataOutputStream;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.math.BigInteger;
  7. import java.net.Socket;
  8. import java.net.UnknownHostException;
  9. import java.security.MessageDigest;
  10. import javax.security.sasl.SaslException;
  11. import javax.servlet.ServletException;
  12. import javax.servlet.http.HttpServlet;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import okhttp3.OkHttpClient;
  16. import okhttp3.Request;
  17. import okhttp3.Response;
  18. import tools.WXCore;
  19. public class getPhoneNumberServlet extends HttpServlet {
  20. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  21. String selStr;
  22. InputStream is = null;
  23. try {
  24. is = request.getInputStream();
  25. StringBuilder sb = new StringBuilder();
  26. byte[] b = new byte[4096];
  27. for (int n; (n = is.read(b)) != -1;) {
  28. sb.append(new String(b, 0, n));
  29. }
  30. selStr = java.net.URLDecoder.decode(sb.toString(), "UTF-8");
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. return;
  34. } finally {
  35. if (null != is) {
  36. try {
  37. is.close();
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }
  43. System.out.println("selStr:" + selStr);
  44. String encryptedData = selStr.substring(selStr.lastIndexOf("encryptedData=") + 14, selStr.lastIndexOf("&iv="));
  45. System.out.println("encryptedData:" + encryptedData);
  46. String iv = selStr.substring(selStr.lastIndexOf("iv=") + 3, selStr.lastIndexOf("&code="));
  47. System.out.println("iv:" + iv);
  48. String code = selStr.substring(selStr.lastIndexOf("code=") + 5);
  49. System.out.println("code:" + code);
  50. }
  51. public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  52. doGet(request, response);
  53. }
  54. }

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

  1. package servlet;
  2. import java.io.DataOutputStream;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.math.BigInteger;
  7. import java.net.Socket;
  8. import java.net.UnknownHostException;
  9. import java.security.MessageDigest;
  10. import javax.security.sasl.SaslException;
  11. import javax.servlet.ServletException;
  12. import javax.servlet.http.HttpServlet;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import okhttp3.OkHttpClient;
  16. import okhttp3.Request;
  17. import okhttp3.Response;
  18. import tools.WXCore;
  19. public class getPhoneNumberServlet extends HttpServlet {
  20. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  21. String selStr;
  22. InputStream is = null;
  23. try {
  24. is = request.getInputStream();
  25. StringBuilder sb = new StringBuilder();
  26. byte[] b = new byte[4096];
  27. for (int n; (n = is.read(b)) != -1;) {
  28. sb.append(new String(b, 0, n));
  29. }
  30. selStr = java.net.URLDecoder.decode(sb.toString(), "UTF-8");
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. return;
  34. } finally {
  35. if (null != is) {
  36. try {
  37. is.close();
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }
  43. System.out.println("selStr:" + selStr);
  44. String encryptedData = selStr.substring(selStr.lastIndexOf("encryptedData=") + 14, selStr.lastIndexOf("&iv="));
  45. System.out.println("encryptedData:" + encryptedData);
  46. String iv = selStr.substring(selStr.lastIndexOf("iv=") + 3, selStr.lastIndexOf("&code="));
  47. System.out.println("iv:" + iv);
  48. String code = selStr.substring(selStr.lastIndexOf("code=") + 5);
  49. System.out.println("code:" + code);
  50. OkHttpClient client = new OkHttpClient();
  51. Request okrequest = new Request.Builder()
  52. .url("https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code")
  53. .build();
  54. try {
  55. Response okresponse = client.newCall(okrequest).execute();
  56. String responsedata = okresponse.body().string();
  57. System.out.println("responsedata:" + responsedata);
  58. String openid = responsedata.substring(responsedata.lastIndexOf(":") + 2,
  59. responsedata.lastIndexOf("\""));
  60. String session_key = responsedata.substring(responsedata.indexOf(":") + 2,
  61. responsedata.indexOf("==") + 2);
  62. System.out.println("原始的openid:" + openid);
  63. System.out.println("原始的session_key:" + session_key);
  64. } catch (IOException e) {
  65. e.printStackTrace();
  66. }
  67. }
  68. public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  69. doGet(request, response);
  70. }
  71. }

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

  1. package servlet;
  2. import java.io.DataOutputStream;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.math.BigInteger;
  7. import java.net.Socket;
  8. import java.net.UnknownHostException;
  9. import java.security.MessageDigest;
  10. import javax.security.sasl.SaslException;
  11. import javax.servlet.ServletException;
  12. import javax.servlet.http.HttpServlet;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import okhttp3.OkHttpClient;
  16. import okhttp3.Request;
  17. import okhttp3.Response;
  18. import tools.WXCore;
  19. public class getPhoneNumberServlet extends HttpServlet {
  20. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  21. String selStr;
  22. InputStream is = null;
  23. try {
  24. is = request.getInputStream();
  25. StringBuilder sb = new StringBuilder();
  26. byte[] b = new byte[4096];
  27. for (int n; (n = is.read(b)) != -1;) {
  28. sb.append(new String(b, 0, n));
  29. }
  30. selStr = java.net.URLDecoder.decode(sb.toString(), "UTF-8");
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. return;
  34. } finally {
  35. if (null != is) {
  36. try {
  37. is.close();
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }
  43. System.out.println("selStr:" + selStr);
  44. String encryptedData = selStr.substring(selStr.lastIndexOf("encryptedData=") + 14, selStr.lastIndexOf("&iv="));
  45. System.out.println("encryptedData:" + encryptedData);
  46. String iv = selStr.substring(selStr.lastIndexOf("iv=") + 3, selStr.lastIndexOf("&code="));
  47. System.out.println("iv:" + iv);
  48. String code = selStr.substring(selStr.lastIndexOf("code=") + 5);
  49. System.out.println("code:" + code);
  50. OkHttpClient client = new OkHttpClient();
  51. Request okrequest = new Request.Builder()
  52. .url("https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code")
  53. .build();
  54. try {
  55. Response okresponse = client.newCall(okrequest).execute();
  56. String responsedata = okresponse.body().string();
  57. System.out.println("responsedata:" + responsedata);
  58. String openid = responsedata.substring(responsedata.lastIndexOf(":") + 2,
  59. responsedata.lastIndexOf("\""));
  60. String session_key = responsedata.substring(responsedata.indexOf(":") + 2,
  61. responsedata.indexOf("==") + 2);
  62. System.out.println("原始的openid:" + openid);
  63. System.out.println("原始的session_key:" + session_key);
  64. String appId = "wx7xxxxxxxxxxxxxxxxxxxx";
  65. WXCore wxcore = new WXCore();
  66. String phonenumber = wxcore.decrypt(appId, encryptedData, responsedata_session_key, iv);
  67. System.out.println("手机号码:" + phonenumber);
  68. response.getWriter().write(openid + "&" + phonenumber);
  69. } catch (IOException e) {
  70. e.printStackTrace();
  71. }
  72. }
  73. public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  74. doGet(request, response);
  75. }
  76. }

4、大功告成。

五、运行效果截图:

六、结语

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

如有疑问或项目开发合作,欢迎私信交流

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/284629
推荐阅读
相关标签
  

闽ICP备14008679号