@@ -31,6 +31,11 @@ | |||||
<artifactId>weixin-java-mp</artifactId> | <artifactId>weixin-java-mp</artifactId> | ||||
<version>${project.version}</version> | <version>${project.version}</version> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>com.github.binarywang</groupId> | |||||
<artifactId>weixin-java-miniapp</artifactId> | |||||
<version>${project.version}</version> | |||||
</dependency> | |||||
<dependency> | <dependency> | ||||
<groupId>org.jodd</groupId> | <groupId>org.jodd</groupId> | ||||
@@ -1,6 +1,7 @@ | |||||
package me.chanjar.weixin.open.api; | package me.chanjar.weixin.open.api; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.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.mp.bean.result.WxMpOAuth2AccessToken; | ||||
@@ -35,8 +36,10 @@ public interface WxOpenComponentService { | |||||
*/ | */ | ||||
String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/component/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid=%s"; | String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/component/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid=%s"; | ||||
WxMpService getWxMpServiceByAppid(String appid); | |||||
String MINIAPP_JSCODE_2_SESSION = "https://api.weixin.qq.com/sns/component/jscode2session?appid=%s&js_code=%s&grant_type=authorization_code&component_appid=%s"; | |||||
WxMpService getWxMpServiceByAppid(String appid); | |||||
WxMaService getWxMaServiceByAppid(String appid); | |||||
WxOpenConfigStorage getWxOpenConfigStorage(); | WxOpenConfigStorage getWxOpenConfigStorage(); | ||||
boolean checkSignature(String timestamp, String nonce, String signature); | boolean checkSignature(String timestamp, String nonce, String signature); | ||||
@@ -49,7 +52,6 @@ public interface WxOpenComponentService { | |||||
String getPreAuthUrl(String redirectURI) throws WxErrorException; | String getPreAuthUrl(String redirectURI) throws WxErrorException; | ||||
String route(WxOpenXmlMessage wxMessage) throws WxErrorException; | String route(WxOpenXmlMessage wxMessage) throws WxErrorException; | ||||
/** | /** | ||||
* 使用授权码换取公众号或小程序的接口调用凭据和授权信息 | * 使用授权码换取公众号或小程序的接口调用凭据和授权信息 | ||||
*/ | */ | ||||
@@ -68,7 +70,7 @@ public interface WxOpenComponentService { | |||||
/** | /** | ||||
* 设置授权方的选项信息 | * 设置授权方的选项信息 | ||||
*/ | */ | ||||
WxError setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException; | |||||
void setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException; | |||||
String getAuthorizerAccessToken(String appid, boolean forceRefresh) throws WxErrorException; | String getAuthorizerAccessToken(String appid, boolean forceRefresh) throws WxErrorException; | ||||
@@ -79,5 +81,6 @@ public interface WxOpenComponentService { | |||||
WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; | WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; | ||||
String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state); | String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state); | ||||
WxMaJscode2SessionResult miniappJscode2Session(String appid, String jsCode, String appId) throws WxErrorException; | |||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package me.chanjar.weixin.open.api; | package me.chanjar.weixin.open.api; | ||||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | import me.chanjar.weixin.mp.api.WxMpConfigStorage; | ||||
import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; | import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; | ||||
import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; | import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; | ||||
@@ -36,6 +37,7 @@ public interface WxOpenConfigStorage { | |||||
void updateComponentAccessTokent(WxOpenComponentAccessToken componentAccessToken); | void updateComponentAccessTokent(WxOpenComponentAccessToken componentAccessToken); | ||||
WxMpConfigStorage getWxMpConfigStorage(String appId); | WxMpConfigStorage getWxMpConfigStorage(String appId); | ||||
WxMaConfig getWxMaConfig(String appId); | |||||
/** | /** | ||||
* 应该是线程安全的 | * 应该是线程安全的 | ||||
@@ -1,7 +1,8 @@ | |||||
package me.chanjar.weixin.open.api.impl; | package me.chanjar.weixin.open.api.impl; | ||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | |||||
import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.crypto.SHA1; | import me.chanjar.weixin.common.util.crypto.SHA1; | ||||
import me.chanjar.weixin.common.util.http.URIUtil; | import me.chanjar.weixin.common.util.http.URIUtil; | ||||
@@ -30,7 +31,10 @@ import java.util.Map; | |||||
* @author <a href="https://github.com/007gzs">007</a> | * @author <a href="https://github.com/007gzs">007</a> | ||||
*/ | */ | ||||
public class WxOpenComponentServiceImpl implements WxOpenComponentService { | public class WxOpenComponentServiceImpl implements WxOpenComponentService { | ||||
private static final Map<String, WxMaService> WX_OPEN_MA_SERVICE_MAP = new Hashtable<>(); | |||||
private static final Map<String, WxMpService> WX_OPEN_MP_SERVICE_MAP = new Hashtable<>(); | private static final Map<String, WxMpService> WX_OPEN_MP_SERVICE_MAP = new Hashtable<>(); | ||||
protected final Logger log = LoggerFactory.getLogger(this.getClass()); | protected final Logger log = LoggerFactory.getLogger(this.getClass()); | ||||
private WxOpenService wxOpenService; | private WxOpenService wxOpenService; | ||||
@@ -54,6 +58,20 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { | |||||
return wxMpService; | return wxMpService; | ||||
} | } | ||||
@Override | |||||
public WxMaService getWxMaServiceByAppid(String appId) { | |||||
WxMaService wxMaService = WX_OPEN_MA_SERVICE_MAP.get(appId); | |||||
if (wxMaService == null) { | |||||
synchronized (WX_OPEN_MA_SERVICE_MAP) { | |||||
wxMaService = WX_OPEN_MA_SERVICE_MAP.get(appId); | |||||
if (wxMaService == null) { | |||||
wxMaService = new WxOpenMaServiceImpl(this, appId, getWxOpenConfigStorage().getWxMaConfig(appId)); | |||||
WX_OPEN_MA_SERVICE_MAP.put(appId, wxMaService); | |||||
} | |||||
} | |||||
} | |||||
return wxMaService; | |||||
} | |||||
public WxOpenService getWxOpenService() { | public WxOpenService getWxOpenService() { | ||||
return wxOpenService; | return wxOpenService; | ||||
} | } | ||||
@@ -137,7 +155,7 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { | |||||
} | } | ||||
return "success"; | return "success"; | ||||
} | } | ||||
return null; | |||||
return ""; | |||||
} | } | ||||
@Override | @Override | ||||
@@ -169,14 +187,13 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { | |||||
} | } | ||||
@Override | @Override | ||||
public WxError setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException { | |||||
public void setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException { | |||||
JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); | jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); | ||||
jsonObject.addProperty("authorizer_appid", authorizerAppid); | jsonObject.addProperty("authorizer_appid", authorizerAppid); | ||||
jsonObject.addProperty("option_name", optionName); | jsonObject.addProperty("option_name", optionName); | ||||
jsonObject.addProperty("option_value", optionValue); | jsonObject.addProperty("option_value", optionValue); | ||||
String responseContent = post(API_SET_AUTHORIZER_OPTION_URL, jsonObject.toString()); | |||||
return WxGsonBuilder.create().fromJson(responseContent, WxError.class); | |||||
post(API_SET_AUTHORIZER_OPTION_URL, jsonObject.toString()); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -220,4 +237,11 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { | |||||
appId, URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state), getWxOpenConfigStorage().getComponentAppId()); | appId, URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state), getWxOpenConfigStorage().getComponentAppId()); | ||||
} | } | ||||
@Override | |||||
public WxMaJscode2SessionResult miniappJscode2Session(String appid, String jsCode, String appId) throws WxErrorException { | |||||
String url = String.format(MINIAPP_JSCODE_2_SESSION, appId, jsCode, getWxOpenConfigStorage().getComponentAppId()); | |||||
String responseContent = get(url); | |||||
return WxMaJscode2SessionResult.fromJson(responseContent); | |||||
} | |||||
} | } |
@@ -1,6 +1,7 @@ | |||||
package me.chanjar.weixin.open.api.impl; | package me.chanjar.weixin.open.api.impl; | ||||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||||
import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | ||||
@@ -101,7 +102,12 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||||
@Override | @Override | ||||
public WxMpConfigStorage getWxMpConfigStorage(String appId) { | public WxMpConfigStorage getWxMpConfigStorage(String appId) { | ||||
return new WxOpenMpConfigStorage(this, appId); | |||||
return new WxOpenInnerConfigStorage(this, appId); | |||||
} | |||||
@Override | |||||
public WxMaConfig getWxMaConfig(String appId) { | |||||
return new WxOpenInnerConfigStorage(this, appId); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -222,14 +228,13 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||||
private String token; | private String token; | ||||
private Long expiresTime; | private Long expiresTime; | ||||
} | } | ||||
private static class WxOpenMpConfigStorage implements WxMpConfigStorage { | |||||
private static class WxOpenInnerConfigStorage implements WxMpConfigStorage, WxMaConfig { | |||||
private WxOpenConfigStorage wxOpenConfigStorage; | private WxOpenConfigStorage wxOpenConfigStorage; | ||||
private String appId; | private String appId; | ||||
private Lock accessTokenLock = new ReentrantLock(); | private Lock accessTokenLock = new ReentrantLock(); | ||||
private Lock jsapiTicketLock = new ReentrantLock(); | private Lock jsapiTicketLock = new ReentrantLock(); | ||||
private Lock cardApiTicketLock = new ReentrantLock(); | private Lock cardApiTicketLock = new ReentrantLock(); | ||||
private WxOpenMpConfigStorage(WxOpenConfigStorage wxOpenConfigStorage, String appId) { | |||||
private WxOpenInnerConfigStorage(WxOpenConfigStorage wxOpenConfigStorage, String appId) { | |||||
this.wxOpenConfigStorage = wxOpenConfigStorage; | this.wxOpenConfigStorage = wxOpenConfigStorage; | ||||
this.appId = appId; | this.appId = appId; | ||||
} | } | ||||
@@ -259,6 +264,11 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||||
wxOpenConfigStorage.updateAuthorizerAccessToken(appId, accessToken, expiresInSeconds); | wxOpenConfigStorage.updateAuthorizerAccessToken(appId, accessToken, expiresInSeconds); | ||||
} | } | ||||
@Override | |||||
public String getAppid() { | |||||
return this.appId; | |||||
} | |||||
@Override | @Override | ||||
public void expireAccessToken() { | public void expireAccessToken() { | ||||
wxOpenConfigStorage.expireAuthorizerAccessToken(appId); | wxOpenConfigStorage.expireAuthorizerAccessToken(appId); | ||||
@@ -343,6 +353,11 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||||
return wxOpenConfigStorage.getComponentAesKey(); | return wxOpenConfigStorage.getComponentAesKey(); | ||||
} | } | ||||
@Override | |||||
public String getMsgDataFormat() { | |||||
return null; | |||||
} | |||||
@Override | @Override | ||||
public String getOauth2redirectUri() { | public String getOauth2redirectUri() { | ||||
return null; | return null; | ||||
@@ -0,0 +1,36 @@ | |||||
package me.chanjar.weixin.open.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; | |||||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||||
import me.chanjar.weixin.open.api.WxOpenComponentService; | |||||
/** | |||||
* @author <a href="https://github.com/007gzs">007</a> | |||||
*/ | |||||
/* package */ class WxOpenMaServiceImpl extends WxMaServiceImpl { | |||||
private WxOpenComponentService wxOpenComponentService; | |||||
private WxMaConfig wxMaConfig; | |||||
private String appId; | |||||
public WxOpenMaServiceImpl(WxOpenComponentService wxOpenComponentService, String appId, WxMaConfig wxMaConfig) { | |||||
this.wxOpenComponentService = wxOpenComponentService; | |||||
this.appId = appId; | |||||
this.wxMaConfig = wxMaConfig; | |||||
initHttp(); | |||||
} | |||||
@Override | |||||
public WxMaConfig getWxMaConfig() { | |||||
return wxMaConfig; | |||||
} | |||||
@Override | |||||
public String getAccessToken(boolean forceRefresh) throws WxErrorException { | |||||
return wxOpenComponentService.getAuthorizerAccessToken(appId, forceRefresh); | |||||
} | |||||
} |
@@ -23,7 +23,6 @@ public class WxOpenAuthorizerInfo implements Serializable { | |||||
private Map<String, Integer> businessInfo; | private Map<String, Integer> businessInfo; | ||||
private String alias; | private String alias; | ||||
private String qrcodeUrl; | private String qrcodeUrl; | ||||
/** | /** | ||||
* 账号介绍 | * 账号介绍 | ||||
*/ | */ | ||||
@@ -0,0 +1,14 @@ | |||||
package me.chanjar.weixin.open.bean.auth; | |||||
import lombok.Data; | |||||
import org.apache.commons.lang3.tuple.Pair; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
@Data | |||||
public class WxOpenMiniProgramInfo { | |||||
private Map<String, List<String>> network; | |||||
private List<Pair<String, String>> categories; | |||||
private Integer visitStatus; | |||||
} |
@@ -15,4 +15,7 @@ public class WxOpenAuthorizerInfoResult implements Serializable { | |||||
private WxOpenAuthorizationInfo authorizationInfo; | private WxOpenAuthorizationInfo authorizationInfo; | ||||
private WxOpenAuthorizerInfo authorizerInfo; | private WxOpenAuthorizerInfo authorizerInfo; | ||||
public boolean isMiniProgram(){ | |||||
return authorizerInfo != null && authorizerInfo.getMiniProgramInfo() != null; | |||||
} | |||||
} | } |
@@ -23,6 +23,8 @@ public class WxOpenAuthorizerInfoGsonAdapter implements JsonDeserializer<WxOpenA | |||||
authorizationInfo.setPrincipalName(GsonHelper.getString(jsonObject, "principal_name")); | authorizationInfo.setPrincipalName(GsonHelper.getString(jsonObject, "principal_name")); | ||||
authorizationInfo.setAlias(GsonHelper.getString(jsonObject, "alias")); | authorizationInfo.setAlias(GsonHelper.getString(jsonObject, "alias")); | ||||
authorizationInfo.setQrcodeUrl(GsonHelper.getString(jsonObject, "qrcode_url")); | authorizationInfo.setQrcodeUrl(GsonHelper.getString(jsonObject, "qrcode_url")); | ||||
authorizationInfo.setSignature(GsonHelper.getString(jsonObject, "signature")); | |||||
if (jsonObject.has("service_type_info")) { | if (jsonObject.has("service_type_info")) { | ||||
authorizationInfo.setServiceTypeInfo(GsonHelper.getInteger(jsonObject.getAsJsonObject("service_type_info"), "id")); | authorizationInfo.setServiceTypeInfo(GsonHelper.getInteger(jsonObject.getAsJsonObject("service_type_info"), "id")); | ||||
} | } | ||||
@@ -33,11 +35,12 @@ public class WxOpenAuthorizerInfoGsonAdapter implements JsonDeserializer<WxOpenA | |||||
new TypeToken<Map<String, Integer>>() { | new TypeToken<Map<String, Integer>>() { | ||||
}.getType()); | }.getType()); | ||||
authorizationInfo.setBusinessInfo(businessInfo); | authorizationInfo.setBusinessInfo(businessInfo); | ||||
WxOpenAuthorizerInfo.MiniProgramInfo miniProgramInfo = WxOpenGsonBuilder.create().fromJson(jsonObject.get("MiniProgramInfo"), | |||||
new TypeToken<WxOpenAuthorizerInfo.MiniProgramInfo>() { | |||||
}.getType()); | |||||
authorizationInfo.setMiniProgramInfo(miniProgramInfo); | |||||
if (jsonObject.has("MiniProgramInfo")) { | |||||
WxOpenAuthorizerInfo.MiniProgramInfo miniProgramInfo = WxOpenGsonBuilder.create().fromJson(jsonObject.get("MiniProgramInfo"), | |||||
new TypeToken<WxOpenAuthorizerInfo.MiniProgramInfo>() { | |||||
}.getType()); | |||||
authorizationInfo.setMiniProgramInfo(miniProgramInfo); | |||||
} | |||||
return authorizationInfo; | return authorizationInfo; | ||||
} | } | ||||
} | } |