本文主要介绍部分功能的代码实现,在此之前需认真阅读微信公众平台技术文档之微信网页授权
该工具类包括功能如下:
需要注意的是,此时获取到的access_token与另一篇文章(微信公众号开发----获取access_token,定时刷新access_token)中的获取的access_token是不一样的
关于网页授权access_token和普通access_token的区别
微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。
一、相关jar包
FastJson和JackJson可二选一
com.fasterxml.jackson.core
jackson-databind
2.5.3
com.alibaba
fastjson
1.2.47
org.apache.logging.log4j
log4j-api
2.11.2
org.apache.logging.log4j
log4j-core
2.11.2
二、公众号相关常量及接口地址
前提:公众号的appId 和appsecret
/**
* 公众号相关
*/
public class WechartConst {
//公众号的唯一标识
public static final String appId = "公众号的唯一标识";
//公众号的appsecret
public static final String appSecret = "公众号的appsecret";
//通过code换取网页授权信息
public static final String GET_WEBAUTH_URL ="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
//获取用户基本信息(包括UnionID机制)
public static final String GET_WEIXIN_USER_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
//获取用户基本信息(没有subscribe等字段)
public static final String Get_USER_URL = " https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
/**
* 获取access_token的URL
*/
public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
}
三、 HttpUtil类
用于发送POST或GET请求:HttpsUtil类
四、实体类
UserAccessToken类
介绍两种方法,作用都是把该属性的名称序列化为另外一个名称
(1)利用fastJson中的@JSONField
import com.alibaba.fastjson.annotation.JSONField;
/**
* 微信用户授权token
*/
public class UserAccessToken {
//获取到的凭证
@JSONField(name = "access_token")
private String accessToken;
//access_token接口调用凭证超时时间,单位(秒)
@JSONField(name = "expires_in")
private String expiresIn;
//用户刷新access_token
@JSONField(name = "refresh_token")
private String refreshToken;
//该用户在此公众号下的身份表示,对于此微信号具有唯一性
@JSONField(name = "openid")
private String openId;
//用户授权的作用域
@JSONField(name = "scope")
private String scope;
}
(2)使用JackJson中的@JsonProperty
/**
* 微信用户实体类
*
*/
public class WechatUser implements Serializable {
private static final long serialVersionUID = -4681067645282292327L;
// openId,标识该公众号下面的该用户的唯一Id
@JsonProperty("openid")
private String openId;
// 用户昵称
@JsonProperty("nick_name")
private String nickName;
// 性别
@JsonProperty("sex")
private int sex;
// 省份
@JsonProperty("province")
private String province;
// 诚实
@JsonProperty("city")
private String city;
// 区
@JsonProperty("country")
private String country;
// 头像图片地址
@JsonProperty("headimgurl")
private String headimgurl;
}
AccessToken类
/**
* 封装AccessToken实体
*/
public class AccessToken {
private String accessToken;
private int expiresIn;
}
WechatUserInfo类
public class WechatUserInfo {
//用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息
private int subscribe;
//用户的唯一标识
private String openid;
//用户昵称
private String nickname;
//用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
private int sex;
//用户个人资料填写的省份
private String province;
//普通用户个人资料填写的城市
private String city;
//国家,如中国为CN
private String country;
//用户头像,最后一个数值代表正方形头像大小
private String headimgurl;
五、WechartUtil工具类
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.jfinal.json.Json;
public class WechartUtil {
private static Logger log = LogManager.getLogger(WechartUtil.class);
/**
* 通过code获取UserAccessToken实体类
* @param code
* @return
*/
public static UserAccessToken getUserAccessToken(String code) {
String appId = WechartConst.appId;
String appSecret = WechartConst.appSecret;
//根据传入的code,拼接出访问微信定义好的接口的URL
String requestUrl = WechartConst.GET_WEBAUTH_URL.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);
//向相应URL发送请求获取JSON数据包
JSONObject jsonObject = HttpsUtil.request(requestUrl, "GET", null);
if (jsonObject!= null) {
Integer errCode = jsonObject.getInteger("errcode");
String resultMsg = jsonObject.toJSONString();
if (errCode != null) {
throw new ParameterException("获取用户accessToken失败:" + resultMsg);
}
try {
// 将json字符串转换成相应对象
//Jfinal框架中具有的Json.getJson().parse(String jsonString, Class type)方法
// UserAccessToken token = Json.getJson().parse(tokenStr, UserAccessToken.class);
//利用JackJson
ObjectMapper objectMapper = new ObjectMapper();
UserAccessToken token = objectMapper.readValue(tokenStr, UserAccessToken.class);
return token;
}catch (JSONException e) {
String errorMsg = jsonObject.getString("errmsg");
throw new ParameterException("获取用户accessToken失败:" + errorMsg);
}
}else {
throw new ParameterException("获取用户accessToken失败" );
}
}
/**
* 网页授权作用域为snsapi_userinfo,获取用户基本信息(UnionID机制)
* 前提:必须有一个微信开放平台账号绑定了至少一个微信公众账号或者网站应用或者小程序
* @param accessToken 网页授权accessToken
* @param openId
* @return
*/
public static WechatUserInfo getUserInfo(String accessToken, String openId) {
String requestUrl = WechartConst.GET_WEIXIN_USER_URL.replace("ACCESS_TOKEN", accessToken).replace( "OPENID", openId);
JSONObject jsonObject = HttpsUtil.request(requestUrl, "GET", null);
if (jsonObject!= null) {
Integer errCode = jsonObject.getInteger("errcode");
String resultMsg = jsonObject.toJSONString();
if (errCode != null) {
String errorMsg = jsonObject.getString("errmsg");
throw new ParameterException("获取用户基本信息失败:" + errorMsg);
}
try {
//Jfinal框架中具有的Json.getJson().parse(String jsonString, Class type)方法
//WechatUserInfo user= Json.getJson().parse(jsonObject.toJSONString(), WechatUserInfo.class);
user.setSubscribe(jsonObject.getInteger("subscribe"));
user.setOpenId(jsonObject.getString("openid"));
user.setNickName(jsonObject.getString("nickname"));
user.setSex(jsonObject.getInt("sex"));
user.setProvince(jsonObject.getString("province"));
user.setCity(jsonObject.getString("city"));
user.setCountry(jsonObject.getString("country"));
user.setHeadimgurl(jsonObject.getString("headimgurl"));
return user;
} catch (JSONException e) {
throw new ParameterException("获取用户accessToken失败:" + resultMsg);
}
}else {
throw new ParameterException("获取用户accessToken失败" );
}
}
}
四、使用示例
public static void main(String[] args) {
//获取从前端传过来的code
String code = "";
UserAccessToken userAccessToken = getUserAccessToken(code);
String accessToken = userAccessToken.getAccessToken();
String openId = userAccessToken.getOpenId();
WechatUserInfo getUserInfo = getUserInfo(accessToken,openId);
}