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 d23afc64..4ccfe30a 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 @@ -5,6 +5,7 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl; import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; @@ -304,42 +305,49 @@ public interface WxMpService { WxMpConfigStorage getWxMpConfigStorage(); /** - * 注入 {@link WxMpConfigStorage} 的实现. + * 设置 {@link WxMpConfigStorage} 的实现. 兼容老版本 */ void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); /** - * {@link Map} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信应用 - * @param configStorages + * {@link Map} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信公众号配置 + * @param configStorage 新的微信配置 */ - void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages); + void addConfigStorage(String mpId, WxMpConfigStorage configStorage); /** - * 从{@link Map} 移除 {@link String label} 所对应的 {@link WxMpConfigStorage},适用于动态移除的微信应用 - * @param label + * 从{@link Map} 移除 {@link String mpId} 所对应的 {@link WxMpConfigStorage},适用于动态移除微信公众号配置 + * @param mpId 对应公众号的标识 */ - void removeWxMpConfigStorage(String label); + void removeConfigStorage(String mpId); /** - * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 - * 随机采用一个{@link String lable}进行Http初始化操作 - * @param configStorages + * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String mpId} 值 + * 随机采用一个{@link String mpId}进行Http初始化操作 + * @param configStorages WxMpConfigStorage map */ - void setMultiWxMpConfigStorage(Map configStorages); + void setMultiConfigStorages(Map configStorages); /** * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 - * @param configStorages - * @param defaultInitLabel 设置一个{@link WxMpConfigStorage} 所对应的{@link String label}进行Http初始化 + * @param configStorages WxMpConfigStorage map + * @param defaultMpId 设置一个{@link WxMpConfigStorage} 所对应的{@link String mpId}进行Http初始化 + */ + void setMultiConfigStorages(Map configStorages, String defaultMpId); + + /** + * 进行相应的公众号切换 + * @param mpId 公众号标识 + * @return 切换是否成功 */ - void setMultiWxMpConfigStorage(Map configStorages, String defaultInitLabel); + boolean switchover(String mpId); /** - * 进行相应的 WxApp 切换 - * @param label - * @return + * 进行相应的公众号切换 + * @param mpId 公众号标识 + * @return 切换成功,则返回当前对象,方便链式调用,否则抛出异常 */ - boolean switchover(String label); + WxMpService switchover1(String mpId); /** * 返回客服接口方法实现类,以方便调用其各个接口. 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 59fcf792..31b88f5f 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,15 +1,7 @@ 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.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -23,14 +15,21 @@ 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; /** * 基础实现类. @@ -63,12 +62,11 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH private WxMpWifiService wifiService = new WxMpWifiServiceImpl(this); private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this); - private Map wxMpConfigStoragePool; + private Map configStorageMap; private int retrySleepMillis = 1000; private int maxRetryTimes = 5; - @Override public boolean checkSignature(String timestamp, String nonce, String signature) { try { @@ -335,52 +333,62 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH @Override public WxMpConfigStorage getWxMpConfigStorage() { - return wxMpConfigStoragePool.get(WxMpConfigStorageHolder.get()); + return this.configStorageMap.get(WxMpConfigStorageHolder.get()); } @Override public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { - Map map = new HashMap<>(1); - map.put(WxMpConfigStorageHolder.get(), wxConfigProvider); - setMultiWxMpConfigStorage(map, WxMpConfigStorageHolder.get()); + final String defaultMpId = WxMpConfigStorageHolder.get(); + this.setMultiConfigStorages(ImmutableMap.of(defaultMpId, wxConfigProvider), defaultMpId); } @Override - public void setMultiWxMpConfigStorage(Map configStorages) { - String randomKey = configStorages.keySet().iterator().next(); - setMultiWxMpConfigStorage(configStorages, randomKey); + public void setMultiConfigStorages(Map configStorages) { + this.setMultiConfigStorages(configStorages, configStorages.keySet().iterator().next()); } @Override - public void setMultiWxMpConfigStorage(Map configStorages, String defaultInitLabel) { - wxMpConfigStoragePool = configStorages; - WxMpConfigStorageHolder.set(defaultInitLabel); + public void setMultiConfigStorages(Map configStorages, String defaultMpId) { + this.configStorageMap = Maps.newHashMap(configStorages); + WxMpConfigStorageHolder.set(defaultMpId); this.initHttp(); } @Override - public void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages) { + public void addConfigStorage(String mpId, WxMpConfigStorage configStorages) { synchronized (this) { - if (wxMpConfigStoragePool.containsKey(label)) { - throw new RuntimeException("该label已存在,请重新设置一个label"); + if (this.configStorageMap.containsKey(mpId)) { + throw new RuntimeException("该公众号标识已存在,请更换其他标识!"); } - wxMpConfigStoragePool.put(label, configStorages); + this.configStorageMap.put(mpId, configStorages); } } @Override - public void removeWxMpConfigStorage(String label) { + public void removeConfigStorage(String mpId) { synchronized (this) { - wxMpConfigStoragePool.remove(label); + this.configStorageMap.remove(mpId); } } @Override - public boolean switchover(String label) { - if (wxMpConfigStoragePool.containsKey(label)) { - WxMpConfigStorageHolder.set(label); + public WxMpService switchover1(String mpId) { + if (this.configStorageMap.containsKey(mpId)) { + WxMpConfigStorageHolder.set(mpId); + return this; + } + + throw new RuntimeException(String.format("无法找到对应【%s】的公众号配置信息,请核实!", mpId)); + } + + @Override + public boolean switchover(String mpId) { + if (this.configStorageMap.containsKey(mpId)) { + WxMpConfigStorageHolder.set(mpId); return true; } + + log.error("无法找到对应【{}】的公众号配置信息,请核实!", mpId); return false; } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java new file mode 100644 index 00000000..52dfbb9e --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.test.ApiTestModule; +import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +/** + *
+ *  Created by BinaryWang on 2019/3/29.
+ * 
+ * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class BaseWxMpServiceImplTest { + @Inject + private WxMpService wxService; + + @Test + public void testSwitchover() { + assertTrue(this.wxService.switchover("another")); + assertThat(WxMpConfigStorageHolder.get()).isEqualTo("another"); + assertFalse(this.wxService.switchover("whatever")); + } + + @Test + public void testSwitchover1() throws WxErrorException { + assertThat(this.wxService.switchover1("another").getAccessToken()).isNotEmpty(); + assertThat(WxMpConfigStorageHolder.get()).isEqualTo("another"); + } +} 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 8afb9d09..45c5e8af 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 @@ -9,9 +9,11 @@ import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; import me.chanjar.weixin.mp.bean.menu.WxMpMenu; -import org.testng.annotations.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.testng.Assert.assertNotNull; /** * 测试菜单 @@ -19,7 +21,7 @@ import static org.testng.Assert.*; * @author chanjarster * @author Binary Wang */ -@Test(groups = "menuAPI") +@Test @Guice(modules = ApiTestModule.class) public class WxMpMenuServiceImplTest { @@ -85,9 +87,6 @@ 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); } @@ -129,9 +128,7 @@ public class WxMpMenuServiceImplTest { " \"language\":\"zh_CN\"\n" + " }\n" + "}"; - if (this.wxService.switchover("test-1")) { - this.menuId = this.wxService.getMenuService().menuCreate(json); - } + this.menuId = this.wxService.getMenuService().menuCreate(json); System.out.println(this.menuId); } @@ -194,7 +191,7 @@ public class WxMpMenuServiceImplTest { System.out.println(wxMenu.toJson()); } - @Test(dependsOnMethods = {"testMenuGet","testMenuCreate"}) + @Test(dependsOnMethods = {"testMenuGet", "testMenuCreate"}) public void testMenuDelete() throws WxErrorException { this.wxService.getMenuService().menuDelete(); } 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 8d6a0d03..29c8d2e2 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,8 +2,6 @@ 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; @@ -16,7 +14,6 @@ import com.thoughtworks.xstream.XStream; import me.chanjar.weixin.common.util.xml.XStreamInitializer; import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.impl.WxMpServiceOkHttpImpl; public class ApiTestModule implements Module { private final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -31,14 +28,13 @@ public class ApiTestModule implements Module { TestConfigStorage config = this.fromXml(TestConfigStorage.class, inputStream); config.setAccessTokenLock(new ReentrantLock()); - WxMpService wxMpServiceMulti = new WxMpServiceHttpClientImpl(); + WxMpService mpService = new WxMpServiceHttpClientImpl(); - // TODO 多WxAppId - wxMpServiceMulti.setWxMpConfigStorage(config); - wxMpServiceMulti.addWxMpConfigStorage("test-1", config); + mpService.setWxMpConfigStorage(config); + mpService.addConfigStorage("another", config); binder.bind(WxMpConfigStorage.class).toInstance(config); - binder.bind(WxMpService.class).toInstance(wxMpServiceMulti); + binder.bind(WxMpService.class).toInstance(mpService); } catch (IOException e) { this.log.error(e.getMessage(), e); }