diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxOAuth2UserInfo.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxOAuth2UserInfo.java new file mode 100644 index 000000000..e64756002 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxOAuth2UserInfo.java @@ -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 Binary Wang + * @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 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,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); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java similarity index 51% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java index 24b87d7a0..0ab32d657 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java @@ -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 lombok.Data; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - /** * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 + * + * @author Daniel Qian */ @Data -public class WxMpOAuth2AccessToken implements Serializable { +public class WxOAuth2AccessToken implements Serializable { private static final long serialVersionUID = -1345910558078620805L; + @SerializedName("access_token") private String accessToken; + @SerializedName("expires_in") private int expiresIn = -1; + @SerializedName("refresh_token") private String refreshToken; + @SerializedName("openid") private String openId; + @SerializedName("scope") private String scope; /** * https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN. * 本接口在scope参数为snsapi_base时不再提供unionID字段。 */ + @SerializedName("unionid") private String unionId; - public static WxMpOAuth2AccessToken fromJson(String json) { - return WxMpGsonBuilder.create().fromJson(json, WxMpOAuth2AccessToken.class); + public static WxOAuth2AccessToken fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxOAuth2AccessToken.class); } @Override public String toString() { - return WxMpGsonBuilder.create().toJson(this); + return WxGsonBuilder.create().toJson(this); } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimpleGetRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimpleGetRequestExecutor.java index a0ce7a17e..266fd226e 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimpleGetRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimpleGetRequestExecutor.java @@ -1,7 +1,5 @@ package me.chanjar.weixin.common.util.http; -import java.io.IOException; - import me.chanjar.weixin.common.enums.WxType; import me.chanjar.weixin.common.error.WxError; 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.okhttp.OkHttpSimpleGetRequestExecutor; +import java.io.IOException; + /** * 简单的GET请求执行器. * 请求的参数是String, 返回的结果也是String @@ -27,7 +27,7 @@ public abstract class SimpleGetRequestExecutor implements RequestExecutor< handler.handle(this.execute(uri, data, wxType)); } - public static RequestExecutor create(RequestHttp requestHttp) { + public static RequestExecutor create(RequestHttp requestHttp) { switch (requestHttp.getRequestType()) { case APACHE_HTTP: return new ApacheSimpleGetRequestExecutor(requestHttp); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java index 6f74702f6..661a0ed79 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java @@ -1,12 +1,13 @@ package me.chanjar.weixin.cp.api.impl; import com.google.gson.JsonObject; -import me.chanjar.weixin.common.enums.WxType; 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.WxErrorException; import me.chanjar.weixin.common.error.WxRuntimeException; import me.chanjar.weixin.common.util.json.GsonParser; +import me.chanjar.weixin.cp.config.WxCpConfigStorage; import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; import org.apache.http.client.config.RequestConfig; 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 * * - * * @author Binary Wang */ public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl { @Override public String getAccessToken(boolean forceRefresh) throws WxErrorException { - if (!getWxCpConfigStorage().isAccessTokenExpired() && !forceRefresh) { - return getWxCpConfigStorage().getAccessToken(); + final WxCpConfigStorage configStorage = getWxCpConfigStorage(); + if (!configStorage.isAccessTokenExpired() && !forceRefresh) { + return configStorage.getAccessToken(); } - Lock lock = getWxCpConfigStorage().getAccessTokenLock(); + Lock lock = configStorage.getAccessTokenLock(); lock.lock(); try { // 拿到锁之后,再次判断一下最新的token是否过期,避免重刷 - if (!getWxCpConfigStorage().isAccessTokenExpired() && !forceRefresh) { - return getWxCpConfigStorage().getAccessToken(); + if (!configStorage.isAccessTokenExpired() && !forceRefresh) { + 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 { HttpGet httpGet = new HttpGet(url); if (getRequestHttpProxy() != null) { - RequestConfig config = RequestConfig.custom() - .setProxy(getRequestHttpProxy()).build(); + RequestConfig config = RequestConfig.custom().setProxy(getRequestHttpProxy()).build(); httpGet.setConfig(config); } String resultContent; @@ -67,60 +68,62 @@ public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl { } WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); - getWxCpConfigStorage().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); + configStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); } catch (IOException e) { throw new WxRuntimeException(e); } } finally { lock.unlock(); } - return getWxCpConfigStorage().getAccessToken(); + return configStorage.getAccessToken(); } @Override public String getAgentJsapiTicket(boolean forceRefresh) throws WxErrorException { + final WxCpConfigStorage configStorage = getWxCpConfigStorage(); if (forceRefresh) { - getWxCpConfigStorage().expireAgentJsapiTicket(); + configStorage.expireAgentJsapiTicket(); } - if (getWxCpConfigStorage().isAgentJsapiTicketExpired()) { - Lock lock = getWxCpConfigStorage().getAgentJsapiTicketLock(); + if (configStorage.isAgentJsapiTicketExpired()) { + Lock lock = configStorage.getAgentJsapiTicketLock(); lock.lock(); try { // 拿到锁之后,再次判断一下最新的token是否过期,避免重刷 - if (getWxCpConfigStorage().isAgentJsapiTicketExpired()) { - String responseContent = this.get(getWxCpConfigStorage().getApiUrl(GET_AGENT_CONFIG_TICKET), null); + if (configStorage.isAgentJsapiTicketExpired()) { + String responseContent = this.get(configStorage.getApiUrl(GET_AGENT_CONFIG_TICKET), null); JsonObject jsonObject = GsonParser.parse(responseContent); - getWxCpConfigStorage().updateAgentJsapiTicket(jsonObject.get("ticket").getAsString(), + configStorage.updateAgentJsapiTicket(jsonObject.get("ticket").getAsString(), jsonObject.get("expires_in").getAsInt()); } } finally { lock.unlock(); } } - return getWxCpConfigStorage().getAgentJsapiTicket(); + return configStorage.getAgentJsapiTicket(); } @Override public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { + final WxCpConfigStorage configStorage = getWxCpConfigStorage(); if (forceRefresh) { - getWxCpConfigStorage().expireJsapiTicket(); + configStorage.expireJsapiTicket(); } - if (getWxCpConfigStorage().isJsapiTicketExpired()) { - Lock lock = getWxCpConfigStorage().getJsapiTicketLock(); + if (configStorage.isJsapiTicketExpired()) { + Lock lock = configStorage.getJsapiTicketLock(); lock.lock(); try { // 拿到锁之后,再次判断一下最新的token是否过期,避免重刷 - if (getWxCpConfigStorage().isJsapiTicketExpired()) { - String responseContent = this.get(getWxCpConfigStorage().getApiUrl(GET_JSAPI_TICKET), null); + if (configStorage.isJsapiTicketExpired()) { + String responseContent = this.get(configStorage.getApiUrl(GET_JSAPI_TICKET), null); JsonObject tmpJsonObject = GsonParser.parse(responseContent); - getWxCpConfigStorage().updateJsapiTicket(tmpJsonObject.get("ticket").getAsString(), + configStorage.updateJsapiTicket(tmpJsonObject.get("ticket").getAsString(), tmpJsonObject.get("expires_in").getAsInt()); } } finally { lock.unlock(); } } - return getWxCpConfigStorage().getJsapiTicket(); + return configStorage.getJsapiTicket(); } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java index 791687b6c..74f3f6a61 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java @@ -65,12 +65,12 @@ public class WxMaSubscribeMessage implements Serializable { /** * 跳转小程序类型: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 */ - private String lang = WxMaConstants.MiniprogramLang.ZH_CN; + private String lang = WxMaConstants.MiniProgramLang.ZH_CN; public WxMaSubscribeMessage addData(Data datum) { if (this.data == null) { diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java index 2ca92d084..8ac322aa5 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java @@ -7,7 +7,10 @@ package cn.binarywang.wx.miniapp.constant; * * @author Binary Wang */ -public class WxMaConstants { +public abstract class WxMaConstants { + private WxMaConstants() { + } + /** * 微信接口返回的参数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 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; } - /** * 小程序订阅消息跳转小程序类型 - * + *

* 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 */ - public static final class MiniprogramLang{ + public static final class MiniProgramLang { + private MiniProgramLang() { + } + /** * 简体中文 */ diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java index cf127970f..1946a1fcf 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java @@ -12,9 +12,6 @@ import com.google.gson.JsonObject; import com.google.inject.Inject; import me.chanjar.weixin.common.error.WxErrorException; -import java.text.SimpleDateFormat; -import java.util.Date; - import static org.assertj.core.api.Assertions.assertThat; /** @@ -47,8 +44,8 @@ public class WxMaMsgServiceImplTest { WxMaSubscribeMessage message = new WxMaSubscribeMessage(); message.setTemplateId(config.getTemplateId()); message.setToUser(config.getOpenid()); - message.setLang(WxMaConstants.MiniprogramLang.ZH_CN); - message.setMiniprogramState(WxMaConstants.MiniprogramState.FORMAL); + message.setLang(WxMaConstants.MiniProgramLang.ZH_CN); + message.setMiniprogramState(WxMaConstants.MiniProgramState.FORMAL); message.addData(new WxMaSubscribeMessage.Data("thing1", "苹果到货啦")); message.addData(new WxMaSubscribeMessage.Data("amount3", "¥5")); message.addData(new WxMaSubscribeMessage.Data("thing5", "记得领取哦")); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxOAuth2Service.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxOAuth2Service.java index 1fbb1f1a9..0c7cc5764 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxOAuth2Service.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxOAuth2Service.java @@ -1,8 +1,8 @@ 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.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.mp.bean.result.WxMpUser; /** * oauth2 相关接口. @@ -17,12 +17,12 @@ public interface WxOAuth2Service { * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=网页授权获取用户基本信息 * * - * @param redirectURI 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode + * @param redirectUri 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode * @param scope scope * @param state state * @return url */ - String buildAuthorizationUrl(String redirectURI, String scope, String state); + String buildAuthorizationUrl(String redirectUri, String scope, String state); /** *

@@ -34,7 +34,18 @@ public interface WxOAuth2Service {
    * @return token对象
    * @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;
 
   /**
    * 
@@ -45,7 +56,7 @@ public interface WxOAuth2Service {
    * @return 新的token对象
    * @throws WxErrorException .
    */
-  WxMpOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException;
+  WxOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException;
 
   /**
    * 
@@ -57,7 +68,7 @@ public interface WxOAuth2Service {
    * @return 用户对象
    * @throws WxErrorException .
    */
-  WxMpUser getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException;
+  WxOAuth2UserInfo getUserInfo(WxOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException;
 
   /**
    * 
@@ -67,6 +78,6 @@ public interface WxOAuth2Service {
    * @param oAuth2AccessToken token对象
    * @return 是否有效
    */
-  boolean validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken);
+  boolean validateAccessToken(WxOAuth2AccessToken oAuth2AccessToken);
 
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
index 6fe921fb8..555078db1 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
@@ -126,7 +126,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
 
   @Getter
   @Setter
-  private WxOAuth2Service oAuth2Service = new WxOAuth2ServiceImpl(this);
+  private WxOAuth2Service oAuth2Service = new WxMpOAuth2ServiceImpl(this);
 
   private Map configStorageMap;
 
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxOAuth2ServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOAuth2ServiceImpl.java
similarity index 67%
rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxOAuth2ServiceImpl.java
rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOAuth2ServiceImpl.java
index 7ad8ed2c4..8d8187daa 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxOAuth2ServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOAuth2ServiceImpl.java
@@ -1,7 +1,8 @@
 package me.chanjar.weixin.mp.api.impl;
 
-import lombok.AllArgsConstructor;
 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.error.WxError;
 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.mp.api.WxMpService;
 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 org.apache.commons.lang3.StringUtils;
 
 import java.io.IOException;
 
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.*;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.OAuth2.*;
 
 /**
  * oauth2 相关接口实现类.
@@ -27,34 +26,37 @@ import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.*;
  * @date 2020-08-08
  */
 @RequiredArgsConstructor
-public class WxOAuth2ServiceImpl implements WxOAuth2Service {
+public class WxMpOAuth2ServiceImpl implements WxOAuth2Service {
   private final WxMpService wxMpService;
 
   @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()),
-      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 {
       RequestExecutor executor = SimpleGetRequestExecutor.create(this.wxMpService.getRequestHttp());
       String responseText = executor.execute(url, null, WxType.MP);
-      return WxMpOAuth2AccessToken.fromJson(responseText);
+      return WxOAuth2AccessToken.fromJson(responseText);
     } catch (IOException e) {
       throw new WxErrorException(WxError.builder().errorCode(99999).errorMsg(e.getMessage()).build(), e);
     }
   }
 
   @Override
-  public WxMpOAuth2AccessToken getAccessToken(String code) throws WxErrorException {
-    String url = String.format(OAUTH2_ACCESS_TOKEN_URL.getUrl(getMpConfigStorage()), getMpConfigStorage().getAppId(),
-      getMpConfigStorage().getSecret(), code);
-    return this.getOAuth2AccessToken(url);
+  public WxOAuth2AccessToken getAccessToken(String code) throws WxErrorException {
+    return this.getAccessToken(getMpConfigStorage().getAppId(), getMpConfigStorage().getSecret(), code);
   }
 
   @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);
     return this.getOAuth2AccessToken(url);
   }
@@ -64,7 +66,7 @@ public class WxOAuth2ServiceImpl implements WxOAuth2Service {
   }
 
   @Override
-  public WxMpUser getUserInfo(WxMpOAuth2AccessToken token, String lang) throws WxErrorException {
+  public WxOAuth2UserInfo getUserInfo(WxOAuth2AccessToken token, String lang) throws WxErrorException {
     if (lang == null) {
       lang = "zh_CN";
     }
@@ -74,14 +76,14 @@ public class WxOAuth2ServiceImpl implements WxOAuth2Service {
     try {
       RequestExecutor executor = SimpleGetRequestExecutor.create(this.wxMpService.getRequestHttp());
       String responseText = executor.execute(url, null, WxType.MP);
-      return WxMpUser.fromJson(responseText);
+      return WxOAuth2UserInfo.fromJson(responseText);
     } catch (IOException e) {
       throw new WxRuntimeException(e);
     }
   }
 
   @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());
 
     try {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeCheckcodeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeCheckcodeResult.java
index 84768c091..4b86bbbdd 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeCheckcodeResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeCheckcodeResult.java
@@ -2,7 +2,6 @@ package me.chanjar.weixin.mp.bean.card;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
-import me.chanjar.weixin.mp.bean.result.WxMpResult;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
 
 import java.io.Serializable;
@@ -10,8 +9,7 @@ import java.util.List;
 
 
 @Data
-public class WxMpCardCodeCheckcodeResult extends WxMpResult implements Serializable {
-
+public class WxMpCardCodeCheckcodeResult implements Serializable {
   private static final long serialVersionUID = -5128692403997016750L;
 
   /**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeDepositCountResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeDepositCountResult.java
index a7a114bf5..00631ec74 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeDepositCountResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeDepositCountResult.java
@@ -2,15 +2,16 @@ package me.chanjar.weixin.mp.bean.card;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
-import me.chanjar.weixin.mp.bean.result.WxMpResult;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
 
 import java.io.Serializable;
 
 
+/**
+ * @author S 
+ */
 @Data
-public class WxMpCardCodeDepositCountResult extends WxMpResult implements Serializable {
-
+public class WxMpCardCodeDepositCountResult implements Serializable {
   private static final long serialVersionUID = -6707587956061215868L;
 
   /**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeDepositResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeDepositResult.java
index aeb1246b8..e48a23f4a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeDepositResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCodeDepositResult.java
@@ -2,15 +2,16 @@ package me.chanjar.weixin.mp.bean.card;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
-import me.chanjar.weixin.mp.bean.result.WxMpResult;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
 
 import java.io.Serializable;
 
 
+/**
+ * @author S 
+ */
 @Data
-public class WxMpCardCodeDepositResult extends WxMpResult implements Serializable {
-
+public class WxMpCardCodeDepositResult  implements Serializable {
   private static final long serialVersionUID = 2955588617765355420L;
 
   /**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardMpnewsGethtmlResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardMpnewsGethtmlResult.java
index 13db310d5..6d7dde1ad 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardMpnewsGethtmlResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardMpnewsGethtmlResult.java
@@ -2,15 +2,16 @@ package me.chanjar.weixin.mp.bean.card;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
-import me.chanjar.weixin.mp.bean.result.WxMpResult;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
 
 import java.io.Serializable;
 
 
+/**
+ * @author S 
+ */
 @Data
-public class WxMpCardMpnewsGethtmlResult extends WxMpResult implements Serializable {
-
+public class WxMpCardMpnewsGethtmlResult implements Serializable {
   private static final long serialVersionUID = 6435268886823478711L;
 
   /**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxUserCardListResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxUserCardListResult.java
index 9133a32f1..e38c11564 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxUserCardListResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxUserCardListResult.java
@@ -2,18 +2,20 @@ package me.chanjar.weixin.mp.bean.card;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
-import me.chanjar.weixin.mp.bean.result.WxMpResult;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
 
+import java.io.Serializable;
 import java.util.List;
 
 /**
  * 用户已领卡券返回
+ *
  * @author yang229
  * @date 2019/12/22
  */
 @Data
-public class WxUserCardListResult extends WxMpResult implements java.io.Serializable {
+public class WxUserCardListResult implements Serializable {
+  private static final long serialVersionUID = 4348804828075982412L;
 
   /**
    * 卡券列表
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassGetResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassGetResult.java
index c1f43feb0..fe8f6e404 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassGetResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassGetResult.java
@@ -10,10 +10,10 @@ import java.io.Serializable;
  * 
  * 查询群发消息发送状态【订阅号与服务号认证后均可用】
  * 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 
  */
 @Data
-public class WxMpMassGetResult extends WxMpResult implements Serializable {
-
+public class WxMpMassGetResult implements Serializable {
   private static final long serialVersionUID = -2909694117357278557L;
 
   @SerializedName("msg_id")
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpResult.java
deleted file mode 100644
index 9be4b7e8c..000000000
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpResult.java
+++ /dev/null
@@ -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);
-  }
-}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
index 368814b44..d050aeb66 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
@@ -1,6 +1,8 @@
 package me.chanjar.weixin.mp.enums;
 
 import lombok.AllArgsConstructor;
+import lombok.Getter;
+import me.chanjar.weixin.mp.bean.WxMpHostConfig;
 import me.chanjar.weixin.mp.config.WxMpConfigStorage;
 
 import static me.chanjar.weixin.mp.bean.WxMpHostConfig.*;
@@ -21,9 +23,31 @@ public interface WxMpApiUrl {
    * @param config 微信公众号配置
    * @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
+  @Getter
   enum Device implements WxMpApiUrl {
     /**
      * get_bind_device.
@@ -64,15 +88,39 @@ public interface WxMpApiUrl {
 
     private final String prefix;
     private final String path;
+  }
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
+  @AllArgsConstructor
+  @Getter
+  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
+  @Getter
   enum Other implements WxMpApiUrl {
     /**
      * 获取access_token.
@@ -90,22 +138,6 @@ public interface WxMpApiUrl {
      * 语义查询接口.
      */
     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地址.
      */
@@ -118,10 +150,6 @@ public interface WxMpApiUrl {
      * 第三方使用网站应用授权登录的url.
      */
     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 path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum Marketing implements WxMpApiUrl {
     /**
      * sets add.
@@ -162,13 +187,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum Menu implements WxMpApiUrl {
     /**
      * get_current_selfmenu_info.
@@ -202,14 +224,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
-
   @AllArgsConstructor
+  @Getter
   enum Qrcode implements WxMpApiUrl {
     /**
      * create.
@@ -227,13 +245,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum ShakeAround implements WxMpApiUrl {
     /**
      * getshakeinfo.
@@ -255,13 +270,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum SubscribeMsg implements WxMpApiUrl {
     /**
      * subscribemsg.
@@ -275,13 +287,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum TemplateMsg implements WxMpApiUrl {
     /**
      * send.
@@ -311,13 +320,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum UserBlacklist implements WxMpApiUrl {
     /**
      * getblacklist.
@@ -335,13 +341,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum UserTag implements WxMpApiUrl {
     /**
      * create.
@@ -379,13 +382,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum Wifi implements WxMpApiUrl {
     /**
      * list.
@@ -405,13 +405,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum AiOpen implements WxMpApiUrl {
     /**
      * translatecontent.
@@ -429,13 +426,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum Ocr implements WxMpApiUrl {
     /**
      * 身份证识别.
@@ -496,17 +490,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     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
+  @Getter
   enum Card implements WxMpApiUrl {
     /**
      * create.
@@ -606,13 +593,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum DataCube implements WxMpApiUrl {
     /**
      * getusersummary.
@@ -686,13 +670,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum Kefu implements WxMpApiUrl {
     /**
      * send.
@@ -758,13 +739,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum MassMessage implements WxMpApiUrl {
     /**
      * 上传群发用的图文消息.
@@ -812,13 +790,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum Material implements WxMpApiUrl {
     /**
      * get.
@@ -868,13 +843,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum MemberCard implements WxMpApiUrl {
     /**
      * create.
@@ -913,13 +885,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum Store implements WxMpApiUrl {
     /**
      * getwxcategory.
@@ -949,13 +918,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum User implements WxMpApiUrl {
     /**
      * batchget.
@@ -981,13 +947,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum Comment implements WxMpApiUrl {
     /**
      * 打开已群发文章评论.
@@ -1032,13 +995,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 
   @AllArgsConstructor
+  @Getter
   enum ImgProc implements WxMpApiUrl {
     /**
      * 二维码/条码识别
@@ -1073,16 +1033,10 @@ public interface WxMpApiUrl {
     private final String prefix;
     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
+  @Getter
   enum Invoice implements WxMpApiUrl {
 
     /**
@@ -1148,19 +1102,13 @@ public interface WxMpApiUrl {
     private final String prefix;
     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
+  @Getter
   enum Guide implements WxMpApiUrl {
     /**
      * 添加顾问
@@ -1185,13 +1133,5 @@ public interface WxMpApiUrl {
     private final String prefix;
     private final String path;
 
-    @Override
-    public String getUrl(WxMpConfigStorage config) {
-      if (null == config) {
-        return buildUrl(null, prefix, path);
-      }
-
-      return buildUrl(config.getHostConfig(), prefix, path);
-    }
   }
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java
index 82e2b3631..5f762cc6d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java
@@ -40,7 +40,6 @@ public class WxMpGsonBuilder {
     INSTANCE.registerTypeAdapter(WxMpTemplateMessage.class, new WxMpTemplateMessageGsonAdapter());
     INSTANCE.registerTypeAdapter(WxMpSubscribeMessage.class, new WxMpSubscribeMessageGsonAdapter());
     INSTANCE.registerTypeAdapter(WxMpSemanticQueryResult.class, new WxMpSemanticQueryResultAdapter());
-    INSTANCE.registerTypeAdapter(WxMpOAuth2AccessToken.class, new WxMpOAuth2AccessTokenAdapter());
     INSTANCE.registerTypeAdapter(WxDataCubeUserSummary.class, new WxMpUserSummaryGsonAdapter());
     INSTANCE.registerTypeAdapter(WxDataCubeUserCumulate.class, new WxMpUserCumulateGsonAdapter());
     INSTANCE.registerTypeAdapter(WxMpMaterialUploadResult.class, new WxMpMaterialUploadResultAdapter());
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java
deleted file mode 100644
index c832ef8da..000000000
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java
+++ /dev/null
@@ -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 {
-
-  @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;
-  }
-
-}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java
index ecacc36de..0f742a675 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java
@@ -10,7 +10,8 @@ import me.chanjar.weixin.mp.bean.card.*;
 import org.testng.annotations.Guice;
 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 cardId = "pu7Gr5secJXPkxBeuYUhmp8TYsuY";
     WxUserCardListResult result = this.wxService.getCardService().getUserCardList(openId, cardId);
-    assertTrue(result.isSuccess());
+    assertNotNull(result);
     System.out.println(result);
   }
 }
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpOAuth2ServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpOAuth2ServiceImplTest.java
new file mode 100644
index 000000000..6004d3cbe
--- /dev/null
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpOAuth2ServiceImplTest.java
@@ -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 Binary Wang
+ * @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();
+  }
+}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxOAuth2ServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxOAuth2ServiceImplTest.java
deleted file mode 100644
index 8729f99d2..000000000
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxOAuth2ServiceImplTest.java
+++ /dev/null
@@ -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 Binary Wang
- * @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() {
-  }
-}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java
index 476a56a65..d0c5dfcec 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java
@@ -1,8 +1,9 @@
 package me.chanjar.weixin.mp.demo;
 
+import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
 import me.chanjar.weixin.common.error.WxErrorException;
 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 javax.servlet.http.HttpServlet;
@@ -31,17 +32,17 @@ public class WxMpOAuth2Servlet extends HttpServlet {
       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("

access token

"); - 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("

user info

"); response.getWriter().println(wxMpUser.toString()); - wxMpOAuth2AccessToken = this.wxMpService.getOAuth2Service().refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken()); + oAuth2AccessToken = this.wxMpService.getOAuth2Service().refreshAccessToken(oAuth2AccessToken.getRefreshToken()); response.getWriter().println("

after refresh

"); - response.getWriter().println(wxMpOAuth2AccessToken.toString()); + response.getWriter().println(oAuth2AccessToken.toString()); } catch (WxErrorException e) { e.printStackTrace(); diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index 68dfb3d60..8efcf4210 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -3,7 +3,7 @@ package me.chanjar.weixin.open.api; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import me.chanjar.weixin.common.error.WxErrorException; 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.WxOpenGetResult; import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate; @@ -332,7 +332,7 @@ public interface WxOpenComponentService { * @return the wx mp o auth 2 access token * @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. @@ -353,7 +353,7 @@ public interface WxOpenComponentService { * @return the wx mp o auth 2 access token * @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. diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java index 91b412f88..271cde746 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java @@ -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.WxGsonBuilder; 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.bean.*; import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; @@ -394,10 +394,10 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { } @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 responseContent = get(url); - return WxMpOAuth2AccessToken.fromJson(responseContent); + return WxOAuth2AccessToken.fromJson(responseContent); } @Override @@ -406,10 +406,10 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { } @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 responseContent = get(url); - return WxMpOAuth2AccessToken.fromJson(responseContent); + return WxOAuth2AccessToken.fromJson(responseContent); } @Override