🎨 优化部分代码,重构OAuth2网页授权、网页登录等相关接口,方便接入open模块

This commit is contained in:
Binary Wang 2020-10-11 00:10:08 +08:00
parent 6cc5ebdcce
commit c7b1abc796
26 changed files with 352 additions and 367 deletions

View File

@ -0,0 +1,66 @@
package me.chanjar.weixin.common.bean;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import java.io.Serializable;
/**
* oauth2用户个人信息.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-10-11
*/
@Data
public class WxOAuth2UserInfo implements Serializable {
private static final long serialVersionUID = 3181943506448954725L;
/**
* openid 普通用户的标识对当前开发者帐号唯一
*/
private String openid;
/**
* nickname 普通用户昵称
*/
private String nickname;
/**
* sex 普通用户性别1为男性2为女性
*/
private Integer sex;
/**
* city 普通用户个人资料填写的城市
*/
private String city;
/**
* province 普通用户个人资料填写的省份
*/
private String province;
/**
* country 国家如中国为CN
*/
private String country;
/**
* headimgurl 用户头像最后一个数值代表正方形头像大小有0466496132数值可选0代表640*640正方形头像
* 用户没有头像时该项为空
*/
@SerializedName("headimgurl")
private String headImgUrl;
/**
* unionid 用户统一标识针对一个微信开放平台帐号下的应用同一用户的unionid是唯一的
*/
@SerializedName("unionid")
private String unionId;
/**
* privilege 用户特权信息json数组如微信沃卡用户为chinaunicom
*/
@SerializedName("privilege")
private String[] privileges;
public static WxOAuth2UserInfo fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WxOAuth2UserInfo.class);
}
}

View File

@ -1,39 +1,48 @@
package me.chanjar.weixin.mp.bean.result; package me.chanjar.weixin.common.bean.oauth2;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import java.io.Serializable; import java.io.Serializable;
import lombok.Data;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/** /**
* https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
*
* @author Daniel Qian
*/ */
@Data @Data
public class WxMpOAuth2AccessToken implements Serializable { public class WxOAuth2AccessToken implements Serializable {
private static final long serialVersionUID = -1345910558078620805L; private static final long serialVersionUID = -1345910558078620805L;
@SerializedName("access_token")
private String accessToken; private String accessToken;
@SerializedName("expires_in")
private int expiresIn = -1; private int expiresIn = -1;
@SerializedName("refresh_token")
private String refreshToken; private String refreshToken;
@SerializedName("openid")
private String openId; private String openId;
@SerializedName("scope")
private String scope; private String scope;
/** /**
* https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN. * https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN.
* 本接口在scope参数为snsapi_base时不再提供unionID字段 * 本接口在scope参数为snsapi_base时不再提供unionID字段
*/ */
@SerializedName("unionid")
private String unionId; private String unionId;
public static WxMpOAuth2AccessToken fromJson(String json) { public static WxOAuth2AccessToken fromJson(String json) {
return WxMpGsonBuilder.create().fromJson(json, WxMpOAuth2AccessToken.class); return WxGsonBuilder.create().fromJson(json, WxOAuth2AccessToken.class);
} }
@Override @Override
public String toString() { public String toString() {
return WxMpGsonBuilder.create().toJson(this); return WxGsonBuilder.create().toJson(this);
} }
} }

View File

