globalData.Java
public class globalData {
public String url = "https://api.weixin.qq.com/sns/jscode2session";//微信服务器接口
public String appid = "小程序的appid";
public String secret = "小程序的secret";
public String grant_type = "authorization_code";//这样写就行
}
HttpRestUtils.Java
package com.ruoyi.web.xind;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
public class HttpRestUtils {
/**
* http post
* */
public static String post(String url, MultiValueMap<String, String> params) throws IOException {
return httpRestClient(url, HttpMethod.POST, params);
}
/**
* http get
* */
public static String get(String url, MultiValueMap<String, String> params) throws IOException {
return httpRestClient(url, HttpMethod.GET, params);
}
/**
* HttpMethod post/get
* */
private static String httpRestClient(String url, HttpMethod method, MultiValueMap<String, String> params) throws IOException {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(10*1000);
requestFactory.setReadTimeout(10*1000);
RestTemplate client = new RestTemplate(requestFactory);
HttpHeaders headers = new HttpHeaders();
// 以表单的方式提交
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// headers.setContentType(MediaType.APPLICATION_JSON_UTF8);//不好使,不能用get方法
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);
// 执行HTTP请求
ResponseEntity<String> response = null;
try{
response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);
System.out.println("response="+response);
return response.getBody();
}
catch (HttpClientErrorException e){
System.out.println( "------------- 出现异常 HttpClientErrorException -------------");
System.out.println(e.getMessage());
System.out.println(e.getStatusText());
System.out.println( "-------------responseBody-------------");
System.out.println( e.getResponseBodyAsString());
e.printStackTrace();
return "";
}
catch (Exception e) {
System.out.println( "------------- HttpRestUtils.httpRestClient() 出现异常 Exception -------------");
System.out.println(e.getMessage());
return "";
}
}
}
PostData.Java
package com.ruoyi.web.xind;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
public class PostData {
public String PostData(String url ,String appid,String appSecret,String code,String authorization_code) {
try {
//post请求
HttpMethod method = HttpMethod.GET;
// 封装参数,千万不要替换为Map与HashMap,否则参数无法传递
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("appid",appid);
params.add("secret",appSecret);
params.add("js_code",code);
params.add("grant_type",authorization_code);
System.out.print("发送数据:" + params.toString()+"\n");
//发送http请求并返回结果
String result = HttpRestUtils.get(url, params);
System.out.print("接收反馈:" + result+"\n");
return result;
} catch (Exception e) {
System.out.println("------------- " + this.getClass().toString() + ".PostData() : 出现异常 Exception -------------");
System.out.println(e.getMessage());
return "";
}
}
}
ServerApplication.Java
package com.ruoyi.web.xind;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.system.domain.TWx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/weixin/getphone")
public class ServerApplication {
com.ruoyi.web.xind.globalData globalData = new globalData();
@Autowired
private TwxRepository wxRepository;
//解析电话号码
@GetMapping("/getsessionkey")
public Object getsessionkey(String js_code,String encryptedData, String iv) throws JsonProcessingException {
PostData PostData = new PostData();
String responseData = PostData.PostData(globalData.url, globalData.appid, globalData.secret,js_code,globalData.grant_type);
//获取SessionKey 和openid
ObjectMapper mapper = new ObjectMapper();
JsonNode resData = mapper.readTree(responseData);
try{
if(resData.get("session_key").asText()!=null)
{
String SessionKey = resData.get("session_key").asText();
String openid = resData.get("openid").asText();
System.out.println("SessionKey="+SessionKey);
System.out.println("openid="+openid);
System.out.println("encryptedData="+encryptedData);
System.out.println("iv="+iv);
String wxDecrypt = WechatUtils.wxDecrypt(encryptedData,SessionKey,iv);
System.out.println(wxDecrypt);
// 获取手机号,从这以下只是我想把手机号根据opeid来放到对应的用户的pone字段里面,这下面的根据自己实际需求来完成
mapper = new ObjectMapper();
JsonNode decryptedData = mapper.readTree(wxDecrypt);
String phoneNumber = decryptedData.get("phoneNumber").asText();
// 假设获取到了用户的openid
openid = resData.get("openid").asText();
// 查询或创建TWx实例
TWx wx = wxRepository.findByWxId(openid);
if (wx == null) {
wx = new TWx();
wx.setWxId(openid);
}
// 将手机号存储到TWx表的phone字段中
wx.setPhone(phoneNumber);
// 执行保存或更新操作
wxRepository.save(wx);
return wxDecrypt;
}else {
System.out.println("请求微信服务器异常");
}
}catch (Exception e)
{
System.out.println("请求微信服务器异常");
}
return 0;
}
}
WechatUtils.Java
package com.ruoyi.web.xind;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class WechatUtils {
public static final String AES = "AES";
public static final String AES_CBC_PADDING = "AES/CBC/PKCS7Padding";
/**
* * 微信 数据解密<br/>
* * 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充<br/>
* * 对称解密的目标密文:encrypted=Base64_Decode(encryptData)<br/>
* * 对称解密秘钥:key = Base64_Decode(session_key),aeskey是16字节<br/>
* * 对称解密算法初始向量:iv = Base64_Decode(iv),同样是16字节<br/>
* *
* * @param encrypted 目标密文
* * @param session_key 会话ID
* * @param iv 加密算法的初始向量
*
*/
public static String wxDecrypt(String encrypted, String session_key, String iv) {
String result = null;
byte[] encrypted64 = org.apache.commons.codec.binary.Base64.decodeBase64(encrypted);
byte[] key64 = org.apache.commons.codec.binary.Base64.decodeBase64(session_key);
byte[] iv64 = org.apache.commons.codec.binary.Base64.decodeBase64(iv);
try {
init();
result = new String(decrypt(encrypted64, key64, generateIV(iv64)));
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* * 初始化密钥
*
*/
public static void init() throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyGenerator.getInstance(AES).init(128);
}
/**
* * 生成iv
*
*/
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
// iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
// Arrays.fill(iv, (byte) 0x00);
AlgorithmParameters params = AlgorithmParameters.getInstance(AES);
params.init(new IvParameterSpec(iv));
return params;
}
/**
* * 生成解密
*
*/
public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)
throws Exception {
Key key = new SecretKeySpec(keyBytes, AES);
Cipher cipher = Cipher.getInstance(AES_CBC_PADDING);
// 设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(encryptedData);
}
}
至此就获取用户的手机号就实现了,至于前端就让他自己根据官方来传值,就可以获取到用户的手机号,获取用户的东西在 wxDecrypt,以下就是成功后的展示
![](https://i-blog.csdnimg.cn/blog_migrate/ea2375f6bc99f4f5504e0eb2c901483b.png)