Skip to content

Commit fb6efe9

Browse files
committed
优化多公众号支持代码
1 parent d17bb25 commit fb6efe9

File tree

5 files changed

+116
-67
lines changed

5 files changed

+116
-67
lines changed

weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
66
import me.chanjar.weixin.common.util.http.RequestExecutor;
77
import me.chanjar.weixin.common.util.http.RequestHttp;
8+
import me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl;
89
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
910
import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo;
1011
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
@@ -304,42 +305,49 @@ public interface WxMpService {
304305
WxMpConfigStorage getWxMpConfigStorage();
305306

306307
/**
307-
* 注入 {@link WxMpConfigStorage} 的实现.
308+
* 设置 {@link WxMpConfigStorage} 的实现. 兼容老版本
308309
*/
309310
void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider);
310311

311312
/**
312-
* {@link Map<String, WxMpConfigStorage>} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信应用
313-
* @param configStorages
313+
* {@link Map<String, WxMpConfigStorage>} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信公众号配置
314+
* @param configStorage 新的微信配置
314315
*/
315-
void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages);
316+
void addConfigStorage(String mpId, WxMpConfigStorage configStorage);
316317

317318
/**
318-
* 从{@link Map<String, WxMpConfigStorage>} 移除 {@link String label} 所对应的 {@link WxMpConfigStorage},适用于动态移除的微信应用
319-
* @param label
319+
* 从{@link Map<String, WxMpConfigStorage>} 移除 {@link String mpId} 所对应的 {@link WxMpConfigStorage},适用于动态移除微信公众号配置
320+
* @param mpId 对应公众号的标识
320321
*/
321-
void removeWxMpConfigStorage(String label);
322+
void removeConfigStorage(String mpId);
322323

323324
/**
324-
* 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值
325-
* 随机采用一个{@link String lable}进行Http初始化操作
326-
* @param configStorages
325+
* 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String mpId} 值
326+
* 随机采用一个{@link String mpId}进行Http初始化操作
327+
* @param configStorages WxMpConfigStorage map
327328
*/
328-
void setMultiWxMpConfigStorage(Map<String, WxMpConfigStorage> configStorages);
329+
void setMultiConfigStorages(Map<String, WxMpConfigStorage> configStorages);
329330

330331
/**
331332
* 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值
332-
* @param configStorages
333-
* @param defaultInitLabel 设置一个{@link WxMpConfigStorage} 所对应的{@link String label}进行Http初始化
333+
* @param configStorages WxMpConfigStorage map
334+
* @param defaultMpId 设置一个{@link WxMpConfigStorage} 所对应的{@link String mpId}进行Http初始化
335+
*/
336+
void setMultiConfigStorages(Map<String, WxMpConfigStorage> configStorages, String defaultMpId);
337+
338+
/**
339+
* 进行相应的公众号切换
340+
* @param mpId 公众号标识
341+
* @return 切换是否成功
334342
*/
335-
void setMultiWxMpConfigStorage(Map<String, WxMpConfigStorage> configStorages, String defaultInitLabel);
343+
boolean switchover(String mpId);
336344

337345
/**
338-
* 进行相应的 WxApp 切换
339-
* @param label
340-
* @return
346+
* 进行相应的公众号切换
347+
* @param mpId 公众号标识
348+
* @return 切换成功,则返回当前对象,方便链式调用,否则抛出异常
341349
*/
342-
boolean switchover(String label);
350+
WxMpService switchover1(String mpId);
343351

