当前位置: 首页 > article >正文

2025 Java 微信小程序根据code获取openid,二次code获取手机号【工具类】拿来就用

一、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,调用微信的接口获取到当前用户的openidJSONObject 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");// 转为jsonJSONObject 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);// 转为jsonJSONObject jsonObject = JSON.parseObject(urlResult);return jsonObject;}/*** 获取手机号** @param code 微信小程序的第2个code* @return*/public static JSONObject getWXPhoneInfo(String code) throws IOException {// 调用 2.获取access_tokenString 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 {// 小程序 appidpublic static String WX_OPEN_APPLET_APPID;// 小程序 secret密钥public static String WX_OPEN_APPLET_SECRET;// 商户号public static String WX_OPEN_MCHID;// 密钥keypublic 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;@Overridepublic 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, 设置允许写出数据,默认是不允许 falseconn.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=

相关文章:

2025 Java 微信小程序根据code获取openid,二次code获取手机号【工具类】拿来就用

一、controller调用 /*** 登录** author jiaketao* since 2024-04-10*/ RestController RequestMapping("/login") public class LoginController {/*** 【小程序】登录获取session_key和openid** param code 前端传code* return*/GetMapping("/getWXSessionKe…...

window 显示驱动开发-分页视频内存资源

与 Microsoft Windows 2000 显示驱动程序模型不同&#xff0c;Windows Vista 显示驱动程序模型允许创建比可用物理视频内存总量更多的视频内存资源&#xff0c;然后根据需要分页进出视频内存。 换句话说&#xff0c;并非所有视频内存资源都同时位于视频内存中。 GPU 的管道中可…...

【笔记】记一次PyCharm的问题反馈

#工作记录 最近更新至 PyCharm 社区版的最新版本后&#xff0c;我遇到了多个影响使用体验的问题。令人感到不便的是&#xff0c;一些在旧版本中非常便捷的功能&#xff0c;在新版本中却变得操作复杂、不够直观。过去&#xff0c;我一直通过 PyCharm 内置的故障报告与反馈机制反…...

uniapp中vue3和pinia安装依赖npm install失败

目录 一、问题描述 二、问题原因 三、问题解析及解决方案 一、问题描述 用uni-app开发小程序的时候&#xff0c;使用了vue3pinia,安装依赖的时候发现vue和pinia的版本问题&#xff0c;安装失败&#xff0c; npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve np…...

MySQL 8.0 OCP 1Z0-908 131-140题

Q131.You have upgraded the MySQL binaries from 5.7.28 to 8.0.18 by using an in-place upgrade. Examine the message sequence generated during the first start of MySQL 8.0.18: 。。。[System]。。。/usx/sbin/mysqld (mysqld 8.0.18-commercial) starting as process…...

Spring-messaging-Message接口/环境依赖

参考文档1&#xff1a;https://docs.spring.io/spring-integration/reference/index.html 参考文档2&#xff1a;https://www.jackssybin.cn/articles/2021/03/16/1615897840354.html#b3_solo_h4_44 环境配置 由于我使用的是spring boot&#xff0c;所以只有一个依赖&#xf…...

WPF自定义控件开发全指南:多内容切换与动画集成

WPF自定义控件开发全指南&#xff1a;多内容切换与动画集成 一、控件基础架构设计1.1 选择控件基类1.2 定义关键属性 二、动画系统集成2.1 淡入淡出动画实现2.2 滑动动画实现 三、视觉状态管理四、完整使用示例4.1 XAML声明4.2 动画触发逻辑 五、扩展与优化5.1 性能优化建议5.2…...

ECMAScript标准:JavaScript的核心

什么是ECMAScript&#xff1f; ECMAScript&#xff08;简称ES&#xff09;是一个由ECMA国际&#xff08;欧洲计算机制造商协会&#xff09;制定的脚本语言标准&#xff0c;它为JavaScript、JScript和ActionScript等脚本语言提供了基础规范。JavaScript 可以视为 ECMAScript 的…...

qtc++ qdebug日志生成

本文介绍了将qdebug注册到日志系统&#xff0c;这样qdebug打印的信息将记录在日志文本文件&#xff0c;方便观看程序运行中的历史信息&#xff0c;但是需要注意的是&#xff0c;注册后qdebug的信息将不会打印在qtcreator的输出中&#xff0c;所以作者建议&#xff0c;在开发的时…...

【分布式锁通关指南 10】源码剖析redisson之MultiLock的实现

引言 本期我们将把目光聚焦在 Redisson 中另一个颇具代表性的分布式锁实现——MultiLock。它的核心思想是&#xff1a;一次性对多个独立的 RLock 进行加锁或解锁操作&#xff0c;只有当多个锁都成功加锁时才算真正完成锁的获取&#xff0c;一旦有任何一个失败&#xff0c;整体操…...

DBF Converter:高效转换DBF文件,满足多样化数据处理需求

DBF Converter 是一款功能强大的数据转换工具&#xff0c;专为需要将DBF文件转换为其他格式的用户设计。它支持将DBF文件转换为CSV、Excel、HTML、SQL等多种常见格式&#xff0c;满足用户在不同场景下的数据处理需求。无论是数据迁移、报表生成还是日常数据处理&#xff0c;DBF…...

Java—— 方法引用 : :

方法引用是什么 把已经存在的方法拿过来用&#xff0c;当做函数式接口中抽象方法的方法体 方法引用符 &#xff1a;&#xff1a; 方法引用的条件 1.需要有函数式接口 2.被引用方法必须已经存在 3.被引用方法的形参和返回值需要跟抽象方法保持一致 4.被引用方法的功能要满足当前…...

Jmeter 安装包与界面汉化

Jmeter 安装包&#xff1a; 通过网盘分享的文件&#xff1a;CSDN-apache-jmeter-5.5 链接: https://pan.baidu.com/s/17gK98NxS19oKmkdRhGepBA?pwd1234 提取码: 1234 Jmeter界面汉化&#xff1a;...

6 任务路由与负载均衡

一、任务路由核心机制 1.1 静态路由配置 # celeryconfig.pytask_routes {# 精确匹配任务路径payment.process_order: {queue: priority_payment},# 通配符匹配任务类型report.*: {queue: low_priority_reports},# 正则表达式匹配re.compile(r^video\.(encode|compress)): {q…...

【C++】 —— 笔试刷题day_29

一、排序子序列 题目解析 一个数组的连续子序列&#xff0c;如果这个子序列是非递增或者非递减的&#xff1b;这个连续的子序列就是排序子序列。 现在给定一个数组&#xff0c;然后然我们判断这个子序列可以划分成多少个排序子序列。 例如&#xff1a;1 2 3 2 2 1 可以划分成 …...

Ruby 循环与迭代器

Ruby 循环与迭代器 循环迭代器timesuptostep 循环 。。。。 迭代器 迭代器本质上可以理解为是循环的一种类型 times 3.times do print "Ho! " end begin Ho! Ho! Ho! end上述代码表示我们对当前 block 部分中的内容循环三次。最终&#xff0c;我们打印出了三个…...

力扣-39.组合总和

题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被…...

优化 Element UI 表格样式,隐藏滚动条但保持滚动功能

优化 Element UI 表格样式&#xff0c;隐藏滚动条但保持滚动功能 前言 在基于 Element UI 的项目中&#xff0c;el-table 是非常常用的表格组件。默认情况下&#xff0c;表格的滚动条可能影响页面的美观&#xff0c;特别是在视觉设计上希望更简洁时。本文分享一段优化的 CSS …...

线程池(ThreadPoolExecutor)实现原理和源码细节是Java高并发面试和实战开发的重点

一、线程池核心流程图 ----------------- | 提交任务 | submit/execute -----------------|v ----------------- | 判断核心线程数 | < corePoolSize&#xff1f; -----------------|Yes |Nov v [创建新线程] -----------------| 队列是否满&a…...

MongoTemplate 基础使用帮助手册

前言 MongoDB 是一种流行的 NoSQL 数据库&#xff0c;适合存储大量的非结构化数据。MongoTemplate 是 Spring Data MongoDB 中的一个核心组件&#xff0c;它提供了一组丰富的 API 来与 MongoDB 进行交互。它封装了许多常见的数据库操作&#xff0c;使开发者能够轻松执行 CRUD 操…...

图像处理:预览并绘制图像细节

前言 因为最近在搞毕业论文的事情&#xff0c;要做出一下图像细节对比图&#xff0c;所以我这里写了两个脚本&#xff0c;一个用于框选并同时预览图像放大细节&#xff0c;可显示并返回框选图像的坐标&#xff0c;另外一个是输入框选图像的坐标并将放大的细节放置在图像中&…...

力扣热题——最长相邻不相等子序列 |

题目要求从字符串数组 words 中选出一个最长的子序列&#xff0c;使得该子序列中相邻字符串对应的 groups 数组中的值不同。通过贪心算法&#xff0c;可以高效地解决该问题。具体步骤为&#xff1a;初始化一个结果列表&#xff0c;遍历 words 数组&#xff0c;检查当前字符串的…...

【抽丝剥茧知识讲解】引入mybtis-plus后,mapper实现方式

目录 前言一、传统 Mapper 接口方式二、继承 BaseMapper 的方式三、自定义通用 Mapper 的方式四、使用 MyBatis-Plus 的 ActiveRecord 模式五、使用 MyBatis-Plus 的 IService 接口六、使用建议 前言 mapper文件&#xff0c;作为Mybatis框架中定义SQL语句和映射关系的配置文件&…...

ssti刷刷刷

[NewStarCTF 公开赛赛道]BabySSTI_One 测试发现过滤关键字&#xff0c;但是特殊符号中括号、双引号、点都能用 可以考虑拼接或者编码&#xff0c;这里使用拼接 ?name{{()["__cla"~"ss__"]}}?name{{()["__cla"~"ss__"]["__ba&…...

java+selenum专题(一)

环境搭建部署篇-> 1.简介 java版的selenium&#xff0c;介绍一下java selenium自动化测试。大致和pythonselenium自动化测试差不多。基于java和selenium做自动化测试&#xff0c;因此你必须会搭建基本的开发环境&#xff0c;掌握python基本的语法和一个IDE来进行开发&…...

物体雅克比、空间雅克比、解析雅克比、几何雅克比

在机器人学中&#xff0c;雅可比矩阵是连接广义坐标速度与末端执行器速度的关键工具。根据应用场景和参考系的不同&#xff0c;雅可比矩阵可分为物体雅可比&#xff08;Body Jacobian&#xff09;、空间雅可比&#xff08;Space Jacobian&#xff09;、解析雅可比&#xff08;A…...

[逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五)

[逆向工程]DebugView捕获WPS日志&#xff1f;解析未运行WPS时Shell扩展加载的原因与解决方案&#xff08;二十五&#xff09; 引言&#xff1a;一个“幽灵”般的日志问题 你是否在使用 DebugView 排查系统问题时&#xff0c;发现日志中频繁出现 WPS 相关模块&#xff08;如 k…...

ACM模式用Scanner和System.out超时的解决方案和原理

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;笔试强训 &#x1f4da;本系列文章为个人学…...

Java注解详解:从入门到实战应用篇

1. 引言 Java注解&#xff08;Annotation&#xff09;是JDK 5.0引入的一种元数据机制&#xff0c;用于为代码提供附加信息。它广泛应用于框架开发、代码生成、编译检查等领域。本文将从基础到实战&#xff0c;全面解析Java注解的核心概念和使用场景。 2. 注解基础概念 2.1 什…...

QML 属性动画、行为动画与预定义动画

目录 引言相关阅读本文使用的动画属性工程结构示例解析示例1&#xff1a;属性动画应用示例2&#xff1a;行为动画实现示例3&#xff1a;预定义动画 总结工程下载 引言 QML动画系统为界面元素提供了流畅的过渡效果。本文通过三个示例&#xff0c;结合属性动画(PropertyAnimatio…...