diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 01faeb840..d23afc640 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -12,7 +12,6 @@ import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.enums.TicketType; -import java.util.HashMap; import java.util.Map; /** @@ -309,12 +308,32 @@ public interface WxMpService { */ void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); + /** + * {@link Map} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信应用 + * @param configStorages + */ + void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages); + + /** + * 从{@link Map} 移除 {@link String label} 所对应的 {@link WxMpConfigStorage},适用于动态移除的微信应用 + * @param label + */ + void removeWxMpConfigStorage(String label); + /** * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 - * @return + * 随机采用一个{@link String lable}进行Http初始化操作 + * @param configStorages */ void setMultiWxMpConfigStorage(Map configStorages); + /** + * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 + * @param configStorages + * @param defaultInitLabel 设置一个{@link WxMpConfigStorage} 所对应的{@link String label}进行Http初始化 + */ + void setMultiWxMpConfigStorage(Map configStorages, String defaultInitLabel); + /** * 进行相应的 WxApp 切换 * @param label 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 1a313def5..59fcf7926 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 @@ -1,5 +1,15 @@ package me.chanjar.weixin.mp.api.impl; +import java.io.IOException; +import java.util.HashMap; +import java.util.concurrent.locks.Lock; + +import me.chanjar.weixin.mp.api.*; +import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -13,21 +23,14 @@ import me.chanjar.weixin.common.util.DataUtils; import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.http.*; -import me.chanjar.weixin.mp.api.*; import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.enums.TicketType; -import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.Map; -import java.util.concurrent.locks.Lock; /** * 基础实现类. @@ -40,7 +43,6 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH protected final Logger log = LoggerFactory.getLogger(this.getClass()); protected WxSessionManager sessionManager = new StandardSessionManager(); - protected WxMpConfigStorage wxMpConfigStorage; private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); @@ -62,7 +64,6 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this); private Map wxMpConfigStoragePool; - private boolean isMultiWxApp = false; private int retrySleepMillis = 1000; private int maxRetryTimes = 5; @@ -334,26 +335,46 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH @Override public WxMpConfigStorage getWxMpConfigStorage() { - if (isMultiWxApp) { - return wxMpConfigStoragePool.get(WxMpConfigStorageHolder.get()); - } - - return this.wxMpConfigStorage; + return wxMpConfigStoragePool.get(WxMpConfigStorageHolder.get()); } @Override public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { - this.wxMpConfigStorage = wxConfigProvider; - this.initHttp(); + Map map = new HashMap<>(1); + map.put(WxMpConfigStorageHolder.get(), wxConfigProvider); + setMultiWxMpConfigStorage(map, WxMpConfigStorageHolder.get()); } @Override public void setMultiWxMpConfigStorage(Map configStorages) { + String randomKey = configStorages.keySet().iterator().next(); + setMultiWxMpConfigStorage(configStorages, randomKey); + } + + @Override + public void setMultiWxMpConfigStorage(Map configStorages, String defaultInitLabel) { wxMpConfigStoragePool = configStorages; - isMultiWxApp = true; + WxMpConfigStorageHolder.set(defaultInitLabel); this.initHttp(); } + @Override + public void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages) { + synchronized (this) { + if (wxMpConfigStoragePool.containsKey(label)) { + throw new RuntimeException("该label已存在,请重新设置一个label"); + } + wxMpConfigStoragePool.put(label, configStorages); + } + } + + @Override + public void removeWxMpConfigStorage(String label) { + synchronized (this) { + wxMpConfigStoragePool.remove(label); + } + } + @Override public boolean switchover(String label) { if (wxMpConfigStoragePool.containsKey(label)) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java index e88fad142..89771250e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java @@ -6,6 +6,7 @@ import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; import okhttp3.*; @@ -66,6 +67,7 @@ public class WxMpServiceOkHttpImpl extends BaseWxMpServiceImpl 0) { httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(), diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java index f73bc37ca..af2f9226d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java @@ -7,7 +7,12 @@ package me.chanjar.weixin.mp.util; */ public class WxMpConfigStorageHolder { - private final static ThreadLocal WX_MP_CONFIG_STORAGE_CHOSE = new ThreadLocal<>(); + private final static ThreadLocal WX_MP_CONFIG_STORAGE_CHOSE = new ThreadLocal() { + @Override + protected String initialValue() { + return "default"; + } + }; public static String get() { return WX_MP_CONFIG_STORAGE_CHOSE.get(); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java index c25c946df..8afb9d095 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java @@ -85,6 +85,53 @@ public class WxMpMenuServiceImplTest { "}"; this.menuId = this.wxService.getMenuService().menuCreate(json); + if (this.wxService.switchover("test-1")) { + this.menuId = this.wxService.getMenuService().menuCreate(json); + } + System.out.println(this.menuId); + } + + @Test + public void testMultiCreateConditionalMenu() throws WxErrorException { + String json = "{\n" + + " \"button\":[\n" + + " { \n" + + " \"type\":\"click\",\n" + + " \"name\":\"今日歌曲\",\n" + + " \"key\":\"V1001_TODAY_MUSIC\" \n" + + " },\n" + + " { \n" + + " \"name\":\"菜单\",\n" + + " \"sub_button\":[\n" + + " { \n" + + " \"type\":\"view\",\n" + + " \"name\":\"搜索\",\n" + + " \"url\":\"http://www.soso.com/\"\n" + + " },\n" + + " {\n" + + " \"type\":\"view\",\n" + + " \"name\":\"视频\",\n" + + " \"url\":\"http://v.qq.com/\"\n" + + " },\n" + + " {\n" + + " \"type\":\"click\",\n" + + " \"name\":\"赞一下我们\",\n" + + " \"key\":\"V1001_GOOD\"\n" + + " }]\n" + + " }],\n" + + "\"matchrule\":{\n" + + " \"tag_id\":\"2\",\n" + + " \"sex\":\"1\",\n" + + " \"country\":\"中国\",\n" + + " \"province\":\"广东\",\n" + + " \"city\":\"广州\",\n" + + " \"client_platform_type\":\"2\",\n" + + " \"language\":\"zh_CN\"\n" + + " }\n" + + "}"; + if (this.wxService.switchover("test-1")) { + this.menuId = this.wxService.getMenuService().menuCreate(json); + } System.out.println(this.menuId); } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java index 98173f7d3..8d6a0d03b 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java @@ -2,6 +2,8 @@ package me.chanjar.weixin.mp.api.test; import java.io.IOException; import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.locks.ReentrantLock; import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; @@ -29,11 +31,14 @@ public class ApiTestModule implements Module { TestConfigStorage config = this.fromXml(TestConfigStorage.class, inputStream); config.setAccessTokenLock(new ReentrantLock()); - WxMpService wxService = new WxMpServiceHttpClientImpl(); - wxService.setWxMpConfigStorage(config); + WxMpService wxMpServiceMulti = new WxMpServiceHttpClientImpl(); + + // TODO 多WxAppId + wxMpServiceMulti.setWxMpConfigStorage(config); + wxMpServiceMulti.addWxMpConfigStorage("test-1", config); - binder.bind(WxMpService.class).toInstance(wxService); binder.bind(WxMpConfigStorage.class).toInstance(config); + binder.bind(WxMpService.class).toInstance(wxMpServiceMulti); } catch (IOException e) { this.log.error(e.getMessage(), e); }