diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/WXAFacade.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/WXAFacade.java index 483abe1e..f596bee9 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/WXAFacade.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/WXAFacade.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.wxa; +import java.util.Properties; + import com.foxinmy.weixin4j.cache.CacheStorager; import com.foxinmy.weixin4j.cache.FileCacheStorager; import com.foxinmy.weixin4j.model.Token; @@ -49,18 +51,40 @@ public class WXAFacade { public WXAFacade( WeixinAccount weixinAccount, CacheStorager cacheStorager + ) { + this( + weixinAccount, + cacheStorager, + null + ); + } + + /** + * Constructs {@link WXAFacade} using specified {@link CacheStorager}, + * and overrides properties defined in {@code weixin.properties}. + * + * @param weixinAccount the {@link WeixinAccount}. + * @param cacheStorager the {@link CacheStorager}. + * @param properties properties to overrides the properties defined in {@code weixin.properties}. + */ + public WXAFacade( + WeixinAccount weixinAccount, + CacheStorager cacheStorager, + Properties properties ) { this( weixinAccount, new WeixinTokenCreator(weixinAccount.getId(), weixinAccount.getSecret()), - cacheStorager + cacheStorager, + properties ); } private WXAFacade( WeixinAccount weixinAccount, TokenCreator tokenCreator, - CacheStorager cacheStorager + CacheStorager cacheStorager, + Properties properties ) { if (weixinAccount == null) { throw new IllegalArgumentException( @@ -79,11 +103,11 @@ public class WXAFacade { final TokenManager tokenManager = new TokenManager(tokenCreator, cacheStorager); - this.loginApi = new LoginApi(weixinAccount); - this.qrCodeApi = new QrCodeApi(tokenManager); - this.templateApi = new TemplateApi(tokenManager); - this.templateMessageApi = new TemplateMessageApi(tokenManager); - this.customMessageApi = new CustomMessageApi(tokenManager); + this.loginApi = new LoginApi(weixinAccount, properties); + this.qrCodeApi = new QrCodeApi(tokenManager, properties); + this.templateApi = new TemplateApi(tokenManager, properties); + this.templateMessageApi = new TemplateMessageApi(tokenManager, properties); + this.customMessageApi = new CustomMessageApi(tokenManager, properties); } public LoginApi getLoginApi() { diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/CustomMessageApi.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/CustomMessageApi.java index 9764b936..4e36122a 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/CustomMessageApi.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/CustomMessageApi.java @@ -1,6 +1,7 @@ package com.foxinmy.weixin4j.wxa.api; import java.util.Map; +import java.util.Properties; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.token.TokenManager; @@ -18,6 +19,10 @@ public class CustomMessageApi extends TokenManagerApi { super(tokenManager); } + public CustomMessageApi(TokenManager tokenManager, Properties properties) { + super(tokenManager, properties); + } + /** * 发送客服消息。 * diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/LoginApi.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/LoginApi.java index ddb5500a..e41cf10c 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/LoginApi.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/LoginApi.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.wxa.api; +import java.util.Properties; + import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; @@ -16,6 +18,11 @@ public class LoginApi extends WxaApi { private final WeixinAccount weixinAccount; public LoginApi(WeixinAccount weixinAccount) { + this(weixinAccount, null); + } + + public LoginApi(WeixinAccount weixinAccount, Properties properties) { + super(properties); this.weixinAccount = weixinAccount; } diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/QrCodeApi.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/QrCodeApi.java index 85540a1a..9d523f13 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/QrCodeApi.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/QrCodeApi.java @@ -1,6 +1,7 @@ package com.foxinmy.weixin4j.wxa.api; import java.awt.Color; +import java.util.Properties; import com.alibaba.fastjson.JSON; import com.foxinmy.weixin4j.exception.WeixinException; @@ -22,7 +23,11 @@ import com.foxinmy.weixin4j.token.TokenManager; public class QrCodeApi extends TokenManagerApi { public QrCodeApi(TokenManager tokenManager) { - super(tokenManager); + this(tokenManager, null); + } + + public QrCodeApi(TokenManager tokenManager, Properties properties) { + super(tokenManager, properties); } /** diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TemplateApi.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TemplateApi.java index e1bd0fac..5096e179 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TemplateApi.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TemplateApi.java @@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.wxa.api; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.model.paging.Pageable; @@ -19,7 +20,11 @@ import com.foxinmy.weixin4j.wxa.model.template.Template; public class TemplateApi extends TokenManagerApi { public TemplateApi(TokenManager tokenManager) { - super(tokenManager); + this(tokenManager, null); + } + + public TemplateApi(TokenManager tokenManager, Properties properties) { + super(tokenManager, properties); } /** diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TemplateMessageApi.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TemplateMessageApi.java index 3424e529..7b3eb1b6 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TemplateMessageApi.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TemplateMessageApi.java @@ -1,6 +1,7 @@ package com.foxinmy.weixin4j.wxa.api; import java.util.Map; +import java.util.Properties; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.token.TokenManager; @@ -14,7 +15,11 @@ import com.foxinmy.weixin4j.token.TokenManager; public class TemplateMessageApi extends TokenManagerApi { public TemplateMessageApi(TokenManager tokenManager) { - super(tokenManager); + this(tokenManager, null); + } + + public TemplateMessageApi(TokenManager tokenManager, Properties properties) { + super(tokenManager, properties); } /** diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TokenManagerApi.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TokenManagerApi.java index 90a4365b..2bd26806 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TokenManagerApi.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/TokenManagerApi.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.wxa.api; +import java.util.Properties; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; @@ -11,6 +13,11 @@ abstract class TokenManagerApi extends WxaApi { private final TokenManager tokenManager; public TokenManagerApi(final TokenManager tokenManager) { + this(tokenManager, null); + } + + public TokenManagerApi(final TokenManager tokenManager, final Properties properties) { + super(properties); this.tokenManager = tokenManager; } diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/WxaApi.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/WxaApi.java index 2c6c89c3..a9a054c5 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/WxaApi.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/WxaApi.java @@ -1,6 +1,9 @@ package com.foxinmy.weixin4j.wxa.api; +import java.util.Properties; import java.util.ResourceBundle; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.foxinmy.weixin4j.api.BaseApi; @@ -16,11 +19,55 @@ abstract class WxaApi extends BaseApi { .getBundle("com/foxinmy/weixin4j/wxa/api/weixin"); } + private final Properties cache = new Properties(); + private final Properties properties; + private final Pattern uriPattern = Pattern.compile("(\\{[^\\}]*\\})"); + + public WxaApi() { + this(null); + } + + /** + * Constructs {@link WxaApi} with specified {@code properties}. + * + * @param properties the properties to override the {@link #weixinBundle()}. + */ + public WxaApi(Properties properties) { + this.properties = properties; + } + @Override protected ResourceBundle weixinBundle() { return WEIXIN_BUNDLE; } + @Override + protected String getRequestUri(String key) { + String url = this.cache.getProperty(key); + if (url != null) { + return url; + } + + if (this.properties != null && (url = this.properties.getProperty(key)) != null) { + Matcher m = uriPattern.matcher(url); + StringBuffer sb = new StringBuffer(); + String sub = null; + while (m.find()) { + sub = m.group(); + m.appendReplacement(sb, + getRequestUri(sub.substring(1, sub.length() - 1))); + } + m.appendTail(sb); + url = sb.toString(); + } else { + url = super.getRequestUri(key); + } + + this.cache.setProperty(key, url); + + return url; + } + String getRequestUri(String key, Object... args) { return String.format(getRequestUri(key), args); } diff --git a/weixin4j-wxa/src/test/java/com/foxinmy/weixin4j/wxa/api/WxaApiTest.java b/weixin4j-wxa/src/test/java/com/foxinmy/weixin4j/wxa/api/WxaApiTest.java new file mode 100644 index 00000000..83c3f6b4 --- /dev/null +++ b/weixin4j-wxa/src/test/java/com/foxinmy/weixin4j/wxa/api/WxaApiTest.java @@ -0,0 +1,57 @@ +package com.foxinmy.weixin4j.wxa.api; + +import static org.junit.Assert.assertEquals; + +import java.util.Properties; + +import org.junit.Test; + +import com.foxinmy.weixin4j.cache.FileCacheStorager; +import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.wxa.WXAFacade; + +public class WxaApiTest { + + @Test + public void testGetRequestUriStringObjectArrayDefault() { + WxaApi wxaApi = new WxaApi() { + }; + String uri = wxaApi.getRequestUri("sns_jscode2session", "myAppId", "mySecret", "myJsCode", "myGrantType"); + assertEquals("https://api.weixin.qq.com/sns/jscode2session?appid=myAppId&secret=mySecret&js_code=myJsCode&grant_type=myGrantType", uri); + } + + @Test + public void testGetRequestUriStringObjectArrayOverride() { + Properties properties = new Properties(); + properties.setProperty("api_base_url", "https://api.example.com"); + WxaApi wxaApi = new WxaApi(properties) { + }; + assertEquals( + "https://api.example.com/sns/jscode2session?appid=myAppId&secret=mySecret&js_code=myJsCode&grant_type=myGrantType", + wxaApi.getRequestUri("sns_jscode2session", "myAppId", "mySecret", "myJsCode", "myGrantType") + ); + } + + @Test + public void testFacadeWithProperties() { + Properties properties = new Properties(); + properties.setProperty("api_base_url", "https://api.example.com"); + properties.setProperty("api_cgi_url", "{api_base_url}/cgi-bin2"); + + WXAFacade wxaFacade = new WXAFacade(new WeixinAccount("myAppId", "mySecret"), new FileCacheStorager(), properties); + + assertEquals("https://api.example.com", wxaFacade.getLoginApi().getRequestUri("api_base_url")); + + assertEquals( + "https://api.example.com/sns/jscode2session?appid=myAppId&secret=mySecret&js_code=myJsCode&grant_type=myGrantType", + wxaFacade.getLoginApi().getRequestUri("sns_jscode2session", "myAppId", "mySecret", "myJsCode", "myGrantType") + ); + + assertEquals( + "https://api.example.com/cgi-bin2/wxopen/template/library/list?access_token=myAccessToken", + wxaFacade.getTemplateApi().getRequestUri("wxopen_template_library_list", "myAccessToken") + ); + } + +}