一、controller调用
/**
* 登录
*
* @author jiaketao
* @since 2024-04-10
*/
@RestController
@RequestMapping("/login")
public class LoginController {
/**
* 【小程序】登录获取session_key和openid
*
* @param code 前端传code
* @return
*/
@GetMapping("/getWXSessionKey")
public 自己的业务返回体 getWXSessionKey(String code) {
//根据前端传来的code,调用微信的接口获取到当前用户的openid
JSONObject jsonObject = WeChatLoginUtils.getWXSessionKey(code);
String openId = jsonObject.getString("openid");
//自己的业务逻辑... }
/**
* 【小程序】获取手机号
*
* @param code 第二次的code
* @return
*/
@GetMapping("/getWXPhoneInfo")
public String getWXPhoneInfo(String code) throws IOException {
return WeChatLoginUtils.getWXPhoneInfo(code).getJSONObject("phone_info").getString("phoneNumber");
}
}
二、封装的工具类
1、微信登录核心工具类:WeChatLoginUtils
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
/**
* 微信小程序登录工具类
*
* @author jiaketao
* @since 2024-04-10
*/
public class WeChatLoginUtils {
/**
* 1.获取session_key
*
* @param code 微信小程序的第一个code
* @return
*/
public static JSONObject getWXSessionKey(String code) {
String urlResult = HttpRequestUrlUtil.httpGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + WxConstUtils.WX_OPEN_APPLET_APPID + "&secret=" + WxConstUtils.WX_OPEN_APPLET_SECRET + "&js_code=" + code + "&grant_type=authorization_code");
// 转为json
JSONObject jsonObject = JSON.parseObject(urlResult);
return jsonObject;
}
/**
* 2.获取access_token
*
* @return
*/
public static JSONObject getWXAccessToken() {
String urlResult = HttpRequestUrlUtil.httpGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + WxConstUtils.WX_OPEN_APPLET_APPID + "&secret=" + WxConstUtils.WX_OPEN_APPLET_SECRET);
// 转为json
JSONObject jsonObject = JSON.parseObject(urlResult);
return jsonObject;
}
/**
* 获取手机号
*
* @param code 微信小程序的第2个code
* @return
*/
public static JSONObject getWXPhoneInfo(String code) throws IOException {
// 调用 2.获取access_token
String access_token = getWXAccessToken().getString("access_token");
String getPhoneNumberUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + access_token;
JSONObject json = new JSONObject();
json.put("code", code);
// post请求
json = HttpRequestUrlUtil.postResponse(getPhoneNumberUrl, json);
return json;
}
}
2、配置文件:WxConstUtils
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 微信登录支付相关字段工具类
*
* @author zhaoyan
* @since 2024-04-10
*/
@Component
public class WxConstUtils implements InitializingBean {
// 小程序 appid
public static String WX_OPEN_APPLET_APPID;
// 小程序 secret密钥
public static String WX_OPEN_APPLET_SECRET;
// 商户号
public static String WX_OPEN_MCHID;
// 密钥key
public static String WX_OPEN_KEY;
//从配置文件获取以上内容的配置值
// 小程序appid
@Value("${wx.open.applet.app_id}")
private String appletAppId;
//小程序 secret密钥
@Value("${wx.open.applet.secret}")
private String appletSecret;
// 商户号
@Value("${wx.open.mch_id}")
private String mchId;
// 密钥key
@Value("${wx.open_key}")
private String key;
@Override
public void afterPropertiesSet() throws Exception {
WX_OPEN_APPLET_APPID = appletAppId;
WX_OPEN_APPLET_SECRET = appletSecret;
WX_OPEN_MCHID = mchId;
WX_OPEN_KEY = key;
}
}
3、http请求工具类:HttpRequestUrlUtil
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* http请求
*
* @author jiaketao
* @since 2024-04-10
*/
public class HttpRequestUrlUtil {
/**
* post请求
*
* @param url
* @param object
* @return
*/
public static String httpPost(String url, JSONObject object) {
String result = "";
// 使用CloseableHttpClient和CloseableHttpResponse保证httpcient被关闭
CloseableHttpClient httpClient;
CloseableHttpResponse response;
HttpPost httpPost;
UrlEncodedFormEntity entity;
try {
httpClient = HttpClients.custom().build();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
Set<String> keySets = object.keySet();
Iterator<String> keys = keySets.iterator();
while (keys.hasNext()) {
String key = keys.next();
nameValuePairs.add(new BasicNameValuePair(key, object.getString(key)));
}
entity = new UrlEncodedFormEntity(nameValuePairs, "utf-8");
httpPost = new HttpPost(url);
httpPost.setEntity(entity);
//设置超时时间
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000).build();
httpPost.setConfig(requestConfig);
response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
result = EntityUtils.toString(response.getEntity());
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
} catch (Exception e) {
} finally {
}
return result;
}
/**
* get请求
*
* @param url
* @return
*/
public static String httpGet(String url) {
String result = "";
// 使用CloseableHttpClient和CloseableHttpResponse保证httpcient被关闭
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.custom().build();
response = httpClient.execute(new HttpGet(url));
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
result = EntityUtils.toString(response.getEntity());
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
} catch (Exception e) {
} finally {
}
return result;
}
/**
* post请求封装 参数为?a=1&b=2&c=3
*
* @param path 接口地址
* @param Info 参数
* @return
* @throws IOException
*/
public static JSONObject postResponse(String path, String Info) throws IOException {
//1, 得到URL对象
URL url = new URL(path);
//2, 打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//3, 设置提交类型
conn.setRequestMethod("POST");
//4, 设置允许写出数据,默认是不允许 false
conn.setDoOutput(true);
conn.setDoInput(true);//当前的连接可以从服务器读取内容, 默认是true
//5, 获取向服务器写出数据的流
OutputStream os = conn.getOutputStream();
//参数是键值队 , 不以"?"开始
os.write(Info.getBytes());
//os.write("googleTokenKey=&username=admin&password=5df5c29ae86331e1b5b526ad90d767e4".getBytes());
os.flush();
//6, 获取响应的数据
//得到服务器写回的响应数据
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
String str = br.readLine();
JSONObject json = JSONObject.parseObject(str);
System.out.println("响应内容为: " + json);
return json;
}
/**
* post请求封装 参数为{"a":1,"b":2,"c":3}
*
* @param path 接口地址
* @param Info 参数
* @return
* @throws IOException
*/
public static JSONObject postResponse(String path, JSONObject Info) throws IOException {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(path);
post.setHeader("Content-Type", "application/json");
post.addHeader("Authorization", "Basic YWRtaW46");
String result = "";
try {
StringEntity s = new StringEntity(Info.toString(), "utf-8");
s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(s);
// 发送请求
HttpResponse httpResponse = client.execute(post);
// 获取响应输入流
InputStream inStream = httpResponse.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
strber.append(line + "\n");
inStream.close();
result = strber.toString();
System.out.println(result);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
System.out.println("请求服务器成功,做相应处理");
} else {
System.out.println("请求服务端失败");
}
} catch (Exception e) {
System.out.println("请求异常");
throw new RuntimeException(e);
}
return JSONObject.parseObject(result);
}
}
三、maven依赖:pom.xml
<!-- 导入Json格式化依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- 导入Apache HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<!-- Spring Boot Starter (包含 Spring Core, Spring Beans, Spring Context 等) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.18</version> <!-- 或使用最新版本 -->
</dependency>
<!-- 如果需要 @Value 注解读取配置文件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-config</artifactId>
<version>2.7.18</version>
</dependency>
四、配置文件:application.properties
#wechat Config
wx.open.applet.app_id=自己的appid
wx.open.applet.secret=自己的secret密钥
#wx.open.applet.sub_app_id=
wx.open.mch_id=
wx.open_key=
wx.open.sub_mch_id=