@ -1,7 +1,5 @@
package me.chanjar.weixin.common.util.http; package me.chanjar.weixin.common.util.http;
import java.io.IOException;
import me.chanjar.weixin.common.enums.WxType; import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
@ -9,6 +7,8 @@ import me.chanjar.weixin.common.util.http.apache.ApacheSimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimpleGetRequestExecutor; import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.okhttp.OkHttpSimpleGetRequestExecutor; import me.chanjar.weixin.common.util.http.okhttp.OkHttpSimpleGetRequestExecutor;
import java.io.IOException;
/** /**
* 简单的GET请求执行器. * 简单的GET请求执行器.
* 请求的参数是String, 返回的结果也是String * 请求的参数是String, 返回的结果也是String
@ -27,7 +27,7 @@ public abstract class SimpleGetRequestExecutor<H, P> implements RequestExecutor<
handler.handle(this.execute(uri, data, wxType)); handler.handle(this.execute(uri, data, wxType));
} }
public static RequestExecutor<String, String> create(RequestHttp requestHttp) { public static RequestExecutor<String, String> create(RequestHttp<?, ?> requestHttp) {
switch (requestHttp.getRequestType()) { switch (requestHttp.getRequestType()) {
case APACHE_HTTP: case APACHE_HTTP:
return new ApacheSimpleGetRequestExecutor(requestHttp); return new ApacheSimpleGetRequestExecutor(requestHttp);

View File

@ -1,12 +1,13 @@
package me.chanjar.weixin.cp.api.impl; package me.chanjar.weixin.cp.api.impl;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException; import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.common.util.json.GsonParser; import me.chanjar.weixin.common.util.json.GsonParser;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
@ -30,28 +31,28 @@ import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.GET_JSAPI_TICKET;
* Updated by yuanqixun on 2020-05-13 * Updated by yuanqixun on 2020-05-13
* </pre> * </pre>
* *
*
* @author <a href="https://github.com/binarywang">Binary Wang</a> * @author <a href="https://github.com/binarywang">Binary Wang</a>
*/ */
public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl { public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl {
@Override @Override
public String getAccessToken(boolean forceRefresh) throws WxErrorException { public String getAccessToken(boolean forceRefresh) throws WxErrorException {
if (!getWxCpConfigStorage().isAccessTokenExpired() && !forceRefresh) { final WxCpConfigStorage configStorage = getWxCpConfigStorage();
return getWxCpConfigStorage().getAccessToken(); if (!configStorage.isAccessTokenExpired() && !forceRefresh) {
return configStorage.getAccessToken();
} }
Lock lock = getWxCpConfigStorage().getAccessTokenLock(); Lock lock = configStorage.getAccessTokenLock();
lock.lock(); lock.lock();
try { try {
// 拿到锁之后再次判断一下最新的token是否过期避免重刷 // 拿到锁之后再次判断一下最新的token是否过期避免重刷
if (!getWxCpConfigStorage().isAccessTokenExpired() && !forceRefresh) { if (!configStorage.isAccessTokenExpired() && !forceRefresh) {
return getWxCpConfigStorage().getAccessToken(); return configStorage.getAccessToken();
} }
String url = String.format(getWxCpConfigStorage().getApiUrl(WxCpApiPathConsts.GET_TOKEN), this.configStorage.getCorpId(), this.configStorage.getCorpSecret()); String url = String.format(configStorage.getApiUrl(WxCpApiPathConsts.GET_TOKEN),
this.configStorage.getCorpId(), this.configStorage.getCorpSecret());
try { try {
HttpGet httpGet = new HttpGet(url); HttpGet httpGet = new HttpGet(url);
if (getRequestHttpProxy() != null) { if (getRequestHttpProxy() != null) {
RequestConfig config = RequestConfig.custom() RequestConfig config = RequestConfig.custom().setProxy(getRequestHttpProxy()).build();
.setProxy(getRequestHttpProxy()).build();
httpGet.setConfig(config); httpGet.setConfig(config);
} }
String resultContent; String resultContent;
@ -67,60 +68,62 @@ public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl {
} }
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
getWxCpConfigStorage().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); configStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
} catch (IOException e) { } catch (IOException e) {
throw new WxRuntimeException(e); throw new WxRuntimeException(e);
} }
} finally { } finally {
lock.unlock(); lock.unlock();
} }
return getWxCpConfigStorage().getAccessToken(); return configStorage.getAccessToken();
} }
@Override @Override
public String getAgentJsapiTicket(boolean forceRefresh) throws WxErrorException { public String getAgentJsapiTicket(boolean forceRefresh) throws WxErrorException {
final WxCpConfigStorage configStorage = getWxCpConfigStorage();
if (forceRefresh) { if (forceRefresh) {
getWxCpConfigStorage().expireAgentJsapiTicket(); configStorage.expireAgentJsapiTicket();
} }
if (getWxCpConfigStorage().isAgentJsapiTicketExpired()) { if (configStorage.isAgentJsapiTicketExpired()) {
Lock lock = getWxCpConfigStorage().getAgentJsapiTicketLock(); Lock lock = configStorage.getAgentJsapiTicketLock();
lock.lock(); lock.lock();
try { try {
// 拿到锁之后再次判断一下最新的token是否过期避免重刷 // 拿到锁之后再次判断一下最新的token是否过期避免重刷
if (getWxCpConfigStorage().isAgentJsapiTicketExpired()) { if (configStorage.isAgentJsapiTicketExpired()) {
String responseContent = this.get(getWxCpConfigStorage().getApiUrl(GET_AGENT_CONFIG_TICKET), null); String responseContent = this.get(configStorage.getApiUrl(GET_AGENT_CONFIG_TICKET), null);
JsonObject jsonObject = GsonParser.parse(responseContent); JsonObject jsonObject = GsonParser.parse(responseContent);
getWxCpConfigStorage().updateAgentJsapiTicket(jsonObject.get("ticket").getAsString(), configStorage.updateAgentJsapiTicket(jsonObject.get("ticket").getAsString(),
jsonObject.get("expires_in").getAsInt()); jsonObject.get("expires_in").getAsInt());
} }
} finally { } finally {
lock.unlock(); lock.unlock();
} }
} }
return getWxCpConfigStorage().getAgentJsapiTicket(); return configStorage.getAgentJsapiTicket();
} }
@Override @Override
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
final WxCpConfigStorage configStorage = getWxCpConfigStorage();
if (forceRefresh) { if (forceRefresh) {
getWxCpConfigStorage().expireJsapiTicket(); configStorage.expireJsapiTicket();
} }
if (getWxCpConfigStorage().isJsapiTicketExpired()) { if (configStorage.isJsapiTicketExpired()) {
Lock lock = getWxCpConfigStorage().getJsapiTicketLock(); Lock lock = configStorage.getJsapiTicketLock();
lock.lock(); lock.lock();
try { try {
// 拿到锁之后再次判断一下最新的token是否过期避免重刷 // 拿到锁之后再次判断一下最新的token是否过期避免重刷
if (getWxCpConfigStorage().isJsapiTicketExpired()) { if (configStorage.isJsapiTicketExpired()) {
String responseContent = this.get(getWxCpConfigStorage().getApiUrl(GET_JSAPI_TICKET), null); String responseContent = this.get(configStorage.getApiUrl(GET_JSAPI_TICKET), null);
JsonObject tmpJsonObject = GsonParser.parse(responseContent); JsonObject tmpJsonObject = GsonParser.parse(responseContent);
getWxCpConfigStorage().updateJsapiTicket(tmpJsonObject.get("ticket").getAsString(), configStorage.updateJsapiTicket(tmpJsonObject.get("ticket").getAsString(),
tmpJsonObject.get("expires_in").getAsInt()); tmpJsonObject.get("expires_in").getAsInt());
} }
} finally { } finally {
lock.unlock(); lock.unlock();
} }
} }
return getWxCpConfigStorage().getJsapiTicket(); return configStorage.getJsapiTicket();
} }
} }

View File

