mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-10-29 01:18:36 +08:00
#985 修复多WxApp场景下initHttp方法执行时的空指针异常错误
This commit is contained in:
@ -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<String, WxMpConfigStorage>} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信应用
|
||||
* @param configStorages
|
||||
*/
|
||||
void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages);
|
||||
|
||||
/**
|
||||
* 从{@link Map<String, WxMpConfigStorage>} 移除 {@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<String, WxMpConfigStorage> configStorages);
|
||||
|
||||
/**
|
||||
* 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值
|
||||
* @param configStorages
|
||||
* @param defaultInitLabel 设置一个{@link WxMpConfigStorage} 所对应的{@link String label}进行Http初始化
|
||||
*/
|
||||
void setMultiWxMpConfigStorage(Map<String, WxMpConfigStorage> configStorages, String defaultInitLabel);
|
||||
|
||||
/**
|
||||
* 进行相应的 WxApp 切换
|
||||
* @param label
|
||||
|
||||
@ -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<H, P> 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<H, P> implements WxMpService, RequestH
|
||||
private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this);
|
||||
|
||||
private Map<String, WxMpConfigStorage> wxMpConfigStoragePool;
|
||||
private boolean isMultiWxApp = false;
|
||||
|
||||
private int retrySleepMillis = 1000;
|
||||
private int maxRetryTimes = 5;
|
||||
@ -334,26 +335,46 @@ public abstract class BaseWxMpServiceImpl<H, P> 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<String, WxMpConfigStorage> map = new HashMap<>(1);
|
||||
map.put(WxMpConfigStorageHolder.get(), wxConfigProvider);
|
||||
setMultiWxMpConfigStorage(map, WxMpConfigStorageHolder.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMultiWxMpConfigStorage(Map<String, WxMpConfigStorage> configStorages) {
|
||||
String randomKey = configStorages.keySet().iterator().next();
|
||||
setMultiWxMpConfigStorage(configStorages, randomKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMultiWxMpConfigStorage(Map<String, WxMpConfigStorage> 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)) {
|
||||
|
||||
@ -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<OkHttpClient, OkH
|
||||
|
||||
@Override
|
||||
public void initHttp() {
|
||||
WxMpConfigStorage wxMpConfigStorage = getWxMpConfigStorage();
|
||||
//设置代理
|
||||
if (wxMpConfigStorage.getHttpProxyHost() != null && wxMpConfigStorage.getHttpProxyPort() > 0) {
|
||||
httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(),
|
||||
|
||||
@ -7,7 +7,12 @@ package me.chanjar.weixin.mp.util;
|
||||
*/
|
||||
public class WxMpConfigStorageHolder {
|
||||
|
||||
private final static ThreadLocal<String> WX_MP_CONFIG_STORAGE_CHOSE = new ThreadLocal<>();
|
||||
private final static ThreadLocal<String> WX_MP_CONFIG_STORAGE_CHOSE = new ThreadLocal<String>() {
|
||||
@Override
|
||||
protected String initialValue() {
|
||||
return "default";
|
||||
}
|
||||
};
|
||||
|
||||
public static String get() {
|
||||
return WX_MP_CONFIG_STORAGE_CHOSE.get();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user