Spring后端HttpClient实现微信小程序登录

这是微信官方提供的时序图。我们需要关注的是前后端的交互,以及服务端如何收发网络请求。

小程序端

封装基本网络请求

我们先封装一个基本的网络请求。

javascript 复制代码
const baseUrl="localhost:8080"
export default{
  sendRequsetAsync
}
/* e
url:目标页面,带斜杠:/user
method:方法,默认GET
data:json格式的数据
*/
async function sendRequsetAsync(e) {
  let response
  console.log("发送异步网络请求")
  console.log(e)
  let promise = await new Promise((resolve, reject) => {
    wx.request({
      url: baseUrl + e.url,
      method: e.method || "GET",
      data: e.data || {},
      success: (res) => {
        resolve(res)
      },
      fail: (error) => {
        reject(error)
      }
    })
  })
  console.log(promise);
  return promise
}

指定baseUrl为本地8080端口。之后所有的小程序网络请求都基于这个方法。

这样当服务端地址变更时,只需要修改这里的baseUrl,而不需要对每个涉及网络请求的js文件都作修改。

使用promise获取服务端返回的数据。直接接受wx.request()的返回值,得到的是一个网络请求任务对象。

赋值采用的是JS特有的括号()方法。如果用等号可能会赋值失败。

如果没有await,创建对象直接直接输出,得到的是一个promise对象。

这是因为promise是一个异步请求对象。在执行结束前,设计的数据会随时变动。

如果要等待异步请求结束,查看最终结算,则需要加上await

方法内使用await的前提是方法外使用async

实现小程序登录

我们已经封装了基本的网络请求,根据微信官方提供的时序图,我们接下来需要获取用户登录授权码code

调用wx.login()方法可以直接获取:

wx.login()会弹出提示请求用户授权,这也是一个异步请求,如果要等接收到用户反馈之后再执行下一步操作,也需要添加await

javascript 复制代码
let loginResultLocal = await wx.login()
console.log(loginResultLocal)
if (loginResultLocal.errMsg == "login:ok") {//本地请求登录,获取code
  let loginResultServer = await loginByCode(loginResultLocal.code)//尝试通过code登陆
  if (loginResultServer.state == 0) {//用户未注册
    console.log("用户未注册")
  } else if (loginResultServer.state == 1) {//用户已注册
    console.log("用户已注册");
  }
} else {//如果用户不同意登录,跳转到拒绝服务页面,直到同意
  wx.reLaunch({
    url: '/pages/user/userRegister/userRegister'
  })
}

当然,这段代码也需要封装进工具类中,也需要调用之前封装好的其他工具类。

导入其他工具类只需要这一行代码,照葫芦画瓢即可:import webRequest from "./webRequest.js";

现在已经获取到了code,也封装了基本网络请求。接下来需要实现登陆方法,将小程序端获取到的code发送到服务端,接收服务端返回的openid等信息。

现在我们还没介绍服务端的业务逻辑,无论发送什么内容,返回数据都是"收到"。

javascript 复制代码
async function loginByCode(code) {//通过code登录
  console.log("通过code登录:"+code);
  let e = {
    "url": "/user/user/login",
    "method": "POST",
    "data": {
      "loginMethod": "code",
      "code": code
    }
  }
  let requestResult = await webRequest.sendRequsetAsync(e)
  return requestResult
}

控制台输出

服务端好像收到了小程序端发送到数据,但服务端接受的实际内容、服务端的业务逻辑,我们目前还是不清楚的。

服务端

小程序端以json形式,以POST方法发送了用户凭证code
openid需要从服务端通过GET方法获取

可以得出,服务端应能够:

  • 解析json
  • 响应post方法
  • 发送get请求

解析JSON,响应POST方法

根据开发文档,我们需要提前准备好appid和secret。如果不知道在哪里,可以直接私我。

按照上面的格式添加到配置文件中。

这并没有通过全局静态常量的方式保存在类中。因为小程序信息可能会经常用到,之后也可能会发生改变,通过引用的方式,可以只修改这一处。

java 复制代码
@Value("${wechat.appid}")
private String appid;
@Value("${wechat.secret}")
private String secret;

通过@Value注解将配置文件中的值赋值给下面的字符串。

GET方法的参数暴露在Url中,可以选择用简单粗暴的字符串拼接方式发送GET请求。

服务端发送登录请求还需要code,这由小程序端通过POST请求传入。

可以提前创建实体类。

java 复制代码
public class UserLoginDTO {
    @Getter
    private String code;
}

响应POST请求通过@PostMapping注解实现

解析POST请求携带的JSON,作为函数参数传入,通过@RequestBody注解实现

HttpClient

HttpClient工具包用于在spring中发送网络请求。
https://hc.apache.org/httpcomponents-client-5.2.x/quickstart.html

发送请求步骤:

  1. 创建HttpClient对象
  2. 创建Http请求对象
  3. 调用HttpClient的execute方法发送请求
java 复制代码
//创建HttpClient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建请求对象
HttpGet httpGet = new HttpGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + appid
        + "&secret=" + secret
        + "&js_code=" + userLoginDTO.getCode()
        + "&grant_type=authorization_code");
//发送请求,接受响应结果
CloseableHttpResponse response = httpClient.execute(httpGet);        //获取服务端返回的状态码
if (response.getCode() == 200) {
    //获取服务端返回的数据
    HttpEntity entity = response.getEntity();
    String body = EntityUtils.toString(entity);
    System.out.println(body);
    //关闭资源
    response.close();
    httpClient.close();
    return body;
}

Api测试

回到小程序端。服务端返回的消息随着软件开发的完善可能会作出修改。将相关代码单独封装。

目前输出结果如下:

可以通过wx.getStorageSyncwx.setStorageSync方法把openid和会话密钥在用户本地存取。

相关推荐
从心归零6 分钟前
sshj使用代理连接服务器
java·服务器·sshj
一个诺诺前行的后端程序员40 分钟前
springcloud微服务实战<1>
spring·spring cloud·微服务
IT毕设梦工厂1 小时前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
Jiaberrr1 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
Ylucius2 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
h177113472052 小时前
单身狗的逆袭之路之开发相亲交友系统
微信小程序·小程序·交友·系统开发·回归算法
七夜zippoe2 小时前
分布式系统实战经验
java·分布式
是梦终空2 小时前
JAVA毕业设计176—基于Java+Springboot+vue3的交通旅游订票管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·源代码·交通订票
落落落sss2 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
码爸2 小时前
flink doris批量sink
java·前端·flink