微信小程序通过Java后台获取openid

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pomo16/article/details/88252677

写在前面

Client: 微信小程序

Server: Java Servlet running on local Tomcat 9.0

Tools: 微信开发者工具 && Eclipse

获取思路

参考试水微信小程序与Java后台通信一文,我们可以快速建立起小程序与 Java 后台之间的通信。而获取 openid 之前,我们首先要知道微信小程序官方如何定义 openid 的工作机制。参考微信小程序公众平台的开发文档:小程序登录,可以得知 openid 的工作机制主要为下图所示:

由此可以得知小程序若想在后台获取到 openid 就必须在前端发送一个临时生成的 code 到 Java 后台,然后 Java 后台使用 code 向微信相关 API 请求并获得 session_key 以及 openid。请求的 API 为:

https://api.weixin.qq.com/sns/jscode2session?appid=xxx&secret=xxx&js_code=xxx&grant_type=authorization_code

其中 appid 和 secret 秘钥需要在开发者平台的开发设置中获取,且 secret 秘钥不会明文保存,生成后记得保存下来,否则如果忘记需要重新生成。js_code 则是小程序传回的临时 code。

小程序端

小程序端制作一个简单的测试界面,并在 js 中向后台发送生成的 code:

//app.js
App({
  globalData: {
    userInfo: null
  }
})
<!--index.wxml-->
<view>
  <view class="userinfo">
    <block wx:if="{{!hasUserInfo && canIUse}}">
      <image class="userinfo-avatar" src="{{usernoneSrc}}" mode="cover"></image>
      <button open-type="getUserInfo" bindgetuserinfo="getUserInfo" style='margin-bottom:50rpx' bindtap="login"> 点击授权 </button>
    </block>
    <block wx:else>
      <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="vipText">
    <block wx:if="{{vipFlag}}">
      <text style='color:orange;border:1px solid orange;border-radius:25%;'>vip</text>
    </block>
    <block wx:else>
      <text style='color:#eee;border:1px solid #eee;border-radius: 25%;'>vip</text>
    </block>
  </view>
</view>
.userinfo {
  display: flex;
  flex-direction: column;
  align-items: center;
  border-bottom: 2px solid #eee;
}

.userinfo-avatar {
  width: 200rpx;
  height: 200rpx;
  margin: 50rpx;
  border-radius: 50%;
  border: 1px solid #eee;
}

.userinfo-nickname {
  color: #aaa;
  font-size: 60rpx;
  margin-bottom: 50rpx;
}

.vipText {
  width: 100%;
  text-align: center;
  margin-top: 50rpx;
}
const app = getApp()

Page({
  data: {
    userInfo: {},
    usernoneSrc: "/images/user.png",
    //vipFlag: true,
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //登录获取code
  login: function () {
    wx.login({
      success: function (res) {
        //发送请求
        wx.request({
          url: 'http://localhost:8080/smallAPP/ConnectTest', //接口地址
          data: { code: res.code },
          header: {
            'content-type': 'application/x-www-form-urlencoded'
          },
          success: function (res) {
            console.log(res.data);
          },
          fail: function (res) {
            console.log("Fail to connect...");
          }
        })
      }
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse) {
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function (e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  }
})

界面如下:

Server

lib

除了试水微信小程序与Java后台通信一文中的 json 相关包,我们还需要导入一个用于进行 Http 请求的 Apache 的工具:HttpClient。该工具本来位于 Apache 的 Commons 项目中,但是后来置于 Apache 的 HttpComponents 项目中了,具体说明详见 Apache Commons 以及 Jakarta Commons HttpClient

Download HttpClient

Servlet

package com.smallAPP.common;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import net.sf.json.JSONObject;

@WebServlet("/ConnectTest")
public class ConnectTest extends HttpServlet {
	private static final long serialVersionUID = 1L;
    public ConnectTest() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {//设置请求编码
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        
        String code = request.getParameter("code");
        System.out.println(code);
        
        String appSecret = "对应secret秘钥";
        String appId = "对应APPID";
        
        if (code != null) {
            //获取openid和access_token的连接
            String getOpenIdUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId +"&secret=" + appSecret + "&js_code=" + code +"&grant_type=authorization_code";
            System.out.println(getOpenIdUrl);
            //获取返回的code
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(getOpenIdUrl);
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            //向微信发送请求并获取response
            String responseBody = httpClient.execute(httpGet,responseHandler);
            System.out.println("=========================获取token===================");
            System.out.println(responseBody);
            JSONObject jsonObject = JSONObject.fromObject(responseBody);
            System.out.println(jsonObject.toString());
        }
        
        //转成json数据
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("data", code);
        result.put("msg", "后台已收到");
        JSONObject object = JSONObject.fromObject(result);
        PrintWriter out = response.getWriter();
		out.print(object.toString());
		out.close();
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

测试

在小程序界面点击绑定了发送 code 代码的按钮后,小程序端获取授权以及用户头像等基本信息,如下图:

此时观察后台的结果,看是否获取到 openid:

如上图所示已经成功获取了 openid。

一些坑

  • HttpClient 这个工具包已经换位置了。
  • 如果请求返回有错误,请检查请求的 API 一万遍!因为比较长,很容易拼错。
展开阅读全文

没有更多推荐了,返回首页