一、背景
客户生成服务器不允许访问外网,系统小程序登录等需要外网环境,现在使用squid代理访问外网环境,
微信小程序授权登录一直报错:
c.b.portal.servlet.ExceptionAdvice - java.net.UnknownHostException:
api.weixin.qq.com: Name or service not known
me.chanjar.weixin.common.error.WxRuntimeException: java.net.UnknownHostException:
api.weixin.qq.com: Name or service not known
at cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl.getAccessToken(BaseWxMaServiceImpl.java:161)
二、解决
内网服务器通过代理可以访问外网,正常访问请求,通过设置代理可以成功访问外网
System.setProperty("http.proxyHost", "10.4.4.100");
System.setProperty("http.proxyPort", "19191");
但是微信小程序设置不起作用,微信小程序需要单独配置代理地址和端口:
@Bean
public WxMaService wxMaService() {
// 代码里 getConfigs()处报错的同学,请注意仔细阅读项目说明,你的IDE需要引入lombok插件!!!!
final List<WxMaProperties.Config> configs = this.properties.getConfigs();
if (configs == null) {
throw new RuntimeException("配置文件异常");
}
Map<String, String> map = new HashMap<>();
WxMaService service = new WxMaServiceImpl();
service.setMultiConfigs(configs
.stream().map(a -> {
map.put(a.getAppId(), a.getName());
WxMaDefaultConfigImpl configStorage;
// TODO: 考虑优化redis
configStorage = new WxMaDefaultConfigImpl();
configStorage.setAppid(a.getAppId());
configStorage.setSecret(a.getSecret());
configStorage.setToken(a.getToken());
configStorage.setAesKey(a.getAesKey());
configStorage.setHttpProxyPort(a.getHttpProxyPort()); //代理地址
configStorage.setHttpProxyHost(a.getHttpProxyHost()); // 代理端口
return configStorage;
}).collect(Collectors.toMap(a -> map.get(a.getAppid()), a -> a, (o, n) -> o)));
return service;
}
配置类WxMpConfigStorage:
public interface WxMpConfigStorage {
/**
* Gets access token.
*
* @return the access token
*/
String getAccessToken();
/**
* Gets access token lock.
*
* @return the access token lock
*/
Lock getAccessTokenLock();
/**
* Is access token expired boolean.
*
* @return the boolean
*/
boolean isAccessTokenExpired();
/**
* 强制将access token过期掉.
*/
void expireAccessToken();
/**
* 应该是线程安全的.
*
* @param accessToken 要更新的WxAccessToken对象
*/
void updateAccessToken(WxAccessToken accessToken);
/**
* 应该是线程安全的.
*
* @param accessToken 新的accessToken值
* @param expiresInSeconds 过期时间,以秒为单位
*/
void updateAccessToken(String accessToken, int expiresInSeconds);
/**
* Gets ticket.
*
* @param type the type
* @return the ticket
*/
String getTicket(TicketType type);
/**
* Gets ticket lock.
*
* @param type the type
* @return the ticket lock
*/
Lock getTicketLock(TicketType type);
/**
* Is ticket expired boolean.
*
* @param type the type
* @return the boolean
*/
boolean isTicketExpired(TicketType type);
/**
* 强制将ticket过期掉.
*
* @param type the type
*/
void expireTicket(TicketType type);
/**
* 更新ticket.
* 应该是线程安全的
*
* @param type ticket类型
* @param ticket 新的ticket值
* @param expiresInSeconds 过期时间,以秒为单位
*/
void updateTicket(TicketType type, String ticket, int expiresInSeconds);
/**
* Gets app id.
*
* @return the app id
*/
String getAppId();
/**
* Gets secret.
*
* @return the secret
*/
String getSecret();
/**
* Gets token.
*
* @return the token
*/
String getToken();
/**
* Gets aes key.
*
* @return the aes key
*/
String getAesKey();
/**
* Gets template id.
*
* @return the template id
*/
String getTemplateId();
/**
* Gets expires time.
*
* @return the expires time
*/
long getExpiresTime();
/**
* Gets oauth 2 redirect uri.
*
* @return the oauth 2 redirect uri
*/
String getOauth2redirectUri();
/**
* Gets http proxy host.
*
* @return the http proxy host
*/
String getHttpProxyHost();
/**
* Gets http proxy port.
*
* @return the http proxy port
*/
int getHttpProxyPort();
/**
* Gets http proxy username.
*
* @return the http proxy username
*/
String getHttpProxyUsername();
/**
* Gets http proxy password.
*
* @return the http proxy password
*/
String getHttpProxyPassword();
/**
* http 请求重试间隔
* <pre>
* {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setRetrySleepMillis(int)}
* </pre>
*/
int getRetrySleepMillis();
/**
* http 请求最大重试次数
* <pre>
* {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setMaxRetryTimes(int)}
* </pre>
*/
int getMaxRetryTimes();
/**
* Gets tmp dir file.
*
* @return the tmp dir file
*/
File getTmpDirFile();
/**
* http client builder.
*
* @return ApacheHttpClientBuilder apache http client builder
*/
ApacheHttpClientBuilder getApacheHttpClientBuilder();
/**
* 是否自动刷新token.
*
* @return the boolean
*/
boolean autoRefreshToken();
/**
* 得到微信接口地址域名部分的自定义设置信息.
*
* @return the host config
*/
WxMpHostConfig getHostConfig();
/**
* 设置微信接口地址域名部分的自定义设置信息.
*
* @param hostConfig host config
*/
void setHostConfig(WxMpHostConfig hostConfig);
}
具体如何配置就不多说了,很简单,写配置类,创建wxService对象,注入MultiConfigs(我们的配置信息即可)。