- 后端接口入參:
- code :臨時登錄憑證(必傳)
- encryptedData:密文
- iv:偏移量
- 控制層接口:

1 @Action(value = "findWx") 2 public void findWx() throws IOException { 3 System.out.println("開始"); 4 //小程序返回登錄相關信息(自定義返回給小程序的信息) 5 RequestWxAppMsg msg = new RequestWxAppMsg(); 6 msg.setCode(AppActionResultCode.CODE_FAILURE); 7 System.out.println("wxcode:" + code); 8 System.out.println("encryptedData:" + encryptedData); 9 System.out.println("iv:" + iv); 10 /*======================================================*/ 11 //登錄憑證不能為空 12 if (code == null || code.length() == 0) { 13 msg.setCode(AppActionResultCode.CODE_FAILURE); 14 System.out.println("登錄憑證不能為空"); 15 } 16 //小程序唯一標識 (在微信小程序管理后台獲取) 17 String wxspAppid = "***************"; 18 //小程序的 app secret (在微信小程序管理后台獲取) 19 String wxspSecret = "***************"; 20 //授權(必填) 21 String grant_type = code; 22 /*========1、向微信服務器 使用登錄憑證 code 獲取 session_key 和 openid=========*/ 23 //請求參數 24 String params = "appid=" + wxspAppid + "&secret=" + wxspSecret + "&js_code=" + code + "&grant_type=" + grant_type; 25 //發送請求 26 String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", params); 27 //解析相應內容(轉換成json對象) 28 JSONObject json = JSONObject.fromObject(sr); 29 //獲取會話密鑰(session_key) 30 String session_key = json.get("session_key").toString(); 31 //用戶的唯一標識(openid) 32 String openid = (String) json.get("openid"); 33 //返回的數據 34 msg.setOpenId(openid); 35 System.out.println("請求成功獲取openId以及會話密鑰(如果不需要unionId以及手機號此刻可以直接結束返回openId)"); 36 /*=========2、對encryptedData加密數據進行AES解密(unionId)========================*/ 37 try { 38 String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8"); 39 System.out.println("解密結果:"+result); 40 if (null != result && result.length() > 0) { 41 JSONObject userInfoJSON = JSONObject.fromObject(result); 42 //返回的數據 43 msg.setUnionId((String) userInfoJSON.get("unionId")); 44 msg.setCode(AppActionResultCode.CODE_SUCCESS); 45 } 46 } catch (Exception e) { 47 e.printStackTrace(); 48 } 49 /*=========2、對encryptedData加密數據進行AES解密(phone)========================*/ 50 try { 51 String phone = AuthLoginUtil.getPhone(encryptedData,session_key,iv); 52 if(!phone.equals("")){ 53 msg.setPhone(phone); 54 } 55 } catch (InvalidAlgorithmParameterException e) { 56 // TODO Auto-generated catch block 57 e.printStackTrace(); 58 } 59 doOutput(msg); 60 }
- 發送請求的工具類HttpRequest:

1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStreamReader; 4 import java.io.PrintWriter; 5 import java.net.URL; 6 import java.net.URLConnection; 7 import java.util.List; 8 import java.util.Map; 9 10 public class HttpRequest{ 11 public static void main(String[] args) { 12 //發送 GET 請求 13 String s=HttpRequest.sendGet("http://v.qq.com/x/cover/kvehb7okfxqstmc.html?vid=e01957zem6o", ""); 14 System.out.println(s); 15 //發送 POST 請求 16 //String sr=HttpRequest.sendPost("http://www.toutiao.com/stream/widget/local_weather/data/?city=%E4%B8%8A%E6%B5%B7", ""); 17 //JSONObject json = JSONObject.fromObject(sr); 18 //System.out.println(json.get("data")); 19 } 20 /** 21 * 向指定URL發送GET方法的請求 22 * 23 * @param url 24 * 發送請求的URL 25 * @param param 26 * 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。 27 * @return URL 所代表遠程資源的響應結果 28 */ 29 public static String sendGet(String url, String param) { 30 String result = ""; 31 BufferedReader in = null; 32 try { 33 String urlNameString = url + "?" + param; 34 URL realUrl = new URL(urlNameString); 35 // 打開和URL之間的連接 36 URLConnection connection = realUrl.openConnection(); 37 // 設置通用的請求屬性 38 connection.setRequestProperty("accept", "*/*"); 39 connection.setRequestProperty("connection", "Keep-Alive"); 40 connection.setRequestProperty("user-agent", 41 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 42 // 建立實際的連接 43 connection.connect(); 44 // 獲取所有響應頭字段 45 Map<String, List<String>> map = connection.getHeaderFields(); 46 // 遍歷所有的響應頭字段 47 for (String key : map.keySet()) { 48 System.out.println(key + "--->" + map.get(key)); 49 } 50 // 定義 BufferedReader輸入流來讀取URL的響應 51 in = new BufferedReader(new InputStreamReader( 52 connection.getInputStream())); 53 String line; 54 while ((line = in.readLine()) != null) { 55 result += line; 56 } 57 } catch (Exception e) { 58 System.out.println("發送GET請求出現異常!" + e); 59 e.printStackTrace(); 60 } 61 // 使用finally塊來關閉輸入流 62 finally { 63 try { 64 if (in != null) { 65 in.close(); 66 } 67 } catch (Exception e2) { 68 e2.printStackTrace(); 69 } 70 } 71 return result; 72 } 73 74 /** 75 * 向指定 URL 發送POST方法的請求 76 * 77 * @param url 78 * 發送請求的 URL 79 * @param param 80 * 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。 81 * @return 所代表遠程資源的響應結果 82 */ 83 public static String sendPost(String url, String param) { 84 PrintWriter out = null; 85 BufferedReader in = null; 86 String result = ""; 87 try { 88 URL realUrl = new URL(url); 89 // 打開和URL之間的連接 90 URLConnection conn = realUrl.openConnection(); 91 // 設置通用的請求屬性 92 conn.setRequestProperty("accept", "*/*"); 93 conn.setRequestProperty("connection", "Keep-Alive"); 94 conn.setRequestProperty("user-agent", 95 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 96 // 發送POST請求必須設置如下兩行 97 conn.setDoOutput(true); 98 conn.setDoInput(true); 99 // 獲取URLConnection對象對應的輸出流 100 out = new PrintWriter(conn.getOutputStream()); 101 // 發送請求參數 102 out.print(param); 103 // flush輸出流的緩沖 104 out.flush(); 105 // 定義BufferedReader輸入流來讀取URL的響應 106 in = new BufferedReader( 107 new InputStreamReader(conn.getInputStream())); 108 String line; 109 while ((line = in.readLine()) != null) { 110 result += line; 111 } 112 } catch (Exception e) { 113 System.out.println("發送 POST 請求出現異常!"+e); 114 e.printStackTrace(); 115 } 116 //使用finally塊來關閉輸出流、輸入流 117 finally{ 118 try{ 119 if(out!=null){ 120 out.close(); 121 } 122 if(in!=null){ 123 in.close(); 124 } 125 } 126 catch(IOException ex){ 127 ex.printStackTrace(); 128 } 129 } 130 return result; 131 } 132 }
- 解密unionId的工具類AesCbcUtil:

1 import org.apache.commons.codec.binary.Base64; 2 import org.bouncycastle.jce.provider.BouncyCastleProvider; 3 import javax.crypto.BadPaddingException; 4 import javax.crypto.Cipher; 5 import javax.crypto.IllegalBlockSizeException; 6 import javax.crypto.NoSuchPaddingException; 7 import javax.crypto.spec.IvParameterSpec; 8 import javax.crypto.spec.SecretKeySpec; 9 import java.io.UnsupportedEncodingException; 10 import java.security.*; 11 import java.security.spec.InvalidParameterSpecException; 12 13 public class AesCbcUtil { 14 15 static { 16 Security.addProvider(new BouncyCastleProvider()); 17 } 18 19 /** 20 * AES解密 21 * 22 * @param data //密文,被加密的數據 23 * @param key //秘鑰 24 * @param iv //偏移量 25 * @param encodingFormat //解密后的結果需要進行的編碼 26 * @return 27 * @throws Exception 28 */ 29 public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception { 30 //被加密的數據 31 byte[] dataByte = Base64.decodeBase64(data); 32 //加密秘鑰 33 byte[] keyByte = Base64.decodeBase64(key); 34 //偏移量 35 byte[] ivByte = Base64.decodeBase64(iv); 36 try { 37 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 38 39 SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); 40 41 AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); 42 parameters.init(new IvParameterSpec(ivByte)); 43 44 cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化 45 46 byte[] resultByte = cipher.doFinal(dataByte); 47 if (null != resultByte && resultByte.length > 0) { 48 String result = new String(resultByte, encodingFormat); 49 return result; 50 } 51 return null; 52 } catch (NoSuchAlgorithmException e) { 53 e.printStackTrace(); 54 } catch (NoSuchPaddingException e) { 55 e.printStackTrace(); 56 } catch (InvalidParameterSpecException e) { 57 e.printStackTrace(); 58 } catch (InvalidKeyException e) { 59 e.printStackTrace(); 60 } catch (InvalidAlgorithmParameterException e) { 61 e.printStackTrace(); 62 } catch (IllegalBlockSizeException e) { 63 e.printStackTrace(); 64 } catch (BadPaddingException e) { 65 e.printStackTrace(); 66 } catch (UnsupportedEncodingException e) { 67 e.printStackTrace(); 68 } 69 70 return null; 71 } 72 73 }
- 解密手機號的工具類AuthLoginUtil:

1 import java.io.UnsupportedEncodingException; 2 import java.security.InvalidAlgorithmParameterException; 3 import org.apache.tomcat.util.codec.binary.Base64; 4 import com.alibaba.fastjson.JSON; 5 import com.alibaba.fastjson.JSONObject; 6 7 public class AuthLoginUtil { 8 //解密得到電話號碼 9 public static String getPhone(String encryptedData,String sessionKey,String iv) throws InvalidAlgorithmParameterException, UnsupportedEncodingException{ 10 String phone=""; 11 byte[] resultByte = AES.decrypt(Base64.decodeBase64(encryptedData), 12 Base64.decodeBase64(sessionKey), 13 Base64.decodeBase64(iv)); 14 if (null != resultByte && resultByte.length > 0) { 15 String userInfo = new String(resultByte, "UTF-8"); 16 System.out.println(userInfo); 17 JSONObject userJson =JSON.parseObject(userInfo); 18 phone = userJson.getString("phoneNumber"); 19 System.out.println("電話:"+phone); 20 //解密成功 21 System.out.println("解密成功"); 22 } else { 23 System.out.println("解密報錯"); 24 } 25 return phone; 26 } 27 }
- 參考博客:
- 注:解密手機號與unionId分別寫在2個接口中(解密的入參不同),unionId解不出來要去檢查一下你的微信開放平台(微信開放平台)是否有綁定微信小程序。