@ -65,12 +65,12 @@ public class WxMaSubscribeMessage implements Serializable {
/** /**
* 跳转小程序类型developer为开发版trial为体验版formal为正式版默认为正式版 * 跳转小程序类型developer为开发版trial为体验版formal为正式版默认为正式版
*/ */
private String miniprogramState = WxMaConstants.MiniprogramState.FORMAL; private String miniprogramState = WxMaConstants.MiniProgramState.FORMAL;
/** /**
* 进入小程序查看的语言类型支持zh_CN(简体中文)en_US(英文)zh_HK(繁体中文)zh_TW(繁体中文)默认为zh_CN * 进入小程序查看的语言类型支持zh_CN(简体中文)en_US(英文)zh_HK(繁体中文)zh_TW(繁体中文)默认为zh_CN
*/ */
private String lang = WxMaConstants.MiniprogramLang.ZH_CN; private String lang = WxMaConstants.MiniProgramLang.ZH_CN;
public WxMaSubscribeMessage addData(Data datum) { public WxMaSubscribeMessage addData(Data datum) {
if (this.data == null) { if (this.data == null) {

View File

@ -7,7 +7,10 @@ package cn.binarywang.wx.miniapp.constant;
* *
* @author <a href="https://github.com/binarywang">Binary Wang</a> * @author <a href="https://github.com/binarywang">Binary Wang</a>
*/ */
public class WxMaConstants { public abstract class WxMaConstants {
private WxMaConstants() {
}
/** /**
* 微信接口返回的参数errcode. * 微信接口返回的参数errcode.
*/ */
@ -16,7 +19,7 @@ public class WxMaConstants {
/** /**
* 素材类型. * 素材类型.
*/ */
public static class MediaType { public abstract static class MediaType {
/** /**
* 图片. * 图片.
*/ */
@ -26,7 +29,7 @@ public class WxMaConstants {
/** /**
* 消息格式. * 消息格式.
*/ */
public static class MsgDataFormat { public abstract static class MsgDataFormat {
public static final String XML = "XML"; public static final String XML = "XML";
public static final String JSON = "JSON"; public static final String JSON = "JSON";
} }
@ -72,7 +75,7 @@ public class WxMaConstants {
/** /**
* 快递账号绑定类型 * 快递账号绑定类型
*/ */
public static final class BindAccountType{ public static final class BindAccountType {
/** /**
* 绑定 * 绑定
@ -88,7 +91,7 @@ public class WxMaConstants {
/** /**
* 快递下单订单来源 * 快递下单订单来源
*/ */
public static final class OrderAddSource{ public static final class OrderAddSource {
/** /**
* 小程序 * 小程序
@ -104,7 +107,11 @@ public class WxMaConstants {
/** /**
* 快递下单保价 * 快递下单保价
*/ */
public static final class OrderAddInsured{ public static final class OrderAddInsured {
private OrderAddInsured() {
}
/** /**
* 不保价 * 不保价
*/ */
@ -121,13 +128,15 @@ public class WxMaConstants {
public static final int DEFAULT_INSURED_VALUE = 0; public static final int DEFAULT_INSURED_VALUE = 0;
} }
/** /**
* 小程序订阅消息跳转小程序类型 * 小程序订阅消息跳转小程序类型
* * <p>
* developer为开发版trial为体验版formal为正式版默认为正式版 * developer为开发版trial为体验版formal为正式版默认为正式版
*/ */
public static final class MiniprogramState{ public static final class MiniProgramState {
private MiniProgramState() {
}
/** /**
* 开发版 * 开发版
*/ */
@ -149,7 +158,10 @@ public class WxMaConstants {
* 进入小程序查看的语言类型 * 进入小程序查看的语言类型
* 支持zh_CN(简体中文)en_US(英文)zh_HK(繁体中文)zh_TW(繁体中文)默认为zh_CN * 支持zh_CN(简体中文)en_US(英文)zh_HK(繁体中文)zh_TW(繁体中文)默认为zh_CN
*/ */
public static final class MiniprogramLang{ public static final class MiniProgramLang {
private MiniProgramLang() {
}
/** /**
* 简体中文 * 简体中文
*/ */

View File

@ -12,9 +12,6 @@ import com.google.gson.JsonObject;
import com.google.inject.Inject; import com.google.inject.Inject;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
@ -47,8 +44,8 @@ public class WxMaMsgServiceImplTest {
WxMaSubscribeMessage message = new WxMaSubscribeMessage(); WxMaSubscribeMessage message = new WxMaSubscribeMessage();
message.setTemplateId(config.getTemplateId()); message.setTemplateId(config.getTemplateId());
message.setToUser(config.getOpenid()); message.setToUser(config.getOpenid());
message.setLang(WxMaConstants.MiniprogramLang.ZH_CN); message.setLang(WxMaConstants.MiniProgramLang.ZH_CN);
message.setMiniprogramState(WxMaConstants.MiniprogramState.FORMAL); message.setMiniprogramState(WxMaConstants.MiniProgramState.FORMAL);
message.addData(new WxMaSubscribeMessage.Data("thing1", "苹果到货啦")); message.addData(new WxMaSubscribeMessage.Data("thing1", "苹果到货啦"));
message.addData(new WxMaSubscribeMessage.Data("amount3", "¥5")); message.addData(new WxMaSubscribeMessage.Data("amount3", "¥5"));
message.addData(new WxMaSubscribeMessage.Data("thing5", "记得领取哦")); message.addData(new WxMaSubscribeMessage.Data("thing5", "记得领取哦"));

View File

@ -1,8 +1,8 @@
package me.chanjar.weixin.mp.api; package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
/** /**
* oauth2 相关接口. * oauth2 相关接口.
@ -17,12 +17,12 @@ public interface WxOAuth2Service {
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=网页授权获取用户基本信息 * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=网页授权获取用户基本信息
* </pre> * </pre>
* *
* @param redirectURI 用户授权完成后的重定向链接无需urlencode, 方法内会进行encode * @param redirectUri 用户授权完成后的重定向链接无需urlencode, 方法内会进行encode
* @param scope scope * @param scope scope
* @param state state * @param state state
* @return url * @return url
*/ */
String buildAuthorizationUrl(String redirectURI, String scope, String state); String buildAuthorizationUrl(String redirectUri, String scope, String state);
/** /**
* <pre> * <pre>
@ -34,7 +34,18 @@ public interface WxOAuth2Service {
* @return token对象 * @return token对象
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WxMpOAuth2AccessToken getAccessToken(String code) throws WxErrorException; WxOAuth2AccessToken getAccessToken(String code) throws WxErrorException;
/**
* 用code换取oauth2的access token.
*
* @param appId the appid
* @param appSecret the secret
* @param code code
* @return token对象
* @throws WxErrorException .
*/
WxOAuth2AccessToken getAccessToken(String appId, String appSecret, String code) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -45,7 +56,7 @@ public interface WxOAuth2Service {
* @return 新的token对象 * @return 新的token对象
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WxMpOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException; WxOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -57,7 +68,7 @@ public interface WxOAuth2Service {
* @return 用户对象 * @return 用户对象
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WxMpUser getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException; WxOAuth2UserInfo getUserInfo(WxOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -67,6 +78,6 @@ public interface WxOAuth2Service {
* @param oAuth2AccessToken token对象 * @param oAuth2AccessToken token对象
* @return 是否有效 * @return 是否有效
*/ */
boolean validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken); boolean validateAccessToken(WxOAuth2AccessToken oAuth2AccessToken);
} }

View File

@ -126,7 +126,7 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
@Getter @Getter
@Setter @Setter
private WxOAuth2Service oAuth2Service = new WxOAuth2ServiceImpl(this); private WxOAuth2Service oAuth2Service = new WxMpOAuth2ServiceImpl(this);
private Map<String, WxMpConfigStorage> configStorageMap; private Map<String, WxMpConfigStorage> configStorageMap;

View File

@ -1,7 +1,8 @@
package me.chanjar.weixin.mp.api.impl; package me.chanjar.weixin.mp.api.impl;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.enums.WxType; import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
@ -11,14 +12,12 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.URIUtil; import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxOAuth2Service; import me.chanjar.weixin.mp.api.WxOAuth2Service;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.config.WxMpConfigStorage; import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.IOException; import java.io.IOException;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.*; import static me.chanjar.weixin.mp.enums.WxMpApiUrl.OAuth2.*;
/** /**
* oauth2 相关接口实现类. * oauth2 相关接口实现类.
@ -27,34 +26,37 @@ import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.*;
* @date 2020-08-08 * @date 2020-08-08
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
public class WxOAuth2ServiceImpl implements WxOAuth2Service { public class WxMpOAuth2ServiceImpl implements WxOAuth2Service {
private final WxMpService wxMpService; private final WxMpService wxMpService;
@Override @Override
public String buildAuthorizationUrl(String redirectURI, String scope, String state) { public String buildAuthorizationUrl(String redirectUri, String scope, String state) {
return String.format(CONNECT_OAUTH2_AUTHORIZE_URL.getUrl(getMpConfigStorage()), return String.format(CONNECT_OAUTH2_AUTHORIZE_URL.getUrl(getMpConfigStorage()),
getMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); getMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectUri), scope, StringUtils.trimToEmpty(state));
} }
private WxMpOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException { private WxOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException {
try { try {
RequestExecutor<String, String> executor = SimpleGetRequestExecutor.create(this.wxMpService.getRequestHttp()); RequestExecutor<String, String> executor = SimpleGetRequestExecutor.create(this.wxMpService.getRequestHttp());
String responseText = executor.execute(url, null, WxType.MP); String responseText = executor.execute(url, null, WxType.MP);
return WxMpOAuth2AccessToken.fromJson(responseText); return WxOAuth2AccessToken.fromJson(responseText);
} catch (IOException e) { } catch (IOException e) {
throw new WxErrorException(WxError.builder().errorCode(99999).errorMsg(e.getMessage()).build(), e); throw new WxErrorException(WxError.builder().errorCode(99999).errorMsg(e.getMessage()).build(), e);
} }
} }
@Override @Override
public WxMpOAuth2AccessToken getAccessToken(String code) throws WxErrorException { public WxOAuth2AccessToken getAccessToken(String code) throws WxErrorException {
String url = String.format(OAUTH2_ACCESS_TOKEN_URL.getUrl(getMpConfigStorage()), getMpConfigStorage().getAppId(), return this.getAccessToken(getMpConfigStorage().getAppId(), getMpConfigStorage().getSecret(), code);
getMpConfigStorage().getSecret(), code);
return this.getOAuth2AccessToken(url);
} }
@Override @Override
public WxMpOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException { public WxOAuth2AccessToken getAccessToken(String appId, String appSecret, String code) throws WxErrorException {
return this.getOAuth2AccessToken(String.format(OAUTH2_ACCESS_TOKEN_URL.getUrl(getMpConfigStorage()), appId, appSecret, code));
}
@Override
public WxOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException {
String url = String.format(OAUTH2_REFRESH_TOKEN_URL.getUrl(getMpConfigStorage()), getMpConfigStorage().getAppId(), refreshToken); String url = String.format(OAUTH2_REFRESH_TOKEN_URL.getUrl(getMpConfigStorage()), getMpConfigStorage().getAppId(), refreshToken);
return this.getOAuth2AccessToken(url); return this.getOAuth2AccessToken(url);
} }
@ -64,7 +66,7 @@ public class WxOAuth2ServiceImpl implements WxOAuth2Service {
} }
@Override @Override
public WxMpUser getUserInfo(WxMpOAuth2AccessToken token, String lang) throws WxErrorException { public WxOAuth2UserInfo getUserInfo(WxOAuth2AccessToken token, String lang) throws WxErrorException {
if (lang == null) { if (lang == null) {
lang = "zh_CN"; lang = "zh_CN";
} }
@ -74,14 +76,14 @@ public class WxOAuth2ServiceImpl implements WxOAuth2Service {
try { try {
RequestExecutor<String, String> executor = SimpleGetRequestExecutor.create(this.wxMpService.getRequestHttp()); RequestExecutor<String, String> executor = SimpleGetRequestExecutor.create(this.wxMpService.getRequestHttp());
String responseText = executor.execute(url, null, WxType.MP); String responseText = executor.execute(url, null, WxType.MP);
return WxMpUser.fromJson(responseText); return WxOAuth2UserInfo.fromJson(responseText);
} catch (IOException e) { } catch (IOException e) {
throw new WxRuntimeException(e); throw new WxRuntimeException(e);
} }
} }
@Override @Override
public boolean validateAccessToken(WxMpOAuth2AccessToken token) { public boolean validateAccessToken(WxOAuth2AccessToken token) {
String url = String.format(OAUTH2_VALIDATE_TOKEN_URL.getUrl(getMpConfigStorage()), token.getAccessToken(), token.getOpenId()); String url = String.format(OAUTH2_VALIDATE_TOKEN_URL.getUrl(getMpConfigStorage()), token.getAccessToken(), token.getOpenId());
try { try {

View File

@ -2,7 +2,6 @@ package me.chanjar.weixin.mp.bean.card;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import lombok.Data; import lombok.Data;
import me.chanjar.weixin.mp.bean.result.WxMpResult;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable; import java.io.Serializable;
@ -10,8 +9,7 @@ import java.util.List;
@Data @Data
public class WxMpCardCodeCheckcodeResult extends WxMpResult implements Serializable { public class WxMpCardCodeCheckcodeResult implements Serializable {
private static final long serialVersionUID = -5128692403997016750L; private static final long serialVersionUID = -5128692403997016750L;
/** /**

View File

@ -2,15 +2,16 @@ package me.chanjar.weixin.mp.bean.card;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import lombok.Data; import lombok.Data;
import me.chanjar.weixin.mp.bean.result.WxMpResult;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable; import java.io.Serializable;
/**
* @author S <sshzh90@gmail.com>
*/
@Data @Data
public class WxMpCardCodeDepositCountResult extends WxMpResult implements Serializable { public class WxMpCardCodeDepositCountResult implements Serializable {
private static final long serialVersionUID = -6707587956061215868L; private static final long serialVersionUID = -6707587956061215868L;
/** /**

View File

@ -2,15 +2,16 @@ package me.chanjar.weixin.mp.bean.card;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import lombok.Data; import lombok.Data;
import me.chanjar.weixin.mp.bean.result.WxMpResult;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable; import java.io.Serializable;
/**
* @author S <sshzh90@gmail.com>
*/
@Data @Data
public class WxMpCardCodeDepositResult extends WxMpResult implements Serializable { public class WxMpCardCodeDepositResult implements Serializable {
private static final long serialVersionUID = 2955588617765355420L; private static final long serialVersionUID = 2955588617765355420L;
/** /**

View File

@ -2,15 +2,16 @@ package me.chanjar.weixin.mp.bean.card;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import lombok.Data; import lombok.Data;
import me.chanjar.weixin.mp.bean.result.WxMpResult;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable; import java.io.Serializable;
/**
* @author S <sshzh90@gmail.com>
*/
@Data @Data
public class WxMpCardMpnewsGethtmlResult extends WxMpResult implements Serializable { public class WxMpCardMpnewsGethtmlResult implements Serializable {
private static final long serialVersionUID = 6435268886823478711L; private static final long serialVersionUID = 6435268886823478711L;
/** /**

View File

@ -2,18 +2,20 @@ package me.chanjar.weixin.mp.bean.card;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import lombok.Data; import lombok.Data;
import me.chanjar.weixin.mp.bean.result.WxMpResult;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
* 用户已领卡券返回 * 用户已领卡券返回
*
* @author yang229 * @author yang229
* @date 2019/12/22 * @date 2019/12/22
*/ */
@Data @Data
public class WxUserCardListResult extends WxMpResult implements java.io.Serializable { public class WxUserCardListResult implements Serializable {
private static final long serialVersionUID = 4348804828075982412L;
/** /**
* 卡券列表 * 卡券列表

View File

@ -10,10 +10,10 @@ import java.io.Serializable;
* <pre> * <pre>
* 查询群发消息发送状态订阅号与服务号认证后均可用 * 查询群发消息发送状态订阅号与服务号认证后均可用
* https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html#%E6%9F%A5%E8%AF%A2%E7%BE%A4%E5%8F%91%E6%B6%88%E6%81%AF%E5%8F%91%E9%80%81%E7%8A%B6%E6%80%81%E3%80%90%E8%AE%A2%E9%98%85%E5%8F%B7%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%8F%B7%E8%AE%A4%E8%AF%81%E5%90%8E%E5%9D%87%E5%8F%AF%E7%94%A8%E3%80%91 * https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html#%E6%9F%A5%E8%AF%A2%E7%BE%A4%E5%8F%91%E6%B6%88%E6%81%AF%E5%8F%91%E9%80%81%E7%8A%B6%E6%80%81%E3%80%90%E8%AE%A2%E9%98%85%E5%8F%B7%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%8F%B7%E8%AE%A4%E8%AF%81%E5%90%8E%E5%9D%87%E5%8F%AF%E7%94%A8%E3%80%91
* @author S <sshzh90@gmail.com>
*/ */
@Data @Data
public class WxMpMassGetResult extends WxMpResult implements Serializable { public class WxMpMassGetResult implements Serializable {
private static final long serialVersionUID = -2909694117357278557L; private static final long serialVersionUID = -2909694117357278557L;
@SerializedName("msg_id") @SerializedName("msg_id")

View File

@ -1,33 +0,0 @@
package me.chanjar.weixin.mp.bean.result;
import lombok.Data;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
/**
* 基础的微信公众号平台请求结果.
*/
@Data
public class WxMpResult implements Serializable {
private static final long serialVersionUID = 2101652152604850904L;
protected String errcode;
protected String errmsg;
/**
* 请求是否成功.
*/
public boolean isSuccess() {
return StringUtils.equalsIgnoreCase(errcode, "0");
}
public static WxMpResult fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WxMpResult.class);
}
@Override
public String toString() {
return WxGsonBuilder.create().toJson(this);
}
}

View File

@ -1,6 +1,8 @@
package me.chanjar.weixin.mp.enums; package me.chanjar.weixin.mp.enums;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter;
import me.chanjar.weixin.mp.bean.WxMpHostConfig;
import me.chanjar.weixin.mp.config.WxMpConfigStorage; import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import static me.chanjar.weixin.mp.bean.WxMpHostConfig.*; import static me.chanjar.weixin.mp.bean.WxMpHostConfig.*;
@ -21,9 +23,31 @@ public interface WxMpApiUrl {
* @param config 微信公众号配置 * @param config 微信公众号配置
* @return api地址 * @return api地址
*/ */
String getUrl(WxMpConfigStorage config); default String getUrl(WxMpConfigStorage config) {
WxMpHostConfig hostConfig = null;
if (config != null) {
hostConfig = config.getHostConfig();
}
return buildUrl(hostConfig, this.getPrefix(), this.getPath());
}
/**
* the path
*
* @return path
*/
String getPath();
/**
* the prefix
*
* @return prefix
*/
String getPrefix();
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Device implements WxMpApiUrl { enum Device implements WxMpApiUrl {
/** /**
* get_bind_device. * get_bind_device.
@ -64,15 +88,39 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
}
@Override @AllArgsConstructor
public String getUrl(WxMpConfigStorage config) { @Getter
return buildUrl(config.getHostConfig(), prefix, path); enum OAuth2 implements WxMpApiUrl {
} /**
* 用code换取oauth2的access token.
*/
OAUTH2_ACCESS_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"),
/**
* 刷新oauth2的access token.
*/
OAUTH2_REFRESH_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s"),
/**
* 用oauth2获取用户信息.
*/
OAUTH2_USERINFO_URL(API_DEFAULT_HOST_URL, "/sns/userinfo?access_token=%s&openid=%s&lang=%s"),
/**
* 验证oauth2的access token是否有效.
*/
OAUTH2_VALIDATE_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/auth?access_token=%s&openid=%s"),
/**
* oauth2授权的url连接.
*/
CONNECT_OAUTH2_AUTHORIZE_URL(OPEN_DEFAULT_HOST_URL, "/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&connect_redirect=1#wechat_redirect");
private final String prefix;
private final String path;
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Other implements WxMpApiUrl { enum Other implements WxMpApiUrl {
/** /**
* 获取access_token. * 获取access_token.
@ -90,22 +138,6 @@ public interface WxMpApiUrl {
* 语义查询接口. * 语义查询接口.
*/ */
SEMANTIC_SEMPROXY_SEARCH_URL(API_DEFAULT_HOST_URL, "/semantic/semproxy/search"), SEMANTIC_SEMPROXY_SEARCH_URL(API_DEFAULT_HOST_URL, "/semantic/semproxy/search"),
/**
* 用code换取oauth2的access token.
*/
OAUTH2_ACCESS_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"),
/**
* 刷新oauth2的access token.
*/
OAUTH2_REFRESH_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s"),
/**
* 用oauth2获取用户信息.
*/
OAUTH2_USERINFO_URL(API_DEFAULT_HOST_URL, "/sns/userinfo?access_token=%s&openid=%s&lang=%s"),
/**
* 验证oauth2的access token是否有效.
*/
OAUTH2_VALIDATE_TOKEN_URL(API_DEFAULT_HOST_URL, "/sns/auth?access_token=%s&openid=%s"),
/** /**
* 获取微信服务器IP地址. * 获取微信服务器IP地址.
*/ */
@ -118,10 +150,6 @@ public interface WxMpApiUrl {
* 第三方使用网站应用授权登录的url. * 第三方使用网站应用授权登录的url.
*/ */
QRCONNECT_URL(OPEN_DEFAULT_HOST_URL, "/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"), QRCONNECT_URL(OPEN_DEFAULT_HOST_URL, "/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"),
/**
* oauth2授权的url连接.
*/
CONNECT_OAUTH2_AUTHORIZE_URL(OPEN_DEFAULT_HOST_URL, "/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&connect_redirect=1#wechat_redirect"),
/** /**
* 获取公众号的自动回复规则. * 获取公众号的自动回复规则.
*/ */
@ -134,13 +162,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Marketing implements WxMpApiUrl { enum Marketing implements WxMpApiUrl {
/** /**
* sets add. * sets add.
@ -162,13 +187,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Menu implements WxMpApiUrl { enum Menu implements WxMpApiUrl {
/** /**
* get_current_selfmenu_info. * get_current_selfmenu_info.
@ -202,14 +224,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Qrcode implements WxMpApiUrl { enum Qrcode implements WxMpApiUrl {
/** /**
* create. * create.
@ -227,13 +245,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum ShakeAround implements WxMpApiUrl { enum ShakeAround implements WxMpApiUrl {
/** /**
* getshakeinfo. * getshakeinfo.
@ -255,13 +270,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum SubscribeMsg implements WxMpApiUrl { enum SubscribeMsg implements WxMpApiUrl {
/** /**
* subscribemsg. * subscribemsg.
@ -275,13 +287,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum TemplateMsg implements WxMpApiUrl { enum TemplateMsg implements WxMpApiUrl {
/** /**
* send. * send.
@ -311,13 +320,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum UserBlacklist implements WxMpApiUrl { enum UserBlacklist implements WxMpApiUrl {
/** /**
* getblacklist. * getblacklist.
@ -335,13 +341,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum UserTag implements WxMpApiUrl { enum UserTag implements WxMpApiUrl {
/** /**
* create. * create.
@ -379,13 +382,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Wifi implements WxMpApiUrl { enum Wifi implements WxMpApiUrl {
/** /**
* list. * list.
@ -405,13 +405,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum AiOpen implements WxMpApiUrl { enum AiOpen implements WxMpApiUrl {
/** /**
* translatecontent. * translatecontent.
@ -429,13 +426,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Ocr implements WxMpApiUrl { enum Ocr implements WxMpApiUrl {
/** /**
* 身份证识别. * 身份证识别.
@ -496,17 +490,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
if (config == null) {
return buildUrl(null, prefix, path);
}
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Card implements WxMpApiUrl { enum Card implements WxMpApiUrl {
/** /**
* create. * create.
@ -606,13 +593,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum DataCube implements WxMpApiUrl { enum DataCube implements WxMpApiUrl {
/** /**
* getusersummary. * getusersummary.
@ -686,13 +670,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Kefu implements WxMpApiUrl { enum Kefu implements WxMpApiUrl {
/** /**
* send. * send.
@ -758,13 +739,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum MassMessage implements WxMpApiUrl { enum MassMessage implements WxMpApiUrl {
/** /**
* 上传群发用的图文消息. * 上传群发用的图文消息.
@ -812,13 +790,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Material implements WxMpApiUrl { enum Material implements WxMpApiUrl {
/** /**
* get. * get.
@ -868,13 +843,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum MemberCard implements WxMpApiUrl { enum MemberCard implements WxMpApiUrl {
/** /**
* create. * create.
@ -913,13 +885,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Store implements WxMpApiUrl { enum Store implements WxMpApiUrl {
/** /**
* getwxcategory. * getwxcategory.
@ -949,13 +918,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum User implements WxMpApiUrl { enum User implements WxMpApiUrl {
/** /**
* batchget. * batchget.
@ -981,13 +947,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Comment implements WxMpApiUrl { enum Comment implements WxMpApiUrl {
/** /**
* 打开已群发文章评论. * 打开已群发文章评论.
@ -1032,13 +995,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum ImgProc implements WxMpApiUrl { enum ImgProc implements WxMpApiUrl {
/** /**
* 二维码/条码识别 * 二维码/条码识别
@ -1073,16 +1033,10 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
if (null == config) {
return buildUrl(null, prefix, path);
}
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Invoice implements WxMpApiUrl { enum Invoice implements WxMpApiUrl {
/** /**
@ -1148,19 +1102,13 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
if (null == config) {
return buildUrl(null, prefix, path);
}
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
/** /**
* 对话能力 * 对话能力
*/ */
@AllArgsConstructor @AllArgsConstructor
@Getter
enum Guide implements WxMpApiUrl { enum Guide implements WxMpApiUrl {
/** /**
* 添加顾问 * 添加顾问
@ -1185,13 +1133,5 @@ public interface WxMpApiUrl {
private final String prefix; private final String prefix;
private final String path; private final String path;
@Override
public String getUrl(WxMpConfigStorage config) {
if (null == config) {
return buildUrl(null, prefix, path);
}
return buildUrl(config.getHostConfig(), prefix, path);
}
} }
} }

View File

@ -40,7 +40,6 @@ public class WxMpGsonBuilder {
INSTANCE.registerTypeAdapter(WxMpTemplateMessage.class, new WxMpTemplateMessageGsonAdapter()); INSTANCE.registerTypeAdapter(WxMpTemplateMessage.class, new WxMpTemplateMessageGsonAdapter());
INSTANCE.registerTypeAdapter(WxMpSubscribeMessage.class, new WxMpSubscribeMessageGsonAdapter()); INSTANCE.registerTypeAdapter(WxMpSubscribeMessage.class, new WxMpSubscribeMessageGsonAdapter());
INSTANCE.registerTypeAdapter(WxMpSemanticQueryResult.class, new WxMpSemanticQueryResultAdapter()); INSTANCE.registerTypeAdapter(WxMpSemanticQueryResult.class, new WxMpSemanticQueryResultAdapter());
INSTANCE.registerTypeAdapter(WxMpOAuth2AccessToken.class, new WxMpOAuth2AccessTokenAdapter());
INSTANCE.registerTypeAdapter(WxDataCubeUserSummary.class, new WxMpUserSummaryGsonAdapter()); INSTANCE.registerTypeAdapter(WxDataCubeUserSummary.class, new WxMpUserSummaryGsonAdapter());
INSTANCE.registerTypeAdapter(WxDataCubeUserCumulate.class, new WxMpUserCumulateGsonAdapter()); INSTANCE.registerTypeAdapter(WxDataCubeUserCumulate.class, new WxMpUserCumulateGsonAdapter());
INSTANCE.registerTypeAdapter(WxMpMaterialUploadResult.class, new WxMpMaterialUploadResultAdapter()); INSTANCE.registerTypeAdapter(WxMpMaterialUploadResult.class, new WxMpMaterialUploadResultAdapter());

View File

@ -1,38 +0,0 @@
package me.chanjar.weixin.mp.util.json;
import com.google.gson.*;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import java.lang.reflect.Type;
public class WxMpOAuth2AccessTokenAdapter implements JsonDeserializer<WxMpOAuth2AccessToken> {
@Override
public WxMpOAuth2AccessToken deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
JsonParseException {
WxMpOAuth2AccessToken accessToken = new WxMpOAuth2AccessToken();
JsonObject accessTokenJsonObject = json.getAsJsonObject();
if (accessTokenJsonObject.get("access_token") != null && !accessTokenJsonObject.get("access_token").isJsonNull()) {
accessToken.setAccessToken(GsonHelper.getAsString(accessTokenJsonObject.get("access_token")));
}
if (accessTokenJsonObject.get("expires_in") != null && !accessTokenJsonObject.get("expires_in").isJsonNull()) {
accessToken.setExpiresIn(GsonHelper.getAsPrimitiveInt(accessTokenJsonObject.get("expires_in")));
}
if (accessTokenJsonObject.get("refresh_token") != null && !accessTokenJsonObject.get("refresh_token").isJsonNull()) {
accessToken.setRefreshToken(GsonHelper.getAsString(accessTokenJsonObject.get("refresh_token")));
}
if (accessTokenJsonObject.get("openid") != null && !accessTokenJsonObject.get("openid").isJsonNull()) {
accessToken.setOpenId(GsonHelper.getAsString(accessTokenJsonObject.get("openid")));
}
if (accessTokenJsonObject.get("scope") != null && !accessTokenJsonObject.get("scope").isJsonNull()) {
accessToken.setScope(GsonHelper.getAsString(accessTokenJsonObject.get("scope")));
}
if (accessTokenJsonObject.get("unionid") != null && !accessTokenJsonObject.get("unionid").isJsonNull()) {
accessToken.setUnionId(GsonHelper.getAsString(accessTokenJsonObject.get("unionid")));
}
return accessToken;
}
}

View File

@ -10,7 +10,8 @@ import me.chanjar.weixin.mp.bean.card.*;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static org.testng.AssertJUnit.*; import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
/** /**
* 测试代码仅供参考未做严格测试因原接口作者并未提供单元测试代码 * 测试代码仅供参考未做严格测试因原接口作者并未提供单元测试代码
@ -234,7 +235,7 @@ public class WxMpCardServiceImplTest {
String openId = "ou7Gr5sJZgFGgj38sRCNQg5pc3Fc"; String openId = "ou7Gr5sJZgFGgj38sRCNQg5pc3Fc";
String cardId = "pu7Gr5secJXPkxBeuYUhmp8TYsuY"; String cardId = "pu7Gr5secJXPkxBeuYUhmp8TYsuY";
WxUserCardListResult result = this.wxService.getCardService().getUserCardList(openId, cardId); WxUserCardListResult result = this.wxService.getCardService().getUserCardList(openId, cardId);
assertTrue(result.isSuccess()); assertNotNull(result);
System.out.println(result); System.out.println(result);
} }
} }

View File

@ -0,0 +1,59 @@
package me.chanjar.weixin.mp.api.impl;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.test.ApiTestModule;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import javax.inject.Inject;
import static org.assertj.core.api.Assertions.assertThat;
/**
* 测试类.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-08-09
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMpOAuth2ServiceImplTest {
@Inject
private WxMpService mpService;
@Test
public void testBuildAuthorizationUrl() {
final String url = this.mpService.getOAuth2Service().buildAuthorizationUrl("http://www.baidu.com", "test", "GOD");
assertThat(url).isEqualTo("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +
this.mpService.getWxMpConfigStorage().getAppId() +
"&redirect_uri=http%3A%2F%2Fwww.baidu.com&response_type=code&scope=test&state=GOD&connect_redirect=1#wechat_redirect");
}
@Test
public void testGetAccessToken() throws WxErrorException {
final WxOAuth2AccessToken accessToken = this.mpService.getOAuth2Service().getAccessToken("11");
assertThat(accessToken).isNotNull();
}
@Test
public void testRefreshAccessToken() throws WxErrorException {
final WxOAuth2AccessToken accessToken = this.mpService.getOAuth2Service().refreshAccessToken("11");
assertThat(accessToken).isNotNull();
}
@Test
public void testGetUserInfo() throws WxErrorException {
final WxOAuth2AccessToken accessToken = this.mpService.getOAuth2Service().getAccessToken("11");
final WxOAuth2UserInfo userInfo = this.mpService.getOAuth2Service().getUserInfo(accessToken, null);
assertThat(userInfo).isNotNull();
}
@Test
public void testValidateAccessToken() {
final boolean result = this.mpService.getOAuth2Service().validateAccessToken(new WxOAuth2AccessToken());
assertThat(result).isTrue();
}
}

View File

@ -1,47 +0,0 @@
package me.chanjar.weixin.mp.api.impl;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.test.ApiTestModule;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import javax.inject.Inject;
import static org.assertj.core.api.Assertions.assertThat;
/**
* 测试类.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-08-09
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxOAuth2ServiceImplTest {
@Inject
private WxMpService mpService;
@Test
public void testBuildAuthorizationUrl() {
final String url = this.mpService.getOAuth2Service().buildAuthorizationUrl("http://www.baidu.com", "test", "GOD");
assertThat(url).isEqualTo("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +
this.mpService.getWxMpConfigStorage().getAppId() +
"&redirect_uri=http%3A%2F%2Fwww.baidu.com&response_type=code&scope=test&state=GOD&connect_redirect=1#wechat_redirect");
}
@Test
public void testGetAccessToken() {
}
@Test
public void testRefreshAccessToken() {
}
@Test
public void testGetUserInfo() {
}
@Test
public void testValidateAccessToken() {
}
}

View File

@ -1,8 +1,9 @@
package me.chanjar.weixin.mp.demo; package me.chanjar.weixin.mp.demo;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.bean.result.WxMpUser;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
@ -31,17 +32,17 @@ public class WxMpOAuth2Servlet extends HttpServlet {
response.getWriter().println("<h1>code</h1>"); response.getWriter().println("<h1>code</h1>");
response.getWriter().println(code); response.getWriter().println(code);
WxMpOAuth2AccessToken wxMpOAuth2AccessToken = this.wxMpService.getOAuth2Service().getAccessToken(code); WxOAuth2AccessToken oAuth2AccessToken = this.wxMpService.getOAuth2Service().getAccessToken(code);
response.getWriter().println("<h1>access token</h1>"); response.getWriter().println("<h1>access token</h1>");
response.getWriter().println(wxMpOAuth2AccessToken.toString()); response.getWriter().println(oAuth2AccessToken.toString());
WxMpUser wxMpUser = this.wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null); WxOAuth2UserInfo wxMpUser = this.wxMpService.getOAuth2Service().getUserInfo(oAuth2AccessToken, null);
response.getWriter().println("<h1>user info</h1>"); response.getWriter().println("<h1>user info</h1>");
response.getWriter().println(wxMpUser.toString()); response.getWriter().println(wxMpUser.toString());
wxMpOAuth2AccessToken = this.wxMpService.getOAuth2Service().refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken()); oAuth2AccessToken = this.wxMpService.getOAuth2Service().refreshAccessToken(oAuth2AccessToken.getRefreshToken());
response.getWriter().println("<h1>after refresh</h1>"); response.getWriter().println("<h1>after refresh</h1>");
response.getWriter().println(wxMpOAuth2AccessToken.toString()); response.getWriter().println(oAuth2AccessToken.toString());
} catch (WxErrorException e) { } catch (WxErrorException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -3,7 +3,7 @@ package me.chanjar.weixin.open.api;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.open.bean.WxOpenCreateResult; import me.chanjar.weixin.open.bean.WxOpenCreateResult;
import me.chanjar.weixin.open.bean.WxOpenGetResult; import me.chanjar.weixin.open.bean.WxOpenGetResult;
import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate; import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate;
@ -332,7 +332,7 @@ public interface WxOpenComponentService {
* @return the wx mp o auth 2 access token * @return the wx mp o auth 2 access token
* @throws WxErrorException the wx error exception * @throws WxErrorException the wx error exception
*/ */
WxMpOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException; WxOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException;
/** /**
* Check signature boolean. * Check signature boolean.
@ -353,7 +353,7 @@ public interface WxOpenComponentService {
* @return the wx mp o auth 2 access token * @return the wx mp o auth 2 access token
* @throws WxErrorException the wx error exception * @throws WxErrorException the wx error exception
*/ */
WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; WxOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException;
/** /**
* Oauth 2 build authorization url string. * Oauth 2 build authorization url string.

View File

@ -14,7 +14,7 @@ import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.common.util.json.GsonParser; import me.chanjar.weixin.common.util.json.GsonParser;
import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.open.api.*; import me.chanjar.weixin.open.api.*;
import me.chanjar.weixin.open.bean.*; import me.chanjar.weixin.open.bean.*;
import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo;
@ -394,10 +394,10 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
} }
@Override @Override
public WxMpOAuth2AccessToken oauth2getAccessToken(String appId, String code) throws WxErrorException { public WxOAuth2AccessToken oauth2getAccessToken(String appId, String code) throws WxErrorException {
String url = String.format(OAUTH2_ACCESS_TOKEN_URL, appId, code, getWxOpenConfigStorage().getComponentAppId()); String url = String.format(OAUTH2_ACCESS_TOKEN_URL, appId, code, getWxOpenConfigStorage().getComponentAppId());
String responseContent = get(url); String responseContent = get(url);
return WxMpOAuth2AccessToken.fromJson(responseContent); return WxOAuth2AccessToken.fromJson(responseContent);
} }
@Override @Override
@ -406,10 +406,10 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
} }
@Override @Override
public WxMpOAuth2AccessToken oauth2refreshAccessToken(String appId, String refreshToken) throws WxErrorException { public WxOAuth2AccessToken oauth2refreshAccessToken(String appId, String refreshToken) throws WxErrorException {
String url = String.format(OAUTH2_REFRESH_TOKEN_URL, appId, refreshToken, getWxOpenConfigStorage().getComponentAppId()); String url = String.format(OAUTH2_REFRESH_TOKEN_URL, appId, refreshToken, getWxOpenConfigStorage().getComponentAppId());
String responseContent = get(url); String responseContent = get(url);
return WxMpOAuth2AccessToken.fromJson(responseContent); return WxOAuth2AccessToken.fromJson(responseContent);
} }
@Override @Override