diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/cache/CacheManager.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/cache/CacheManager.java index ff9d9485..b269e4a2 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/cache/CacheManager.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/cache/CacheManager.java @@ -15,70 +15,69 @@ import com.foxinmy.weixin4j.exception.WeixinException; * @see */ public class CacheManager { - protected final CacheCreator cacheCreator; - protected final CacheStorager cacheStorager; - private final ReentrantLock lock = new ReentrantLock(); + protected final CacheCreator cacheCreator; + protected final CacheStorager cacheStorager; + private final ReentrantLock lock = new ReentrantLock(); - public CacheManager(CacheCreator cacheCreator, - CacheStorager cacheStorager) { - this.cacheCreator = cacheCreator; - this.cacheStorager = cacheStorager; - } + public CacheManager(CacheCreator cacheCreator, CacheStorager cacheStorager) { + this.cacheCreator = cacheCreator; + this.cacheStorager = cacheStorager; + } - /** - * 获取缓存对象 - * - * @return 缓存对象 - * @throws WeixinException - */ - public T getCache() throws WeixinException { - String cacheKey = cacheCreator.key(); - T cache = cacheStorager.lookup(cacheKey); - try { - if (cache == null && lock.tryLock(3, TimeUnit.SECONDS)) { - try { - cache = cacheStorager.lookup(cacheKey); - if (cache == null) { - cache = cacheCreator.create(); - cacheStorager.caching(cacheKey, cache); - } - } finally { - lock.unlock(); - } - } - } catch (InterruptedException e) { - throw new WeixinException("get cache error on lock", e); - } - return cache; - } + /** + * 获取缓存对象 + * + * @return 缓存对象 + * @throws WeixinException + */ + public T getCache() throws WeixinException { + String cacheKey = cacheCreator.key(); + T cache = cacheStorager.lookup(cacheKey); + try { + if (cache == null && lock.tryLock(3, TimeUnit.SECONDS)) { + try { + cache = cacheStorager.lookup(cacheKey); + if (cache == null) { + cache = cacheCreator.create(); + cacheStorager.caching(cacheKey, cache); + } + } finally { + lock.unlock(); + } + } + } catch (InterruptedException e) { + throw new WeixinException("get cache error on lock", e); + } + return cache; + } - /** - * 刷新缓存对象 - * - * @return 缓存对象 - * @throws WeixinException - */ - public T refreshCache() throws WeixinException { - String cacheKey = cacheCreator.key(); - T cache = cacheCreator.create(); - cacheStorager.caching(cacheKey, cache); - return cache; - } + /** + * 刷新缓存对象 + * + * @return 缓存对象 + * @throws WeixinException + */ + public T refreshCache() throws WeixinException { + String cacheKey = cacheCreator.key(); + T cache = cacheCreator.create(); + cacheStorager.caching(cacheKey, cache); + return cache; + } - /** - * 移除缓存 - * - * @return 被移除的缓存对象 - */ - public T evictCache() { - String cacheKey = cacheCreator.key(); - return cacheStorager.evict(cacheKey); - } + /** + * 移除缓存 + * + * @return 被移除的缓存对象 + */ + public T evictCache() { + String cacheKey = cacheCreator.key(); + return cacheStorager.evict(cacheKey); + } - /** - * 清除所有的缓存(请慎重) - */ - public void clearCache() { - cacheStorager.clear(); - } + /** + * 清除所有的缓存(请慎重) + */ + public void clearCache() { + cacheStorager.clear(); + } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/jssdk/JSSDKConfigurator.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/jssdk/JSSDKConfigurator.java index c6531f48..cf8a39d5 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/jssdk/JSSDKConfigurator.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/jssdk/JSSDKConfigurator.java @@ -13,7 +13,6 @@ import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.MapUtil; import com.foxinmy.weixin4j.util.RandomUtil; import com.foxinmy.weixin4j.util.StringUtil; -import com.foxinmy.weixin4j.util.Weixin4jConfigUtil; /** * JSSDK配置类 @@ -25,106 +24,92 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil; * @see */ public class JSSDKConfigurator { - private final TokenManager ticketTokenManager; - private JSONObject config; - private Set apis; + private final TokenManager ticketTokenManager; + private JSONObject config; + private Set apis; - /** - * ticket保存类 可调用WeixinProxy#getTicketManager获取 - * - * @param ticketTokenManager - */ - public JSSDKConfigurator(TokenManager ticketTokenManager) { - this.ticketTokenManager = ticketTokenManager; - this.config = new JSONObject(); - this.apis = new HashSet(); - } + /** + * ticket保存类 可调用WeixinProxy#getTicketManager获取 + * + * @param ticketTokenManager + */ + public JSSDKConfigurator(TokenManager ticketTokenManager) { + this.ticketTokenManager = ticketTokenManager; + this.config = new JSONObject(); + this.apis = new HashSet(); + } - /** - * 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出, - * 仅在pc端时才会打印。 - * - * @return - */ - public JSSDKConfigurator debugMode() { - config.put("debug", true); - return this; - } + /** + * 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出, + * 仅在pc端时才会打印。 + * + * @return + */ + public JSSDKConfigurator debugMode() { + config.put("debug", true); + return this; + } - /** - * 公众号的唯一标识 不填则获取weixin4j.properties#account中的id - * - * @param appId - * @return - */ - public JSSDKConfigurator appId(String appId) { - config.put("appId", appId); - return this; - } + /** + * 需要使用的JS接口列表 + * + * @see JSSDKAPI + * @param apis + * @return + */ + public JSSDKConfigurator apis(JSSDKAPI... apis) { + for (JSSDKAPI api : apis) { + this.apis.add(api); + } + return this; + } - /** - * 需要使用的JS接口列表 - * - * @see JSSDKAPI - * @param apis - * @return - */ - public JSSDKConfigurator apis(JSSDKAPI... apis) { - for (JSSDKAPI api : apis) { - this.apis.add(api); - } - return this; - } + /** + * 需要使用的JS接口列表 + * + * @see JSSDKAPI + * @param apis + * @return + */ + public JSSDKConfigurator apis(JSSDKAPI[]... apis) { + for (JSSDKAPI[] api : apis) { + apis(api); + } + return this; + } - /** - * 需要使用的JS接口列表 - * - * @see JSSDKAPI - * @param apis - * @return - */ - public JSSDKConfigurator apis(JSSDKAPI[]... apis) { - for (JSSDKAPI[] api : apis) { - apis(api); - } - return this; - } - - /** - * 生成config配置JSON串 - * - * @param url - * 当前网页的URL,不包含#及其后面部分 - * @return jssdk配置JSON字符串 - * @see 公众号JSSDK - * @see 企业号JSSDK - * @throws WeixinException - */ - public String toJSONConfig(String url) throws WeixinException { - if (apis.isEmpty()) { - throw new WeixinException("jsapilist not be empty"); - } - Map signMap = new HashMap(); - String timestamp = DateUtil.timestamp2string(); - String noncestr = RandomUtil.generateString(24); - signMap.put("timestamp", timestamp); - signMap.put("noncestr", noncestr); - signMap.put("jsapi_ticket", this.ticketTokenManager.getAccessToken()); - signMap.put("url", url); - String sign = DigestUtil.SHA1(MapUtil.toJoinString(signMap, false, - false)); - if (StringUtil.isBlank(config.getString("appId"))) { - config.put("appId", Weixin4jConfigUtil.getWeixinAccount().getId()); - } - if (StringUtil.isBlank(config.getString("debug"))) { - config.put("debug", false); - } - config.put("timestamp", timestamp); - config.put("nonceStr", noncestr); - config.put("signature", sign); - config.put("jsApiList", apis.toArray()); - return config.toJSONString(); - } + /** + * 生成config配置JSON串 + * + * @param url + * 当前网页的URL,不包含#及其后面部分 + * @return jssdk配置JSON字符串 + * @see 公众号JSSDK + * @see 企业号JSSDK + * @throws WeixinException + */ + public String toJSONConfig(String url) throws WeixinException { + if (apis.isEmpty()) { + throw new WeixinException("jsapilist not be empty"); + } + Map signMap = new HashMap(); + String timestamp = DateUtil.timestamp2string(); + String noncestr = RandomUtil.generateString(24); + signMap.put("timestamp", timestamp); + signMap.put("noncestr", noncestr); + signMap.put("jsapi_ticket", this.ticketTokenManager.getAccessToken()); + signMap.put("url", url); + String sign = DigestUtil.SHA1(MapUtil.toJoinString(signMap, false, false)); + config.put("appId", ticketTokenManager.getWeixinId()); + if (StringUtil.isBlank(config.getString("debug"))) { + config.put("debug", false); + } + config.put("timestamp", timestamp); + config.put("nonceStr", noncestr); + config.put("signature", sign); + config.put("jsApiList", apis.toArray()); + return config.toJSONString(); + } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenCreator.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenCreator.java index 1cb70178..d16f73d2 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenCreator.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenCreator.java @@ -15,31 +15,38 @@ import com.foxinmy.weixin4j.model.Token; */ public abstract class TokenCreator implements CacheCreator { - /** - * 缓存KEY前缀 - */ - public final static String CACHEKEY_PREFIX = "weixin4j_"; + /** + * 缓存KEY前缀 + */ + public final static String CACHEKEY_PREFIX = "weixin4j_"; - protected final WeixinRequestExecutor weixinExecutor; + protected final WeixinRequestExecutor weixinExecutor; - public TokenCreator() { - this.weixinExecutor = new WeixinRequestExecutor(); - } + public TokenCreator() { + this.weixinExecutor = new WeixinRequestExecutor(); + } - /** - * 缓存key:附加key前缀 - * - * @return - */ - @Override - public String key() { - return String.format("%s%s", CACHEKEY_PREFIX, key0()); - } + /** + * 缓存key:附加key前缀 + * + * @return + */ + @Override + public String key() { + return String.format("%s%s_%s", CACHEKEY_PREFIX, name(), uniqueid()); + } - /** - * 返回缓存KEY的名称:建议接口类型命名 如 mp_token_{appid} - * - * @return - */ - public abstract String key0(); + /** + * 返回缓存类型命名,如mp_token + * + * @return + */ + public abstract String name(); + + /** + * 返回缓存唯一标识,如appid + * + * @return + */ + public abstract String uniqueid(); } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenManager.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenManager.java index 536299f7..64b2cb36 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenManager.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenManager.java @@ -16,25 +16,33 @@ import com.foxinmy.weixin4j.model.Token; * @see CacheStorager */ public class TokenManager extends CacheManager { - /** - * - * @param tokenCreator - * 负责微信各种token的创建 - * @param cacheStorager - * 负责token的存储 - */ - public TokenManager(TokenCreator tokenCreator, - CacheStorager cacheStorager) { - super(tokenCreator, cacheStorager); - } + /** + * + * @param tokenCreator + * 负责微信各种token的创建 + * @param cacheStorager + * 负责token的存储 + */ + public TokenManager(TokenCreator tokenCreator, CacheStorager cacheStorager) { + super(tokenCreator, cacheStorager); + } - /** - * 获取token字符串 - * - * @return token字符串 - * @throws WeixinException - */ - public String getAccessToken() throws WeixinException { - return super.getCache().getAccessToken(); - } + /** + * 获取token字符串 + * + * @return token字符串 + * @throws WeixinException + */ + public String getAccessToken() throws WeixinException { + return super.getCache().getAccessToken(); + } + + /** + * 返回唯一标识ID + * + * @return + */ + public String getWeixinId() { + return ((TokenCreator) cacheCreator).uniqueid(); + } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java index 7050b28f..c7ad245b 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java @@ -281,7 +281,7 @@ public class WeixinProxy { * @return */ public TokenManager getTicketManager(TicketType ticketType) { - return new TokenManager(new WeixinTicketCreator(weixinAccount.getId(), ticketType, this.tokenManager), + return new TokenManager(new WeixinTicketCreator(ticketType, this.tokenManager), this.cacheStorager); } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinComponentPreCodeCreator.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinComponentPreCodeCreator.java index 8d474542..dbe5419e 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinComponentPreCodeCreator.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinComponentPreCodeCreator.java @@ -18,32 +18,38 @@ import com.foxinmy.weixin4j.token.TokenManager; */ public class WeixinComponentPreCodeCreator extends TokenCreator { - private final TokenManager componentTokenManager; - private final String componentId; + private final TokenManager componentTokenManager; + private final String componentId; - /** - * - * @param componentTokenManager - * 应用套件的token - * @param componentId - * 应用组件ID - */ - public WeixinComponentPreCodeCreator(TokenManager componentTokenManager, String componentId) { - this.componentTokenManager = componentTokenManager; - this.componentId = componentId; - } + /** + * + * @param componentTokenManager + * 应用套件的token + * @param componentId + * 应用组件ID + */ + public WeixinComponentPreCodeCreator(TokenManager componentTokenManager, String componentId) { + this.componentTokenManager = componentTokenManager; + this.componentId = componentId; + } - @Override - public String key0() { - return String.format("mp_component_precode_%s", componentId); - } + @Override + public String name() { + return "mp_component_precode"; + } + + @Override + public String uniqueid() { + return componentId; + } + + @Override + public Token create() throws WeixinException { + WeixinResponse response = weixinExecutor.post( + String.format(URLConsts.COMPONENET_PRE_CODE_URL, componentTokenManager.getAccessToken()), + String.format("{\"component_appid\":\"%s\"}", componentId)); + JSONObject result = response.getAsJson(); + return new Token(result.getString("pre_auth_code"), result.getLongValue("expires_in") * 1000l); + } - @Override - public Token create() throws WeixinException { - WeixinResponse response = weixinExecutor.post( - String.format(URLConsts.COMPONENET_PRE_CODE_URL, componentTokenManager.getAccessToken()), - String.format("{\"component_appid\":\"%s\"}", componentId)); - JSONObject result = response.getAsJson(); - return new Token(result.getString("pre_auth_code"), result.getLongValue("expires_in") * 1000l); - } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinComponentTokenCreator.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinComponentTokenCreator.java index ee4a138f..acd184b0 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinComponentTokenCreator.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinComponentTokenCreator.java @@ -17,32 +17,35 @@ import com.foxinmy.weixin4j.token.TokenCreator; * @since JDK 1.6 */ public class WeixinComponentTokenCreator extends TokenCreator { - private final TicketManager ticketManager; + private final TicketManager ticketManager; - /** - * - * @param ticketManager - * 组件ticket存取 - */ - public WeixinComponentTokenCreator(TicketManager ticketManager) { - this.ticketManager = ticketManager; - } + /** + * + * @param ticketManager + * 组件ticket存取 + */ + public WeixinComponentTokenCreator(TicketManager ticketManager) { + this.ticketManager = ticketManager; + } - @Override - public String key0() { - return String.format("mp_component_token_%s", ticketManager.getThirdId()); - } + @Override + public String name() { + return "mp_component_token"; + } - @Override - public Token create() throws WeixinException { - JSONObject obj = new JSONObject(); - obj.put("component_appid", ticketManager.getThirdId()); - obj.put("component_appsecret", ticketManager.getThirdSecret()); - obj.put("component_verify_ticket", ticketManager.getAccessTicket()); - WeixinResponse response = weixinExecutor.post( - URLConsts.COMPONENT_TOKEN_URL, obj.toJSONString()); - obj = response.getAsJson(); - return new Token(obj.getString("component_access_token"), - obj.getLongValue("expires_in") * 1000l); - } + @Override + public String uniqueid() { + return ticketManager.getThirdId(); + } + + @Override + public Token create() throws WeixinException { + JSONObject obj = new JSONObject(); + obj.put("component_appid", ticketManager.getThirdId()); + obj.put("component_appsecret", ticketManager.getThirdSecret()); + obj.put("component_verify_ticket", ticketManager.getAccessTicket()); + WeixinResponse response = weixinExecutor.post(URLConsts.COMPONENT_TOKEN_URL, obj.toJSONString()); + obj = response.getAsJson(); + return new Token(obj.getString("component_access_token"), obj.getLongValue("expires_in") * 1000l); + } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinTokenComponentCreator.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinTokenComponentCreator.java index 1ba09a61..e0a8e554 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinTokenComponentCreator.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/component/WeixinTokenComponentCreator.java @@ -19,39 +19,43 @@ import com.foxinmy.weixin4j.token.TokenManager; */ public class WeixinTokenComponentCreator extends TokenCreator { - private final PerTicketManager perTicketManager; - private final TokenManager componentTokenManager; + private final PerTicketManager perTicketManager; + private final TokenManager componentTokenManager; - /** - * - * @param perTicketManager - * 第三方套件永久授权码 - * @param componentTokenManager - * 第三方套件凭证token - */ - public WeixinTokenComponentCreator(PerTicketManager perTicketManager, - TokenManager componentTokenManager) { - this.perTicketManager = perTicketManager; - this.componentTokenManager = componentTokenManager; - } + /** + * + * @param perTicketManager + * 第三方套件永久授权码 + * @param componentTokenManager + * 第三方套件凭证token + */ + public WeixinTokenComponentCreator(PerTicketManager perTicketManager, TokenManager componentTokenManager) { + this.perTicketManager = perTicketManager; + this.componentTokenManager = componentTokenManager; + } - @Override - public String key0() { - return String.format("mp_token_component_%s_%s", - perTicketManager.getThirdId(), perTicketManager.getAuthAppId()); - } + @Override + public String name() { + return String.format("mp_token_component_%s_%s", perTicketManager.getThirdId(), + perTicketManager.getAuthAppId()); + } + + @Override + public String uniqueid() { + throw new UnsupportedOperationException(); + } + + @Override + public Token create() throws WeixinException { + JSONObject obj = new JSONObject(); + obj.put("component_appid", perTicketManager.getThirdId()); + obj.put("authorizer_appid", perTicketManager.getAuthAppId()); + obj.put("authorizer_refresh_token", perTicketManager.getAccessTicket()); + WeixinResponse response = weixinExecutor.post( + String.format(URLConsts.TOKEN_COMPONENT_URL, componentTokenManager.getAccessToken()), + obj.toJSONString()); + obj = response.getAsJson(); + return new Token(obj.getString("access_token"), obj.getLongValue("expires_in") * 1000l); + } - @Override - public Token create() throws WeixinException { - JSONObject obj = new JSONObject(); - obj.put("component_appid", perTicketManager.getThirdId()); - obj.put("authorizer_appid", perTicketManager.getAuthAppId()); - obj.put("authorizer_refresh_token", perTicketManager.getAccessTicket()); - WeixinResponse response = weixinExecutor.post( - String.format(URLConsts.TOKEN_COMPONENT_URL, - componentTokenManager.getAccessToken()), obj.toJSONString()); - obj = response.getAsJson(); - return new Token(obj.getString("access_token"), - obj.getLongValue("expires_in") * 1000l); - } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/message/TemplateMessage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/message/TemplateMessage.java index ac6c820f..99d4c1c1 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/message/TemplateMessage.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/message/TemplateMessage.java @@ -15,175 +15,211 @@ import com.foxinmy.weixin4j.util.NameValue; * @author jinyu(foxinmy@gmail.com) * @date 2014年9月29日 * @since JDK 1.6 - * @see 模板消息 + * @see 模板消息 */ public class TemplateMessage implements Serializable { - private static final long serialVersionUID = 7950608393821661436L; + private static final long serialVersionUID = 7950608393821661436L; - /** - * 用户的openid - */ - @JSONField(name = "touser") - private String toUser; - /** - * 模板ID - */ - @JSONField(name = "template_id") - private String templateId; - /** - * 点击消息跳转的url - */ - private String url; - /** - * 头部信息(first第一行) - */ - @JSONField(serialize = false) - private NameValue head; - /** - * 尾部信息(remark最后行) - */ - @JSONField(serialize = false) - private NameValue tail; - /** - * 数据项 - */ - @JSONField(name = "data") - private Map content; + /** + * 用户的openid + */ + @JSONField(name = "touser") + private String toUser; + /** + * 模板ID + */ + @JSONField(name = "template_id") + private String templateId; + /** + * 点击消息跳转的url + */ + private String url; + /** + * 头部信息(first第一行) + */ + @JSONField(serialize = false) + private NameValue head; + /** + * 尾部信息(remark最后行) + */ + @JSONField(serialize = false) + private NameValue tail; - private final static String HEAD_KEY = "first"; - private final static String TAIL_KEY = "remark"; - private final static String DEFAULT_COLOR = "#173177"; + /** + * 跳小程序所需数据,不需跳小程序可不用传该数据 + */ + private String miniprogram; + /** + * 所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系) + */ + private String appid; + /** + * 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar) + */ + private String pagepath; - @JSONCreator - public TemplateMessage(@JSONField(name = "toUser") String toUser, - @JSONField(name = "templateId") String templateId, - @JSONField(name = "url") String url) { - this.toUser = toUser; - this.templateId = templateId; - this.url = url; - this.content = new HashMap(); - } + /** + * 数据项 + */ + @JSONField(name = "data") + private Map content; - public String getToUser() { - return toUser; - } + private final static String HEAD_KEY = "first"; + private final static String TAIL_KEY = "remark"; + private final static String DEFAULT_COLOR = "#173177"; - public String getTemplateId() { - return templateId; - } + @JSONCreator + public TemplateMessage(@JSONField(name = "toUser") String toUser, @JSONField(name = "templateId") String templateId, + @JSONField(name = "url") String url) { + this.toUser = toUser; + this.templateId = templateId; + this.url = url; + this.content = new HashMap(); + } - public String getUrl() { - return url; - } + public String getToUser() { + return toUser; + } - public NameValue getHead() { - return head == null ? content.get(HEAD_KEY) : head; - } + public String getTemplateId() { + return templateId; + } - public NameValue getTail() { - return tail == null ? content.get(TAIL_KEY) : tail; - } + public String getUrl() { + return url; + } - public Map getContent() { - return content; - } + public NameValue getHead() { + return head == null ? content.get(HEAD_KEY) : head; + } - /** - * 新增头部字段(默认颜色为#FF0000) - * - * @param text - * 字段文本 - * @return - */ - public TemplateMessage pushHead(String text) { - return pushHead("#FF0000", text); - } + public NameValue getTail() { + return tail == null ? content.get(TAIL_KEY) : tail; + } - /** - * 新增头部字段 - * - * @param color - * 文字颜色 - * @param text - * 字段文本 - * @return - */ - public TemplateMessage pushHead(String color, String text) { - head = new NameValue(color, text); - content.put(HEAD_KEY, head); - return this; - } + public Map getContent() { + return content; + } - /** - * 新增尾部字段(默认颜色为#173177) - * - * @param text - * 字段文本 - * @return - */ - public TemplateMessage pushTail(String text) { - return pushTail(DEFAULT_COLOR, text); - } + /** + * 新增头部字段(默认颜色为#FF0000) + * + * @param text + * 字段文本 + * @return + */ + public TemplateMessage pushHead(String text) { + return pushHead("#FF0000", text); + } - /** - * 新增尾部字段 - * - * @param color - * 文字颜色 - * @param text - * 字段文本 - * @return - */ - public TemplateMessage pushTail(String color, String text) { - tail = new NameValue(color, text); - content.put(TAIL_KEY, tail); - return this; - } + /** + * 新增头部字段 + * + * @param color + * 文字颜色 + * @param text + * 字段文本 + * @return + */ + public TemplateMessage pushHead(String color, String text) { + head = new NameValue(color, text); + content.put(HEAD_KEY, head); + return this; + } - /** - * 新增字段项(默认颜色为#173177) - * - * @param key - * 预留的字段名 - * @param text - * 字段文本 - * @return - */ - public TemplateMessage pushItem(String key, String text) { - return pushItem(key, DEFAULT_COLOR, text); - } + /** + * 新增尾部字段(默认颜色为#173177) + * + * @param text + * 字段文本 + * @return + */ + public TemplateMessage pushTail(String text) { + return pushTail(DEFAULT_COLOR, text); + } - /** - * 新增字段项 - * - * @param key - * 预留的字段名 - * @param color - * 文字颜色 - * @param text - * 字段文本 - * @return - */ - public TemplateMessage pushItem(String key, String color, String text) { - content.put(key, new NameValue(color, text)); - return this; - } + /** + * 新增尾部字段 + * + * @param color + * 文字颜色 + * @param text + * 字段文本 + * @return + */ + public TemplateMessage pushTail(String color, String text) { + tail = new NameValue(color, text); + content.put(TAIL_KEY, tail); + return this; + } - /** - * 设置所有字段项 - * - * @param items - */ - public void setItems(Map items) { - this.content = items; - } + /** + * 新增字段项(默认颜色为#173177) + * + * @param key + * 预留的字段名 + * @param text + * 字段文本 + * @return + */ + public TemplateMessage pushItem(String key, String text) { + return pushItem(key, DEFAULT_COLOR, text); + } - @Override - public String toString() { - return "TemplateMessage [toUser=" + toUser + ", templateId=" - + templateId + ", url=" + url + ", head=" + getHead() - + ", tail=" + getTail() + ", content=" + content + "]"; - } + /** + * 新增字段项 + * + * @param key + * 预留的字段名 + * @param color + * 文字颜色 + * @param text + * 字段文本 + * @return + */ + public TemplateMessage pushItem(String key, String color, String text) { + content.put(key, new NameValue(color, text)); + return this; + } + + /** + * 设置所有字段项 + * + * @param items + */ + public void setItems(Map items) { + this.content = items; + } + + public String getMiniprogram() { + return miniprogram; + } + + public void setMiniprogram(String miniprogram) { + this.miniprogram = miniprogram; + } + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getPagepath() { + return pagepath; + } + + public void setPagepath(String pagepath) { + this.pagepath = pagepath; + } + + @Override + public String toString() { + return "TemplateMessage [toUser=" + toUser + ", templateId=" + templateId + ", url=" + url + ", head=" + + getHead() + ", tail=" + getTail() + ", content=" + content + "]"; + } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/token/WeixinTicketCreator.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/token/WeixinTicketCreator.java index 1c724f3e..d2188ee4 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/token/WeixinTicketCreator.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/token/WeixinTicketCreator.java @@ -22,39 +22,37 @@ import com.foxinmy.weixin4j.type.TicketType; */ public class WeixinTicketCreator extends TokenCreator { - private final String appid; - private final TicketType ticketType; - private final TokenManager weixinTokenManager; + private final TicketType ticketType; + private final TokenManager weixinTokenManager; - /** - * jssdk - * - * @param appid - * 公众号的appid - * @param ticketType - * 票据类型 - * @param weixinTokenManager - * 公众平台的access_token - */ - public WeixinTicketCreator(String appid, TicketType ticketType, - TokenManager weixinTokenManager) { - this.appid = appid; - this.ticketType = ticketType; - this.weixinTokenManager = weixinTokenManager; - } + /** + * jssdk + * + * @param ticketType + * 票据类型 + * @param weixinTokenManager + * 公众平台的access_token + */ + public WeixinTicketCreator(TicketType ticketType, TokenManager weixinTokenManager) { + this.ticketType = ticketType; + this.weixinTokenManager = weixinTokenManager; + } - @Override - public String key0() { - return String.format("mp_ticket_%s_%s", ticketType.name(), appid); - } + @Override + public String name() { + return String.format("mp_ticket_%s", ticketType.name()); + } - @Override - public Token create() throws WeixinException { - WeixinResponse response = weixinExecutor.get(String.format( - URLConsts.JS_TICKET_URL, weixinTokenManager.getAccessToken(), - ticketType.name())); - JSONObject result = response.getAsJson(); - return new Token(result.getString("ticket"), - result.getLongValue("expires_in") * 1000l); - } + @Override + public String uniqueid() { + return weixinTokenManager.getWeixinId(); + } + + @Override + public Token create() throws WeixinException { + WeixinResponse response = weixinExecutor + .get(String.format(URLConsts.JS_TICKET_URL, weixinTokenManager.getAccessToken(), ticketType.name())); + JSONObject result = response.getAsJson(); + return new Token(result.getString("ticket"), result.getLongValue("expires_in") * 1000l); + } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/token/WeixinTokenCreator.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/token/WeixinTokenCreator.java index 7fb40e15..b6e9e4fe 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/token/WeixinTokenCreator.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/token/WeixinTokenCreator.java @@ -14,39 +14,42 @@ import com.foxinmy.weixin4j.token.TokenCreator; * @author jinyu(foxinmy@gmail.com) * @date 2015年1月10日 * @since JDK 1.6 - * @see 微信公众平台获取token说明 + * @see 微信公众平台获取token说明 * @see com.foxinmy.weixin4j.model.Token */ public class WeixinTokenCreator extends TokenCreator { - private final String appid; - private final String secret; + private final String appid; + private final String secret; - /** - * - * @param appid - * 公众号ID - * @param secret - * 公众号secret - */ - public WeixinTokenCreator(String appid, String secret) { - this.appid = appid; - this.secret = secret; - } + /** + * + * @param appid + * 公众号ID + * @param secret + * 公众号secret + */ + public WeixinTokenCreator(String appid, String secret) { + this.appid = appid; + this.secret = secret; + } - @Override - public String key0() { - return String.format("mp_token_%s", appid); - } + @Override + public String name() { + return "mp_token"; + } - @Override - public Token create() throws WeixinException { - String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, appid, - secret); - WeixinResponse response = weixinExecutor.get(tokenUrl); - JSONObject result = response.getAsJson(); - return new Token(result.getString("access_token"), - result.getLongValue("expires_in") * 1000l); - } + @Override + public String uniqueid() { + return appid; + } + + @Override + public Token create() throws WeixinException { + String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, appid, secret); + WeixinResponse response = weixinExecutor.get(tokenUrl); + JSONObject result = response.getAsJson(); + return new Token(result.getString("access_token"), result.getLongValue("expires_in") * 1000l); + } } diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java index cf4a401d..6c86695d 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java @@ -68,1386 +68,1352 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil; * @see api文档 */ public class WeixinProxy { - /** - * 授权API - */ - private final OauthApi oauthApi; - /** - * 媒体素材API - */ - private final MediaApi mediaApi; - /** - * 菜单API - */ - private final MenuApi menuApi; - /** - * 消息服务API - */ - private final NotifyApi notifyApi; - /** - * 部门API - */ - private final PartyApi partyApi; - /** - * 成员API - */ - private final UserApi userApi; - /** - * 标签API - */ - private final TagApi tagApi; - /** - * 辅助API - */ - private final HelperApi helperApi; - /** - * 应用API - */ - private final AgentApi agentApi; - /** - * 批量操作API - */ - private final BatchApi batchApi; - /** - * 聊天服务API - */ - private final ChatApi chatApi; - /** - * token管理 - */ - private final TokenManager tokenManager; - /** - * 账号信息 - */ - private final WeixinAccount weixinAccount; - /** - * token存储 - */ - private final CacheStorager cacheStorager; - - /** - * 微信接口实现(使用weixin4j.properties配置的account账号信息, - * 使用FileCacheStorager文件方式缓存TOKEN) - */ - public WeixinProxy() { - this(new FileCacheStorager()); - } - - /** - * 微信接口实现(使用weixin4j.properties配置的account账号信息) - * - * @param cacheStorager - * token管理 - */ - public WeixinProxy(CacheStorager cacheStorager) { - this(Weixin4jConfigUtil.getWeixinAccount(), cacheStorager); - } - - /** - * 微信接口实现 - * - * @param weixinAccount - * 账号信息 - * @param cacheStorager - * token管理 - */ - public WeixinProxy(WeixinAccount weixinAccount, - CacheStorager cacheStorager) { - this(weixinAccount, new WeixinTokenCreator(weixinAccount.getId(), - weixinAccount.getSecret()), cacheStorager); - } - - /** - * 第三方套件(永久授权码机制) - * - * @param perTicketManager - * 第三方套件永久授权码 - * {@link com.foxinmy.weixin4j.qy.api.SuiteApi#getPerCodeManager(String)} - * @param suiteTokenManager - * 第三方套件凭证token - * {@link com.foxinmy.weixin4j.qy.api.SuiteApi#getTokenManager} - * @see com.foxinmy.weixin4j.qy.api.SuiteApi - * @see WeixinSuiteProxy#getWeixinProxy(String, String) - */ - public WeixinProxy(PerTicketManager perTicketManager, - TokenManager suiteTokenManager) { - this( - new WeixinAccount(perTicketManager.getThirdId(), - perTicketManager.getThirdSecret()), - new WeixinTokenSuiteCreator(perTicketManager, suiteTokenManager), - perTicketManager.getCacheStorager()); - } - - /** - * 微信接口实现 - * - * @param settings - * 配置信息 - * @param tokenManager - * token管理 - */ - private WeixinProxy(WeixinAccount weixinAccount, TokenCreator tokenCreator, - CacheStorager cacheStorager) { - if (weixinAccount == null) { - throw new IllegalArgumentException( - "weixinAccount must not be empty"); - } - if (tokenCreator == null) { - throw new IllegalArgumentException("tokenCreator must not be empty"); - } - if (cacheStorager == null) { - throw new IllegalArgumentException( - "cacheStorager must not be empty"); - } - this.tokenManager = new TokenManager(tokenCreator, cacheStorager); - this.weixinAccount = weixinAccount; - this.cacheStorager = cacheStorager; - this.oauthApi = new OauthApi(weixinAccount); - this.partyApi = new PartyApi(tokenManager); - this.userApi = new UserApi(tokenManager); - this.tagApi = new TagApi(tokenManager); - this.helperApi = new HelperApi(tokenManager); - this.agentApi = new AgentApi(tokenManager); - this.batchApi = new BatchApi(tokenManager); - this.notifyApi = new NotifyApi(tokenManager); - this.menuApi = new MenuApi(tokenManager); - this.mediaApi = new MediaApi(tokenManager); - this.chatApi = new ChatApi(tokenManager); - } - - /** - * token获取 - * - * @return - */ - public TokenManager getTokenManager() { - return this.tokenManager; - } - - /** - * 获取oauth授权API - * - * @see com.foxinmy.weixin4j.qy.api.OauthApi - * @return - */ - public OauthApi getOauthApi() { - return oauthApi; - } - - /** - * 获取微信账号信息 - * - * @return - */ - public WeixinAccount getWeixinAccount() { - return weixinAccount; - } - - /** - * 获取JSSDK Ticket的tokenManager - * - * @param ticketType - * 票据类型 - * @return - */ - public TokenManager getTicketManager(TicketType ticketType) { - return new TokenManager(new WeixinTicketCreator(weixinAccount.getId(), - ticketType, this.tokenManager), cacheStorager); - } - - /** - * 发送消息提醒(需要管理员对应用有使用权限,对收件人touser、toparty、totag有查看权限,否则本次调用失败) - *

- * 1) 发送人员列表存在错误的userid:执行发送,开发者需注意返回结果说明
- * 2)发送人员不在通讯录权限范围内:不执行发送任务,返回首个出错的userid
- * 3)发送人员不在应用可见范围内:不执行发送任务,返回首个出错的userid
- *

- * - * @param message - * 消息对象 - * @return 如果对应用或收件人、部门、标签任何一个无权限,则本次发送失败;如果收件人、部门或标签不存在,发送仍然执行,但返回无效的部分 - *
{ "errcode": 0, "errmsg": "ok", "invaliduser": "UserID1", - * "invalidparty":"PartyID1", "invalidtag":"TagID1" } - * @throws WeixinException - * @see com.foxinmy.weixin4j.qy.api.NotifyApi - * @see - * 发送接口说明 - * @see - * 发送格式说明 - * @see com.foxinmy.weixin4j.tuple.Text - * @see com.foxinmy.weixin4j.tuple.Image - * @see com.foxinmy.weixin4j.tuple.Voice - * @see com.foxinmy.weixin4j.tuple.Video - * @see com.foxinmy.weixin4j.tuple.File - * @see com.foxinmy.weixin4j.tuple.News - * @see com.foxinmy.weixin4j.tuple.MpNews - * @see com.foxinmy.weixin4j.qy.model.IdParameter - */ - public IdParameter sendNotifyMessage(NotifyMessage message) - throws WeixinException { - return notifyApi.sendNotifyMessage(message); - } - - /** - * 发送客服消息 - * - * @param message - * 消息对象 - * @return 发送结果 - * @see - * 客服接口说明 - * @see com.foxinmy.weixin4j.qy.api.NotifyApi - * @see com.foxinmy.weixin4j.tuple.Text - * @see com.foxinmy.weixin4j.tuple.Image - * @see com.foxinmy.weixin4j.tuple.Voice - * @see com.foxinmy.weixin4j.tuple.Video - * @see com.foxinmy.weixin4j.tuple.File - * @see com.foxinmy.weixin4j.qy.message.CustomeMessage - * @throws WeixinException - */ - public ApiResult sendCustomeMessage(CustomeMessage message) - throws WeixinException { - return notifyApi.sendCustomeMessage(message); - } - - /** - * 获取客服列表 - * - * @param kfType - * 客服类型 为空时返回全部类型的客服 - * @return 第一个元素为内部客服(internal),第二个参数为外部客服(external) - * @see com.foxinmy.weixin4j.qy.api.NotifyApi - * @see com.foxinmy.weixin4j.qy.model.IdParameter - * @see - * 客服列表 - * @throws WeixinException - */ - public IdParameter[] getKfList(KfType kfType) throws WeixinException { - return notifyApi.getKfList(kfType); - } - - /** - * 自定义菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式) - * - * @param agentid - * 应用ID - * - * @param buttons - * 菜单列表 - * @throws WeixinException - * @see com.foxinmy.weixin4j.qy.api.MenuApi - * @see - * 创建自定义菜单 - * @see com.foxinmy.weixin4j.model.Button - */ - public ApiResult createMenu(int agentid, List