344352
/**
345353
* 返回客服接口方法实现类,以方便调用其各个接口.

weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
package me.chanjar.weixin.mp.api.impl;
22

3-
import java.io.IOException;
4-
import java.util.HashMap;
5-
import java.util.concurrent.locks.Lock;
6-
7-
import me.chanjar.weixin.mp.api.*;
8-
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
9-
import org.apache.commons.lang3.StringUtils;
10-
import org.slf4j.Logger;
11-
import org.slf4j.LoggerFactory;
12-
3+
import com.google.common.collect.ImmutableMap;
4+
import com.google.common.collect.Maps;
135
import com.google.gson.JsonArray;
146
import com.google.gson.JsonElement;
157
import com.google.gson.JsonObject;
@@ -23,14 +15,21 @@
2315
import me.chanjar.weixin.common.util.RandomUtils;
2416
import me.chanjar.weixin.common.util.crypto.SHA1;
2517
import me.chanjar.weixin.common.util.http.*;
18+
import me.chanjar.weixin.mp.api.*;
2619
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
2720
import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo;
2821
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
2922
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
3023
import me.chanjar.weixin.mp.bean.result.WxMpUser;
3124
import me.chanjar.weixin.mp.enums.TicketType;
25+
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
26+
import org.apache.commons.lang3.StringUtils;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
3229

30+
import java.io.IOException;
3331
import java.util.Map;
32+
import java.util.concurrent.locks.Lock;
3433

3534
/**
3635
* 基础实现类.
@@ -63,12 +62,11 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
6362
private WxMpWifiService wifiService = new WxMpWifiServiceImpl(this);
6463
private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this);
6564

66-
private Map<String, WxMpConfigStorage> wxMpConfigStoragePool;
65+
private Map<String, WxMpConfigStorage> configStorageMap;
6766

6867
private int retrySleepMillis = 1000;
6968
private int maxRetryTimes = 5;
7069

71-
7270
@Override
7371
public boolean checkSignature(String timestamp, String nonce, String signature) {
7472
try {
@@ -335,52 +333,62 @@ public <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E da
335333

336334
@Override
337335
public WxMpConfigStorage getWxMpConfigStorage() {
338-
return wxMpConfigStoragePool.get(WxMpConfigStorageHolder.get());
336+
return this.configStorageMap.get(WxMpConfigStorageHolder.get());
339337
}
340338

341339
@Override
342340
public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) {
343-
Map<String, WxMpConfigStorage> map = new HashMap<>(1);
344-
map.put(WxMpConfigStorageHolder.get(), wxConfigProvider);
345-
setMultiWxMpConfigStorage(map, WxMpConfigStorageHolder.get());
341+
final String defaultMpId = WxMpConfigStorageHolder.get();
342+
this.setMultiConfigStorages(ImmutableMap.of(defaultMpId, wxConfigProvider), defaultMpId);
346343
}
347344

348345
@Override
349-
public void setMultiWxMpConfigStorage(Map<String, WxMpConfigStorage> configStorages) {
350-
String randomKey = configStorages.keySet().iterator().next();
351-
setMultiWxMpConfigStorage(configStorages, randomKey);
346+
public void setMultiConfigStorages(Map<String, WxMpConfigStorage> configStorages) {
347+
this.setMultiConfigStorages(configStorages, configStorages.keySet().iterator().next());
352348
}
353349

354350
@Override
355-
public void setMultiWxMpConfigStorage(Map<String, WxMpConfigStorage> configStorages, String defaultInitLabel) {
356-
wxMpConfigStoragePool = configStorages;
357-
WxMpConfigStorageHolder.set(defaultInitLabel);
351+
public void setMultiConfigStorages(Map<String, WxMpConfigStorage> configStorages, String defaultMpId) {
352+
this.configStorageMap = Maps.newHashMap(configStorages);
353+
WxMpConfigStorageHolder.set(defaultMpId);
358354
this.initHttp();
359355
}
360356

361357
@Override
362-
public void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages) {
358+
public void addConfigStorage(String mpId, WxMpConfigStorage configStorages) {
363359
synchronized (this) {
364-
if (wxMpConfigStoragePool.containsKey(label)) {
365-
throw new RuntimeException("该label已存在,请重新设置一个label");
360+
if (this.configStorageMap.containsKey(mpId)) {
361+
throw new RuntimeException("该公众号标识已存在,请更换其他标识!");
366362
}
367-
wxMpConfigStoragePool.put(label, configStorages);
363+
this.configStorageMap.put(mpId, configStorages);
368364
}
369365
}
370366

371367
@Override
372-
public void removeWxMpConfigStorage(String label) {
368+
public void removeConfigStorage(String mpId) {
373369
synchronized (this) {
374-
wxMpConfigStoragePool.remove(label);
370+
this.configStorageMap.remove(mpId);
375371
}
376372
}
377373

378374
@Override
379-
public boolean switchover(String label) {
380-
if (wxMpConfigStoragePool.containsKey(label)) {
381-
WxMpConfigStorageHolder.set(label);
375+
public WxMpService switchover1(String mpId) {
376+
if (this.configStorageMap.containsKey(mpId)) {
377+
WxMpConfigStorageHolder.set(mpId);
378+
return this;
379+
}
380+
381+
throw new RuntimeException(String.format("无法找到对应【%s】的公众号配置信息,请核实!", mpId));
382+
}
383+
384+
@Override
385+
public boolean switchover(String mpId) {
386+
if (this.configStorageMap.containsKey(mpId)) {
387+
WxMpConfigStorageHolder.set(mpId);
382388
return true;
383389
}
390+
391+
log.error("无法找到对应【{}】的公众号配置信息,请核实!", mpId);
384392
return false;
385393
}
386394

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package me.chanjar.weixin.mp.api.impl;
2+
3+
import com.google.inject.Inject;
4+
import me.chanjar.weixin.common.error.WxErrorException;
5+
import me.chanjar.weixin.mp.api.WxMpService;
6+
import me.chanjar.weixin.mp.api.test.ApiTestModule;
7+
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
8+
import org.testng.annotations.Guice;
9+
import org.testng.annotations.Test;
10+
11+
import static org.assertj.core.api.Assertions.assertThat;
12+
import static org.testng.Assert.assertFalse;
13+
import static org.testng.Assert.assertTrue;
14+
15+
/**
16+
* <pre>
17+
* Created by BinaryWang on 2019/3/29.
18+
* </pre>
19+
*
20+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
21+
*/
22+
@Test
23+
@Guice(modules = ApiTestModule.class)
24+
public class BaseWxMpServiceImplTest {
25+
@Inject
26+
private WxMpService wxService;
27+
28+
@Test
29+
public void testSwitchover() {
30+
assertTrue(this.wxService.switchover("another"));
31+
assertThat(WxMpConfigStorageHolder.get()).isEqualTo("another");
32+
assertFalse(this.wxService.switchover("whatever"));
33+
}
34+
35+
@Test
36+
public void testSwitchover1() throws WxErrorException {
37+
assertThat(this.wxService.switchover1("another").getAccessToken()).isNotEmpty();
38+
assertThat(WxMpConfigStorageHolder.get()).isEqualTo("another");
39+
}
40+
}

weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@
99
import me.chanjar.weixin.mp.api.test.ApiTestModule;
1010
import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult;
1111
import me.chanjar.weixin.mp.bean.menu.WxMpMenu;
12-
import org.testng.annotations.*;
12+
import org.testng.annotations.DataProvider;
13+
import org.testng.annotations.Guice;
14+
import org.testng.annotations.Test;
1315

14-
import static org.testng.Assert.*;
16+
import static org.testng.Assert.assertNotNull;
1517

1618
/**
1719
* 测试菜单
1820
*
1921
* @author chanjarster
2022
* @author Binary Wang
2123
*/
22-
@Test(groups = "menuAPI")
24+
@Test
2325
@Guice(modules = ApiTestModule.class)
2426
public class WxMpMenuServiceImplTest {
2527

@@ -85,9 +87,6 @@ public void testCreateConditionalMenu() throws WxErrorException {
8587
"}";
8688

8789
this.menuId = this.wxService.getMenuService().menuCreate(json);
88-
if (this.wxService.switchover("test-1")) {
89-
this.menuId = this.wxService.getMenuService().menuCreate(json);
90-
}
9190
System.out.println(this.menuId);
9291
}
9392

@@ -129,9 +128,7 @@ public void testMultiCreateConditionalMenu() throws WxErrorException {
129128
" \"language\":\"zh_CN\"\n" +
130129
" }\n" +
131130
"}";
132-
if (this.wxService.switchover("test-1")) {
133-
this.menuId = this.wxService.getMenuService().menuCreate(json);
134-
}
131+
this.menuId = this.wxService.getMenuService().menuCreate(json);
135132
System.out.println(this.menuId);
136133
}
137134

@@ -194,7 +191,7 @@ public void testMenuGet() throws WxErrorException {
194191
System.out.println(wxMenu.toJson());
195192
}
196193

197-
@Test(dependsOnMethods = {"testMenuGet","testMenuCreate"})
194+
@Test(dependsOnMethods = {"testMenuGet", "testMenuCreate"})
198195
public void testMenuDelete() throws WxErrorException {
199196
this.wxService.getMenuService().menuDelete();
200197
}

weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import java.io.IOException;
44
import java.io.InputStream;
5-
import java.util.HashMap;
6-
import java.util.Map;
75
import java.util.concurrent.locks.ReentrantLock;
86

97
import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl;
@@ -16,7 +14,6 @@
1614
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
1715
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
1816
import me.chanjar.weixin.mp.api.WxMpService;
19-
import me.chanjar.weixin.mp.api.impl.WxMpServiceOkHttpImpl;
2017

2118
public class ApiTestModule implements Module {
2219
private final Logger log = LoggerFactory.getLogger(this.getClass());
@@ -31,14 +28,13 @@ public void configure(Binder binder) {
3128

3229
TestConfigStorage config = this.fromXml(TestConfigStorage.class, inputStream);
3330
config.setAccessTokenLock(new ReentrantLock());
34-
WxMpService wxMpServiceMulti = new WxMpServiceHttpClientImpl();
31+
WxMpService mpService = new WxMpServiceHttpClientImpl();
3532

36-
// TODO 多WxAppId
37-
wxMpServiceMulti.setWxMpConfigStorage(config);
38-
wxMpServiceMulti.addWxMpConfigStorage("test-1", config);
33+
mpService.setWxMpConfigStorage(config);
34+
mpService.addConfigStorage("another", config);
3935

4036
binder.bind(WxMpConfigStorage.class).toInstance(config);
41-
binder.bind(WxMpService.class).toInstance(wxMpServiceMulti);
37+
binder.bind(WxMpService.class).toInstance(mpService);
4238
} catch (IOException e) {
4339
this.log.error(e.getMessage(), e);
4440
}

0 commit comments

Comments
 (0)