| @@ -7,8 +7,8 @@ import java.io.File; | |||
| /** | |||
| * 微信客户端配置存储 | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public interface WxCpConfigStorage { | |||
| @@ -36,12 +36,13 @@ public interface WxCpConfigStorage { | |||
| /** | |||
| * 应该是线程安全的 | |||
| * | |||
| * @param jsapiTicket | |||
| */ | |||
| void updateJsapiTicket(String jsapiTicket, int expiresInSeconds); | |||
| String getCorpId(); | |||
| String getCorpSecret(); | |||
| String getAgentId(); | |||
| @@ -61,11 +62,12 @@ public interface WxCpConfigStorage { | |||
| String getHttp_proxy_username(); | |||
| String getHttp_proxy_password(); | |||
| File getTmpDirFile(); | |||
| /** | |||
| * http client builder | |||
| * | |||
| * @return ApacheHttpClientBuilder | |||
| */ | |||
| ApacheHttpClientBuilder getApacheHttpClientBuilder(); | |||
| @@ -7,8 +7,8 @@ import java.io.File; | |||
| /** | |||
| * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
| @@ -39,6 +39,10 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
| return this.accessToken; | |||
| } | |||
| public void setAccessToken(String accessToken) { | |||
| this.accessToken = accessToken; | |||
| } | |||
| public boolean isAccessTokenExpired() { | |||
| return System.currentTimeMillis() > this.expiresTime; | |||
| } | |||
| @@ -50,7 +54,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
| public synchronized void updateAccessToken(WxAccessToken accessToken) { | |||
| updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
| } | |||
| public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { | |||
| this.accessToken = accessToken; | |||
| this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l; | |||
| @@ -91,28 +95,32 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
| return this.corpId; | |||
| } | |||
| public void setCorpId(String corpId) { | |||
| this.corpId = corpId; | |||
| } | |||
| public String getCorpSecret() { | |||
| return this.corpSecret; | |||
| } | |||
| public String getToken() { | |||
| return this.token; | |||
| public void setCorpSecret(String corpSecret) { | |||
| this.corpSecret = corpSecret; | |||
| } | |||
| public long getExpiresTime() { | |||
| return this.expiresTime; | |||
| public String getToken() { | |||
| return this.token; | |||
| } | |||
| public void setCorpId(String corpId) { | |||
| this.corpId = corpId; | |||
| public void setToken(String token) { | |||
| this.token = token; | |||
| } | |||
| public void setCorpSecret(String corpSecret) { | |||
| this.corpSecret = corpSecret; | |||
| public long getExpiresTime() { | |||
| return this.expiresTime; | |||
| } | |||
| public void setToken(String token) { | |||
| this.token = token; | |||
| public void setExpiresTime(long expiresTime) { | |||
| this.expiresTime = expiresTime; | |||
| } | |||
| public String getAesKey() { | |||
| @@ -123,14 +131,6 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
| this.aesKey = aesKey; | |||
| } | |||
| public void setAccessToken(String accessToken) { | |||
| this.accessToken = accessToken; | |||
| } | |||
| public void setExpiresTime(long expiresTime) { | |||
| this.expiresTime = expiresTime; | |||
| } | |||
| public String getAgentId() { | |||
| return agentId; | |||
| } | |||
| @@ -183,21 +183,21 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
| @Override | |||
| public String toString() { | |||
| return "WxCpInMemoryConfigStorage{" + | |||
| "corpId='" + corpId + '\'' + | |||
| ", corpSecret='" + corpSecret + '\'' + | |||
| ", token='" + token + '\'' + | |||
| ", accessToken='" + accessToken + '\'' + | |||
| ", aesKey='" + aesKey + '\'' + | |||
| ", agentId='" + agentId + '\'' + | |||
| ", expiresTime=" + expiresTime + | |||
| ", http_proxy_host='" + http_proxy_host + '\'' + | |||
| ", http_proxy_port=" + http_proxy_port + | |||
| ", http_proxy_username='" + http_proxy_username + '\'' + | |||
| ", http_proxy_password='" + http_proxy_password + '\'' + | |||
| ", jsapiTicket='" + jsapiTicket + '\'' + | |||
| ", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' + | |||
| ", tmpDirFile='" + tmpDirFile + '\'' + | |||
| '}'; | |||
| "corpId='" + corpId + '\'' + | |||
| ", corpSecret='" + corpSecret + '\'' + | |||
| ", token='" + token + '\'' + | |||
| ", accessToken='" + accessToken + '\'' + | |||
| ", aesKey='" + aesKey + '\'' + | |||
| ", agentId='" + agentId + '\'' + | |||
| ", expiresTime=" + expiresTime + | |||
| ", http_proxy_host='" + http_proxy_host + '\'' + | |||
| ", http_proxy_port=" + http_proxy_port + | |||
| ", http_proxy_username='" + http_proxy_username + '\'' + | |||
| ", http_proxy_password='" + http_proxy_password + '\'' + | |||
| ", jsapiTicket='" + jsapiTicket + '\'' + | |||
| ", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' + | |||
| ", tmpDirFile='" + tmpDirFile + '\'' + | |||
| '}'; | |||
| } | |||
| public File getTmpDirFile() { | |||
| @@ -1,7 +1,6 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.session.WxSession; | |||
| import me.chanjar.weixin.common.session.WxSessionManager; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
| @@ -1,13 +1,13 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | |||
| import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; | |||
| import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; | |||
| import me.chanjar.weixin.common.session.InternalSession; | |||
| import me.chanjar.weixin.common.session.InternalSessionManager; | |||
| import me.chanjar.weixin.common.session.StandardSessionManager; | |||
| import me.chanjar.weixin.common.session.WxSessionManager; | |||
| import me.chanjar.weixin.common.util.LogExceptionHandler; | |||
| import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | |||
| import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; | |||
| import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
| import org.slf4j.Logger; | |||
| @@ -45,15 +45,13 @@ import java.util.concurrent.Future; | |||
| * router.route(message); | |||
| * | |||
| * </pre> | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class WxCpMessageRouter { | |||
| protected final Logger log = LoggerFactory.getLogger(WxCpMessageRouter.class); | |||
| private static final int DEFAULT_THREAD_POOL_SIZE = 100; | |||
| protected final Logger log = LoggerFactory.getLogger(WxCpMessageRouter.class); | |||
| private final List<WxCpMessageRouterRule> rules = new ArrayList<WxCpMessageRouterRule>(); | |||
| private final WxCpService wxCpService; | |||
| @@ -79,6 +77,7 @@ public class WxCpMessageRouter { | |||
| * 设置自定义的 {@link ExecutorService} | |||
| * 如果不调用该方法,默认使用 Executors.newFixedThreadPool(100) | |||
| * </pre> | |||
| * | |||
| * @param executorService | |||
| */ | |||
| public void setExecutorService(ExecutorService executorService) { | |||
| @@ -90,6 +89,7 @@ public class WxCpMessageRouter { | |||
| * 设置自定义的 {@link me.chanjar.weixin.common.api.WxMessageDuplicateChecker} | |||
| * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker} | |||
| * </pre> | |||
| * | |||
| * @param messageDuplicateChecker | |||
| */ | |||
| public void setMessageDuplicateChecker(WxMessageDuplicateChecker messageDuplicateChecker) { | |||
| @@ -101,6 +101,7 @@ public class WxCpMessageRouter { | |||
| * 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager} | |||
| * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.session.StandardSessionManager} | |||
| * </pre> | |||
| * | |||
| * @param sessionManager | |||
| */ | |||
| public void setSessionManager(WxSessionManager sessionManager) { | |||
| @@ -112,6 +113,7 @@ public class WxCpMessageRouter { | |||
| * 设置自定义的{@link me.chanjar.weixin.common.api.WxErrorExceptionHandler} | |||
| * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler} | |||
| * </pre> | |||
| * | |||
| * @param exceptionHandler | |||
| */ | |||
| public void setExceptionHandler(WxErrorExceptionHandler exceptionHandler) { | |||
| @@ -131,6 +133,7 @@ public class WxCpMessageRouter { | |||
| /** | |||
| * 处理微信消息 | |||
| * | |||
| * @param wxMessage | |||
| */ | |||
| public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) { | |||
| @@ -144,7 +147,7 @@ public class WxCpMessageRouter { | |||
| for (final WxCpMessageRouterRule rule : rules) { | |||
| if (rule.test(wxMessage)) { | |||
| matchRules.add(rule); | |||
| if(!rule.isReEnter()) { | |||
| if (!rule.isReEnter()) { | |||
| break; | |||
| } | |||
| } | |||
| @@ -158,13 +161,13 @@ public class WxCpMessageRouter { | |||
| final List<Future> futures = new ArrayList<Future>(); | |||
| for (final WxCpMessageRouterRule rule : matchRules) { | |||
| // 返回最后一个非异步的rule的执行结果 | |||
| if(rule.isAsync()) { | |||
| if (rule.isAsync()) { | |||
| futures.add( | |||
| executorService.submit(new Runnable() { | |||
| public void run() { | |||
| rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||
| } | |||
| }) | |||
| executorService.submit(new Runnable() { | |||
| public void run() { | |||
| rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||
| } | |||
| }) | |||
| ); | |||
| } else { | |||
| res = rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||
| @@ -201,10 +204,10 @@ public class WxCpMessageRouter { | |||
| String messageId = ""; | |||
| if (wxMessage.getMsgId() == null) { | |||
| messageId = String.valueOf(wxMessage.getCreateTime()) | |||
| + "-" +String.valueOf(wxMessage.getAgentId() == null ? "" : wxMessage.getAgentId()) | |||
| + "-" + wxMessage.getFromUserName() | |||
| + "-" + String.valueOf(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey()) | |||
| + "-" + String.valueOf(wxMessage.getEvent() == null ? "" : wxMessage.getEvent()) | |||
| + "-" + String.valueOf(wxMessage.getAgentId() == null ? "" : wxMessage.getAgentId()) | |||
| + "-" + wxMessage.getFromUserName() | |||
| + "-" + String.valueOf(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey()) | |||
| + "-" + String.valueOf(wxMessage.getEvent() == null ? "" : wxMessage.getEvent()) | |||
| ; | |||
| } else { | |||
| messageId = String.valueOf(wxMessage.getMsgId()); | |||
| @@ -216,11 +219,12 @@ public class WxCpMessageRouter { | |||
| /** | |||
| * 对session的访问结束 | |||
| * | |||
| * @param wxMessage | |||
| */ | |||
| protected void sessionEndAccess(WxCpXmlMessage wxMessage) { | |||
| InternalSession session = ((InternalSessionManager)sessionManager).findSession(wxMessage.getFromUserName()); | |||
| InternalSession session = ((InternalSessionManager) sessionManager).findSession(wxMessage.getFromUserName()); | |||
| if (session != null) { | |||
| session.endAccess(); | |||
| } | |||
| @@ -1,8 +1,8 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.session.WxSessionManager; | |||
| import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
| @@ -186,7 +186,6 @@ public class WxCpMessageRouterRule { | |||
| /** | |||
| * 规则结束,代表如果一个消息匹配该规则,那么它将不再会进入其他规则 | |||
| * | |||
| */ | |||
| public WxCpMessageRouter end() { | |||
| this.routerBuilder.getRules().add(this); | |||
| @@ -195,7 +194,6 @@ public class WxCpMessageRouterRule { | |||
| /** | |||
| * 规则结束,但是消息还会进入其他规则 | |||
| * | |||
| */ | |||
| public WxCpMessageRouter next() { | |||
| this.reEnter = true; | |||
| @@ -204,24 +202,24 @@ public class WxCpMessageRouterRule { | |||
| protected boolean test(WxCpXmlMessage wxMessage) { | |||
| return | |||
| (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) | |||
| && | |||
| (this.agentId == null || this.agentId.equals(wxMessage.getAgentId())) | |||
| && | |||
| (this.msgType == null || this.msgType.equals(wxMessage.getMsgType())) | |||
| && | |||
| (this.event == null || this.event.equals(wxMessage.getEvent())) | |||
| && | |||
| (this.eventKey == null || this.eventKey.equals(wxMessage.getEventKey())) | |||
| && | |||
| (this.content == null || this.content | |||
| .equals(wxMessage.getContent() == null ? null : wxMessage.getContent().trim())) | |||
| && | |||
| (this.rContent == null || Pattern | |||
| .matches(this.rContent, wxMessage.getContent() == null ? "" : wxMessage.getContent().trim())) | |||
| && | |||
| (this.matcher == null || this.matcher.match(wxMessage)) | |||
| ; | |||
| (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) | |||
| && | |||
| (this.agentId == null || this.agentId.equals(wxMessage.getAgentId())) | |||
| && | |||
| (this.msgType == null || this.msgType.equals(wxMessage.getMsgType())) | |||
| && | |||
| (this.event == null || this.event.equals(wxMessage.getEvent())) | |||
| && | |||
| (this.eventKey == null || this.eventKey.equals(wxMessage.getEventKey())) | |||
| && | |||
| (this.content == null || this.content | |||
| .equals(wxMessage.getContent() == null ? null : wxMessage.getContent().trim())) | |||
| && | |||
| (this.rContent == null || Pattern | |||
| .matches(this.rContent, wxMessage.getContent() == null ? "" : wxMessage.getContent().trim())) | |||
| && | |||
| (this.matcher == null || this.matcher.match(wxMessage)) | |||
| ; | |||
| } | |||
| /** | |||
| @@ -231,9 +229,9 @@ public class WxCpMessageRouterRule { | |||
| * @return true 代表继续执行别的router,false 代表停止执行别的router | |||
| */ | |||
| protected WxCpXmlOutMessage service(WxCpXmlMessage wxMessage, | |||
| WxCpService wxCpService, | |||
| WxSessionManager sessionManager, | |||
| WxErrorExceptionHandler exceptionHandler) { | |||
| WxCpService wxCpService, | |||
| WxSessionManager sessionManager, | |||
| WxErrorExceptionHandler exceptionHandler) { | |||
| try { | |||
| @@ -1,10 +1,5 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.List; | |||
| import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
| import me.chanjar.weixin.common.bean.menu.WxMenu; | |||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
| @@ -17,6 +12,11 @@ import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| import me.chanjar.weixin.cp.bean.WxCpTag; | |||
| import me.chanjar.weixin.cp.bean.WxCpUser; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.List; | |||
| /** | |||
| * 微信API的Service | |||
| */ | |||
| @@ -47,8 +47,9 @@ public interface WxCpService { | |||
| /** | |||
| * 获取access_token, 不强制刷新access_token | |||
| * @see #getAccessToken(boolean) | |||
| * | |||
| * @throws WxErrorException | |||
| * @see #getAccessToken(boolean) | |||
| */ | |||
| String getAccessToken() throws WxErrorException; | |||
| @@ -60,6 +61,7 @@ public interface WxCpService { | |||
| * 程序员在非必要情况下尽量不要主动调用此方法 | |||
| * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取access_token | |||
| * </pre> | |||
| * | |||
| * @param forceRefresh 强制刷新 | |||
| * @throws me.chanjar.weixin.common.exception.WxErrorException | |||
| */ | |||
| @@ -67,8 +69,9 @@ public interface WxCpService { | |||
| /** | |||
| * 获得jsapi_ticket,不强制刷新jsapi_ticket | |||
| * @see #getJsapiTicket(boolean) | |||
| * | |||
| * @throws WxErrorException | |||
| * @see #getJsapiTicket(boolean) | |||
| */ | |||
| String getJsapiTicket() throws WxErrorException; | |||
| @@ -79,6 +82,7 @@ public interface WxCpService { | |||
| * | |||
| * 详情请见:http://qydev.weixin.qq.com/wiki/index.php?title=微信JS接口#.E9.99.84.E5.BD.951-JS-SDK.E4.BD.BF.E7.94.A8.E6.9D.83.E9.99.90.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95 | |||
| * </pre> | |||
| * | |||
| * @param forceRefresh 强制刷新 | |||
| * @throws WxErrorException | |||
| */ | |||
| @@ -90,7 +94,8 @@ public interface WxCpService { | |||
| * | |||
| * 详情请见:http://qydev.weixin.qq.com/wiki/index.php?title=微信JS接口#.E9.99.84.E5.BD.951-JS-SDK.E4.BD.BF.E7.94.A8.E6.9D.83.E9.99.90.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95 | |||
| * </pre> | |||
| * @param url url | |||
| * | |||
| * @param url url | |||
| */ | |||
| WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; | |||
| @@ -111,7 +116,7 @@ public interface WxCpService { | |||
| * @throws WxErrorException | |||
| */ | |||
| WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) | |||
| throws WxErrorException, IOException; | |||
| throws WxErrorException, IOException; | |||
| /** | |||
| * @param mediaType | |||
| @@ -128,9 +133,9 @@ public interface WxCpService { | |||
| * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=上传下载多媒体文件 | |||
| * </pre> | |||
| * | |||
| * @param media_id | |||
| * @return 保存到本地的临时文件 | |||
| * @throws WxErrorException | |||
| * @param media_id | |||
| */ | |||
| File mediaDownload(String media_id) throws WxErrorException; | |||
| @@ -152,10 +157,10 @@ public interface WxCpService { | |||
| * | |||
| * 注意: 这个方法使用WxCpConfigStorage里的agentId | |||
| * </pre> | |||
| * @see #menuCreate(String, me.chanjar.weixin.common.bean.WxMenu) | |||
| * | |||
| * @param menu | |||
| * @throws WxErrorException | |||
| * @see #menuCreate(String, me.chanjar.weixin.common.bean.WxMenu) | |||
| */ | |||
| void menuCreate(WxMenu menu) throws WxErrorException; | |||
| @@ -166,11 +171,11 @@ public interface WxCpService { | |||
| * | |||
| * 注意: 这个方法不使用WxCpConfigStorage里的agentId,需要开发人员自己给出 | |||
| * </pre> | |||
| * @see #menuCreate(me.chanjar.weixin.common.bean.WxMenu) | |||
| * | |||
| * @param agentId 企业号应用的id | |||
| * @param menu | |||
| * @throws WxErrorException | |||
| * @see #menuCreate(me.chanjar.weixin.common.bean.WxMenu) | |||
| */ | |||
| void menuCreate(String agentId, WxMenu menu) throws WxErrorException; | |||
| @@ -181,9 +186,9 @@ public interface WxCpService { | |||
| * | |||
| * 注意: 这个方法使用WxCpConfigStorage里的agentId | |||
| * </pre> | |||
| * @see #menuDelete(String) | |||
| * | |||
| * @throws WxErrorException | |||
| * @see #menuDelete(String) | |||
| */ | |||
| void menuDelete() throws WxErrorException; | |||
| @@ -194,10 +199,10 @@ public interface WxCpService { | |||
| * | |||
| * 注意: 这个方法不使用WxCpConfigStorage里的agentId,需要开发人员自己给出 | |||
| * </pre> | |||
| * @see #menuDelete() | |||
| * | |||
| * @param agentId 企业号应用的id | |||
| * @throws WxErrorException | |||
| * @see #menuDelete() | |||
| */ | |||
| void menuDelete(String agentId) throws WxErrorException; | |||
| @@ -208,9 +213,9 @@ public interface WxCpService { | |||
| * | |||
| * 注意: 这个方法使用WxCpConfigStorage里的agentId | |||
| * </pre> | |||
| * @see #menuGet(String) | |||
| * | |||
| * @throws WxErrorException | |||
| * @see #menuGet(String) | |||
| */ | |||
| WxMenu menuGet() throws WxErrorException; | |||
| @@ -221,10 +226,10 @@ public interface WxCpService { | |||
| * | |||
| * 注意: 这个方法不使用WxCpConfigStorage里的agentId,需要开发人员自己给出 | |||
| * </pre> | |||
| * @see #menuGet() | |||
| * | |||
| * @param agentId 企业号应用的id | |||
| * @throws WxErrorException | |||
| * @see #menuGet() | |||
| */ | |||
| WxMenu menuGet(String agentId) throws WxErrorException; | |||
| @@ -279,9 +284,10 @@ public interface WxCpService { | |||
| * | |||
| * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E6.88.90.E5.91.98.28.E8.AF.A6.E6.83.85.29 | |||
| * </pre> | |||
| * @param departId 必填。部门id | |||
| * @param fetchChild 非必填。1/0:是否递归获取子部门下面的成员 | |||
| * @param status 非必填。0获取全部员工,1获取已关注成员列表,2获取禁用成员列表,4获取未关注成员列表。status可叠加 | |||
| * | |||
| * @param departId 必填。部门id | |||
| * @param fetchChild 非必填。1/0:是否递归获取子部门下面的成员 | |||
| * @param status 非必填。0获取全部员工,1获取已关注成员列表,2获取禁用成员列表,4获取未关注成员列表。status可叠加 | |||
| * @throws WxErrorException | |||
| */ | |||
| List<WxCpUser> userList(Integer departId, Boolean fetchChild, Integer status) throws WxErrorException; | |||
| @@ -330,7 +336,8 @@ public interface WxCpService { | |||
| * | |||
| * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E6.89.B9.E9.87.8F.E5.88.A0.E9.99.A4.E6.88.90.E5.91.98 | |||
| * </pre> | |||
| * @param userids 员工UserID列表。对应管理端的帐号 | |||
| * | |||
| * @param userids 员工UserID列表。对应管理端的帐号 | |||
| * @throws WxErrorException | |||
| */ | |||
| void userDelete(String[] userids) throws WxErrorException; | |||
| @@ -367,7 +374,6 @@ public interface WxCpService { | |||
| /** | |||
| * 获得标签列表 | |||
| * | |||
| */ | |||
| List<WxCpTag> tagGet() throws WxErrorException; | |||
| @@ -391,6 +397,7 @@ public interface WxCpService { | |||
| * 构造oauth2授权的url连接 | |||
| * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=企业获取code | |||
| * </pre> | |||
| * | |||
| * @param redirectUri | |||
| * @param state | |||
| * @return url | |||
| @@ -405,10 +412,10 @@ public interface WxCpService { | |||
| * | |||
| * 注意: 这个方法使用WxCpConfigStorage里的agentId | |||
| * </pre> | |||
| * @see #oauth2getUserInfo(String, String) | |||
| * | |||
| * @param code | |||
| * @return [userid, deviceid] | |||
| * @see #oauth2getUserInfo(String, String) | |||
| */ | |||
| String[] oauth2getUserInfo(String code) throws WxErrorException; | |||
| @@ -420,11 +427,11 @@ public interface WxCpService { | |||
| * | |||
| * 注意: 这个方法不使用WxCpConfigStorage里的agentId,需要开发人员自己给出 | |||
| * </pre> | |||
| * @see #oauth2getUserInfo(String) | |||
| * | |||
| * @param agentId 企业号应用的id | |||
| * @param code | |||
| * @return [userid, deviceid] | |||
| * @see #oauth2getUserInfo(String) | |||
| */ | |||
| String[] oauth2getUserInfo(String agentId, String code) throws WxErrorException; | |||
| @@ -442,8 +449,9 @@ public interface WxCpService { | |||
| * 邀请成员关注 | |||
| * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E9.82.80.E8.AF.B7.E6.88.90.E5.91.98.E5.85.B3.E6.B3.A8 | |||
| * </pre> | |||
| * @param userId 用户的userid | |||
| * @param inviteTips 推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。 | |||
| * | |||
| * @param userId 用户的userid | |||
| * @param inviteTips 推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。 | |||
| * @return 1:微信邀请 2.邮件邀请 | |||
| * @throws WxErrorException | |||
| */ | |||
| @@ -454,6 +462,7 @@ public interface WxCpService { | |||
| * 获取微信服务器的ip段 | |||
| * http://qydev.weixin.qq.com/wiki/index.php?title=回调模式#.E8.8E.B7.E5.8F.96.E5.BE.AE.E4.BF.A1.E6.9C.8D.E5.8A.A1.E5.99.A8.E7.9A.84ip.E6.AE.B5 | |||
| * </pre> | |||
| * | |||
| * @return { "ip_list": ["101.226.103.*", "101.226.62.*"] } | |||
| * @throws WxErrorException | |||
| */ | |||
| @@ -461,6 +470,7 @@ public interface WxCpService { | |||
| /** | |||
| * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 | |||
| * | |||
| * @param url | |||
| * @param queryParam | |||
| * @throws WxErrorException | |||
| @@ -469,6 +479,7 @@ public interface WxCpService { | |||
| /** | |||
| * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 | |||
| * | |||
| * @param url | |||
| * @param postData | |||
| * @throws WxErrorException | |||
| @@ -481,6 +492,7 @@ public interface WxCpService { | |||
| * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。 | |||
| * 可以参考,{@link me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor}的实现方法 | |||
| * </pre> | |||
| * | |||
| * @param executor | |||
| * @param uri | |||
| * @param data | |||
| @@ -502,6 +514,7 @@ public interface WxCpService { | |||
| * 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试 | |||
| * 默认:1000ms | |||
| * </pre> | |||
| * | |||
| * @param retrySleepMillis | |||
| */ | |||
| void setRetrySleepMillis(int retrySleepMillis); | |||
| @@ -511,19 +524,22 @@ public interface WxCpService { | |||
| * 设置当微信系统响应系统繁忙时,最大重试次数 | |||
| * 默认:5次 | |||
| * </pre> | |||
| * | |||
| * @param maxRetryTimes | |||
| */ | |||
| void setMaxRetryTimes(int maxRetryTimes); | |||
| /** | |||
| * 获取某个sessionId对应的session,如果sessionId没有对应的session,则新建一个并返回。 | |||
| * | |||
| * @param id id可以为任意字符串,建议使用FromUserName作为id | |||
| */ | |||
| WxSession getSession(String id); | |||
| /** | |||
| * 获取某个sessionId对应的session,如果sessionId没有对应的session,若create为true则新建一个,否则返回null。 | |||
| * @param id id可以为任意字符串,建议使用FromUserName作为id | |||
| * | |||
| * @param id id可以为任意字符串,建议使用FromUserName作为id | |||
| * @param create | |||
| */ | |||
| WxSession getSession(String id, boolean create); | |||
| @@ -533,12 +549,14 @@ public interface WxCpService { | |||
| * 设置WxSessionManager,只有当需要使用个性化的WxSessionManager的时候才需要调用此方法, | |||
| * WxCpService默认使用的是{@link me.chanjar.weixin.common.session.StandardSessionManager} | |||
| * </pre> | |||
| * | |||
| * @param sessionManager | |||
| */ | |||
| void setSessionManager(WxSessionManager sessionManager); | |||
| /** | |||
| * 上传部门列表覆盖企业号上的部门信息 | |||
| * | |||
| * @param mediaId | |||
| * @throws WxErrorException | |||
| */ | |||
| @@ -546,6 +564,7 @@ public interface WxCpService { | |||
| /** | |||
| * 上传用户列表覆盖企业号上的用户信息 | |||
| * | |||
| * @param mediaId | |||
| * @throws WxErrorException | |||
| */ | |||
| @@ -553,6 +572,7 @@ public interface WxCpService { | |||
| /** | |||
| * 获取异步任务结果 | |||
| * | |||
| * @param joinId | |||
| * @throws WxErrorException | |||
| */ | |||
| @@ -1,23 +1,5 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.io.StringReader; | |||
| import java.security.NoSuchAlgorithmException; | |||
| import java.util.List; | |||
| import java.util.UUID; | |||
| import org.apache.http.HttpHost; | |||
| import org.apache.http.client.ClientProtocolException; | |||
| import org.apache.http.client.config.RequestConfig; | |||
| import org.apache.http.client.methods.CloseableHttpResponse; | |||
| import org.apache.http.client.methods.HttpGet; | |||
| import org.apache.http.impl.client.BasicResponseHandler; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import com.google.gson.JsonArray; | |||
| import com.google.gson.JsonElement; | |||
| import com.google.gson.JsonObject; | |||
| @@ -25,7 +7,6 @@ import com.google.gson.JsonPrimitive; | |||
| import com.google.gson.internal.Streams; | |||
| import com.google.gson.reflect.TypeToken; | |||
| import com.google.gson.stream.JsonReader; | |||
| import me.chanjar.weixin.common.bean.WxAccessToken; | |||
| import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
| import me.chanjar.weixin.common.bean.menu.WxMenu; | |||
| @@ -39,20 +20,30 @@ import me.chanjar.weixin.common.util.RandomUtils; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import me.chanjar.weixin.common.util.crypto.SHA1; | |||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||
| import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | |||
| import me.chanjar.weixin.common.util.http.DefaultApacheHttpHttpClientBuilder; | |||
| import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.URIUtil; | |||
| import me.chanjar.weixin.common.util.http.*; | |||
| import me.chanjar.weixin.common.util.json.GsonHelper; | |||
| import me.chanjar.weixin.cp.bean.WxCpDepart; | |||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| import me.chanjar.weixin.cp.bean.WxCpTag; | |||
| import me.chanjar.weixin.cp.bean.WxCpUser; | |||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
| import org.apache.http.HttpHost; | |||
| import org.apache.http.client.ClientProtocolException; | |||
| import org.apache.http.client.config.RequestConfig; | |||
| import org.apache.http.client.methods.CloseableHttpResponse; | |||
| import org.apache.http.client.methods.HttpGet; | |||
| import org.apache.http.impl.client.BasicResponseHandler; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.io.StringReader; | |||
| import java.security.NoSuchAlgorithmException; | |||
| import java.util.List; | |||
| import java.util.UUID; | |||
| public class WxCpServiceImpl implements WxCpService { | |||
| @@ -73,17 +64,13 @@ public class WxCpServiceImpl implements WxCpService { | |||
| protected CloseableHttpClient httpClient; | |||
| protected HttpHost httpProxy; | |||
| private int retrySleepMillis = 1000; | |||
| private int maxRetryTimes = 5; | |||
| protected WxSessionManager sessionManager = new StandardSessionManager(); | |||
| /** | |||
| * 临时文件目录 | |||
| */ | |||
| protected File tmpDirFile; | |||
| private int retrySleepMillis = 1000; | |||
| private int maxRetryTimes = 5; | |||
| public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { | |||
| try { | |||
| @@ -110,8 +97,8 @@ public class WxCpServiceImpl implements WxCpService { | |||
| synchronized (globalAccessTokenRefreshLock) { | |||
| if (wxCpConfigStorage.isAccessTokenExpired()) { | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" | |||
| + "&corpid=" + wxCpConfigStorage.getCorpId() | |||
| + "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); | |||
| + "&corpid=" + wxCpConfigStorage.getCorpId() | |||
| + "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); | |||
| try { | |||
| HttpGet httpGet = new HttpGet(url); | |||
| if (httpProxy != null) { | |||
| @@ -122,7 +109,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
| String resultContent = null; | |||
| try (CloseableHttpResponse response = httpclient.execute(httpGet)) { | |||
| resultContent = new BasicResponseHandler().handleResponse(response); | |||
| }finally { | |||
| } finally { | |||
| httpGet.releaseConnection(); | |||
| } | |||
| WxError error = WxError.fromJson(resultContent); | |||
| @@ -172,10 +159,10 @@ public class WxCpServiceImpl implements WxCpService { | |||
| String jsapiTicket = getJsapiTicket(false); | |||
| try { | |||
| String signature = SHA1.genWithAmple( | |||
| "jsapi_ticket=" + jsapiTicket, | |||
| "noncestr=" + noncestr, | |||
| "timestamp=" + timestamp, | |||
| "url=" + url | |||
| "jsapi_ticket=" + jsapiTicket, | |||
| "noncestr=" + noncestr, | |||
| "timestamp=" + timestamp, | |||
| "url=" + url | |||
| ); | |||
| WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | |||
| jsapiSignature.setTimestamp(timestamp); | |||
| @@ -236,7 +223,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
| } | |||
| public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) | |||
| throws WxErrorException, IOException { | |||
| throws WxErrorException, IOException { | |||
| return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | |||
| } | |||
| @@ -254,9 +241,9 @@ public class WxCpServiceImpl implements WxCpService { | |||
| public Integer departCreate(WxCpDepart depart) throws WxErrorException { | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create"; | |||
| String responseContent = execute( | |||
| new SimplePostRequestExecutor(), | |||
| url, | |||
| depart.toJson()); | |||
| new SimplePostRequestExecutor(), | |||
| url, | |||
| depart.toJson()); | |||
| JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
| return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id")); | |||
| } | |||
| @@ -280,11 +267,11 @@ public class WxCpServiceImpl implements WxCpService { | |||
| */ | |||
| JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
| return WxCpGsonBuilder.INSTANCE.create() | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("department"), | |||
| new TypeToken<List<WxCpDepart>>() { | |||
| }.getType() | |||
| ); | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("department"), | |||
| new TypeToken<List<WxCpDepart>>() { | |||
| }.getType() | |||
| ); | |||
| } | |||
| @Override | |||
| @@ -340,10 +327,11 @@ public class WxCpServiceImpl implements WxCpService { | |||
| String responseContent = get(url, params); | |||
| JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
| return WxCpGsonBuilder.INSTANCE.create() | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||
| new TypeToken<List<WxCpUser>>() { }.getType() | |||
| ); | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||
| new TypeToken<List<WxCpUser>>() { | |||
| }.getType() | |||
| ); | |||
| } | |||
| @Override | |||
| @@ -362,10 +350,11 @@ public class WxCpServiceImpl implements WxCpService { | |||
| String responseContent = get(url, params); | |||
| JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
| return WxCpGsonBuilder.INSTANCE.create() | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||
| new TypeToken<List<WxCpUser>>() { }.getType() | |||
| ); | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||
| new TypeToken<List<WxCpUser>>() { | |||
| }.getType() | |||
| ); | |||
| } | |||
| @Override | |||
| @@ -399,11 +388,11 @@ public class WxCpServiceImpl implements WxCpService { | |||
| String responseContent = get(url, null); | |||
| JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
| return WxCpGsonBuilder.INSTANCE.create() | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("taglist"), | |||
| new TypeToken<List<WxCpTag>>() { | |||
| }.getType() | |||
| ); | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("taglist"), | |||
| new TypeToken<List<WxCpTag>>() { | |||
| }.getType() | |||
| ); | |||
| } | |||
| @Override | |||
| @@ -412,10 +401,11 @@ public class WxCpServiceImpl implements WxCpService { | |||
| String responseContent = get(url, null); | |||
| JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
| return WxCpGsonBuilder.INSTANCE.create() | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||
| new TypeToken<List<WxCpUser>>() { }.getType() | |||
| ); | |||
| .fromJson( | |||
| tmpJsonElement.getAsJsonObject().get("userlist"), | |||
| new TypeToken<List<WxCpUser>>() { | |||
| }.getType() | |||
| ); | |||
| } | |||
| @Override | |||
| @@ -455,7 +445,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
| @Override | |||
| public String oauth2buildAuthorizationUrl(String redirectUri, String state) { | |||
| String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" ; | |||
| String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"; | |||
| url += "appid=" + wxCpConfigStorage.getCorpId(); | |||
| url += "&redirect_uri=" + URIUtil.encodeURIComponent(redirectUri); | |||
| url += "&response_type=code"; | |||
| @@ -475,12 +465,12 @@ public class WxCpServiceImpl implements WxCpService { | |||
| @Override | |||
| public String[] oauth2getUserInfo(String agentId, String code) throws WxErrorException { | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?" | |||
| + "code=" + code | |||
| + "&agendid=" + agentId; | |||
| + "code=" + code | |||
| + "&agendid=" + agentId; | |||
| String responseText = get(url, null); | |||
| JsonElement je = Streams.parse(new JsonReader(new StringReader(responseText))); | |||
| JsonObject jo = je.getAsJsonObject(); | |||
| return new String[] {GsonHelper.getString(jo, "UserId"), GsonHelper.getString(jo, "DeviceId")}; | |||
| return new String[]{GsonHelper.getString(jo, "UserId"), GsonHelper.getString(jo, "DeviceId")}; | |||
| } | |||
| @Override | |||
| @@ -503,7 +493,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
| JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
| JsonArray jsonArray = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray(); | |||
| String[] ips = new String[jsonArray.size()]; | |||
| for(int i = 0; i < jsonArray.size(); i++) { | |||
| for (int i = 0; i < jsonArray.size(); i++) { | |||
| ips[i] = jsonArray.get(i).getAsString(); | |||
| } | |||
| return ips; | |||
| @@ -542,7 +532,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
| throw e; | |||
| } | |||
| } | |||
| } while(++retryTimes < maxRetryTimes); | |||
| } while (++retryTimes < maxRetryTimes); | |||
| throw new RuntimeException("微信服务端异常,超出重试次数"); | |||
| } | |||
| @@ -580,6 +570,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
| throw new RuntimeException(e); | |||
| } | |||
| } | |||
| protected CloseableHttpClient getHttpclient() { | |||
| return httpClient; | |||
| } | |||
| @@ -591,9 +582,9 @@ public class WxCpServiceImpl implements WxCpService { | |||
| apacheHttpClientBuilder = DefaultApacheHttpHttpClientBuilder.get(); | |||
| } | |||
| apacheHttpClientBuilder.httpProxyHost(wxCpConfigStorage.getHttp_proxy_host()) | |||
| .httpProxyPort(wxCpConfigStorage.getHttp_proxy_port()) | |||
| .httpProxyUsername(wxCpConfigStorage.getHttp_proxy_username()) | |||
| .httpProxyPassword(wxCpConfigStorage.getHttp_proxy_password()); | |||
| .httpProxyPort(wxCpConfigStorage.getHttp_proxy_port()) | |||
| .httpProxyUsername(wxCpConfigStorage.getHttp_proxy_username()) | |||
| .httpProxyPassword(wxCpConfigStorage.getHttp_proxy_password()); | |||
| httpClient = apacheHttpClientBuilder.build(); | |||
| } | |||
| @@ -630,27 +621,27 @@ public class WxCpServiceImpl implements WxCpService { | |||
| public void setSessionManager(WxSessionManager sessionManager) { | |||
| this.sessionManager = sessionManager; | |||
| } | |||
| @Override | |||
| public String replaceParty(String mediaId) throws WxErrorException { | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty"; | |||
| JsonObject jsonObject = new JsonObject(); | |||
| jsonObject.addProperty("media_id", mediaId); | |||
| return post(url, jsonObject.toString()); | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty"; | |||
| JsonObject jsonObject = new JsonObject(); | |||
| jsonObject.addProperty("media_id", mediaId); | |||
| return post(url, jsonObject.toString()); | |||
| } | |||
| @Override | |||
| public String replaceUser(String mediaId) throws WxErrorException { | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser"; | |||
| JsonObject jsonObject = new JsonObject(); | |||
| jsonObject.addProperty("media_id", mediaId); | |||
| return post(url, jsonObject.toString()); | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser"; | |||
| JsonObject jsonObject = new JsonObject(); | |||
| jsonObject.addProperty("media_id", mediaId); | |||
| return post(url, jsonObject.toString()); | |||
| } | |||
| @Override | |||
| public String getTaskResult(String joinId) throws WxErrorException { | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?jobid="+joinId; | |||
| return get(url, null); | |||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?jobid=" + joinId; | |||
| return get(url, null); | |||
| } | |||
| public File getTmpDirFile() { | |||
| @@ -16,6 +16,10 @@ public class WxCpDepart implements Serializable { | |||
| private Integer parentId; | |||
| private Integer order; | |||
| public static WxCpDepart fromJson(String json) { | |||
| return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); | |||
| } | |||
| public Integer getId() { | |||
| return id; | |||
| } | |||
| @@ -48,10 +52,6 @@ public class WxCpDepart implements Serializable { | |||
| this.order = order; | |||
| } | |||
| public static WxCpDepart fromJson(String json) { | |||
| return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); | |||
| } | |||
| public String toJson() { | |||
| return WxCpGsonBuilder.create().toJson(this); | |||
| } | |||
| @@ -59,10 +59,10 @@ public class WxCpDepart implements Serializable { | |||
| @Override | |||
| public String toString() { | |||
| return "WxCpDepart{" + | |||
| "id=" + id + | |||
| ", name='" + name + '\'' + | |||
| ", parentId=" + parentId + | |||
| ", order=" + order + | |||
| '}'; | |||
| "id=" + id + | |||
| ", name='" + name + '\'' + | |||
| ", parentId=" + parentId + | |||
| ", order=" + order + | |||
| '}'; | |||
| } | |||
| } | |||
| @@ -9,8 +9,8 @@ import java.util.List; | |||
| /** | |||
| * 消息 | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class WxCpMessage implements Serializable { | |||
| @@ -29,9 +29,52 @@ public class WxCpMessage implements Serializable { | |||
| private String safe; | |||
| private List<WxArticle> articles = new ArrayList<WxArticle>(); | |||
| /** | |||
| * 获得文本消息builder | |||
| */ | |||
| public static TextBuilder TEXT() { | |||
| return new TextBuilder(); | |||
| } | |||
| /** | |||
| * 获得图片消息builder | |||
| */ | |||
| public static ImageBuilder IMAGE() { | |||
| return new ImageBuilder(); | |||
| } | |||
| /** | |||
| * 获得语音消息builder | |||
| */ | |||
| public static VoiceBuilder VOICE() { | |||
| return new VoiceBuilder(); | |||
| } | |||
| /** | |||
| * 获得视频消息builder | |||
| */ | |||
| public static VideoBuilder VIDEO() { | |||
| return new VideoBuilder(); | |||
| } | |||
| /** | |||
| * 获得图文消息builder | |||
| */ | |||
| public static NewsBuilder NEWS() { | |||
| return new NewsBuilder(); | |||
| } | |||
| /** | |||
| * 获得文件消息builder | |||
| */ | |||
| public static FileBuilder FILE() { | |||
| return new FileBuilder(); | |||
| } | |||
| public String getToUser() { | |||
| return toUser; | |||
| } | |||
| public void setToUser(String toUser) { | |||
| this.toUser = toUser; | |||
| } | |||
| @@ -64,14 +107,6 @@ public class WxCpMessage implements Serializable { | |||
| return msgType; | |||
| } | |||
| public String getSafe() { | |||
| return safe; | |||
| } | |||
| public void setSafe(String safe) { | |||
| this.safe = safe; | |||
| } | |||
| /** | |||
| * <pre> | |||
| * 请使用 | |||
| @@ -82,56 +117,81 @@ public class WxCpMessage implements Serializable { | |||
| * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VIDEO} | |||
| * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_NEWS} | |||
| * </pre> | |||
| * | |||
| * @param msgType | |||
| */ | |||
| public void setMsgType(String msgType) { | |||
| this.msgType = msgType; | |||
| } | |||
| public String getSafe() { | |||
| return safe; | |||
| } | |||
| public void setSafe(String safe) { | |||
| this.safe = safe; | |||
| } | |||
| public String getContent() { | |||
| return content; | |||
| } | |||
| public void setContent(String content) { | |||
| this.content = content; | |||
| } | |||
| public String getMediaId() { | |||
| return mediaId; | |||
| } | |||
| public void setMediaId(String mediaId) { | |||
| this.mediaId = mediaId; | |||
| } | |||
| public String getThumbMediaId() { | |||
| return thumbMediaId; | |||
| } | |||
| public void setThumbMediaId(String thumbMediaId) { | |||
| this.thumbMediaId = thumbMediaId; | |||
| } | |||
| public String getTitle() { | |||
| return title; | |||
| } | |||
| public void setTitle(String title) { | |||
| this.title = title; | |||
| } | |||
| public String getDescription() { | |||
| return description; | |||
| } | |||
| public void setDescription(String description) { | |||
| this.description = description; | |||
| } | |||
| public String getMusicUrl() { | |||
| return musicUrl; | |||
| } | |||
| public void setMusicUrl(String musicUrl) { | |||
| this.musicUrl = musicUrl; | |||
| } | |||
| public String getHqMusicUrl() { | |||
| return hqMusicUrl; | |||
| } | |||
| public void setHqMusicUrl(String hqMusicUrl) { | |||
| this.hqMusicUrl = hqMusicUrl; | |||
| } | |||
| public List<WxArticle> getArticles() { | |||
| return articles; | |||
| } | |||
| public void setArticles(List<WxArticle> articles) { | |||
| this.articles = articles; | |||
| } | |||
| @@ -150,70 +210,35 @@ public class WxCpMessage implements Serializable { | |||
| public String getTitle() { | |||
| return title; | |||
| } | |||
| public void setTitle(String title) { | |||
| this.title = title; | |||
| } | |||
| public String getDescription() { | |||
| return description; | |||
| } | |||
| public void setDescription(String description) { | |||
| this.description = description; | |||
| } | |||
| public String getUrl() { | |||
| return url; | |||
| } | |||
| public void setUrl(String url) { | |||
| this.url = url; | |||
| } | |||
| public String getPicUrl() { | |||
| return picUrl; | |||
| } | |||
| public void setPicUrl(String picUrl) { | |||
| this.picUrl = picUrl; | |||
| } | |||
| } | |||
| /** | |||
| * 获得文本消息builder | |||
| */ | |||
| public static TextBuilder TEXT() { | |||
| return new TextBuilder(); | |||
| } | |||
| /** | |||
| * 获得图片消息builder | |||
| */ | |||
| public static ImageBuilder IMAGE() { | |||
| return new ImageBuilder(); | |||
| } | |||
| /** | |||
| * 获得语音消息builder | |||
| */ | |||
| public static VoiceBuilder VOICE() { | |||
| return new VoiceBuilder(); | |||
| } | |||
| /** | |||
| * 获得视频消息builder | |||
| */ | |||
| public static VideoBuilder VIDEO() { | |||
| return new VideoBuilder(); | |||
| } | |||
| /** | |||
| * 获得图文消息builder | |||
| */ | |||
| public static NewsBuilder NEWS() { | |||
| return new NewsBuilder(); | |||
| } | |||
| /** | |||
| * 获得文件消息builder | |||
| */ | |||
| public static FileBuilder FILE() { | |||
| return new FileBuilder(); | |||
| } | |||
| } | |||
| @@ -23,6 +23,10 @@ public class WxCpTag implements Serializable { | |||
| this.name = name; | |||
| } | |||
| public static WxCpTag fromJson(String json) { | |||
| return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); | |||
| } | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| @@ -39,10 +43,6 @@ public class WxCpTag implements Serializable { | |||
| this.id = id; | |||
| } | |||
| public static WxCpTag fromJson(String json) { | |||
| return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); | |||
| } | |||
| public String toJson() { | |||
| return WxCpGsonBuilder.create().toJson(this); | |||
| } | |||
| @@ -13,6 +13,7 @@ import java.util.List; | |||
| */ | |||
| public class WxCpUser implements Serializable { | |||
| private final List<Attr> extAttrs = new ArrayList<Attr>(); | |||
| private String userId; | |||
| private String name; | |||
| private Integer[] departIds; | |||
| @@ -25,7 +26,10 @@ public class WxCpUser implements Serializable { | |||
| private String avatar; | |||
| private Integer status; | |||
| private Integer enable; | |||
| private final List<Attr> extAttrs = new ArrayList<Attr>(); | |||
| public static WxCpUser fromJson(String json) { | |||
| return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); | |||
| } | |||
| public String getUserId() { | |||
| return userId; | |||
| @@ -116,13 +120,13 @@ public class WxCpUser implements Serializable { | |||
| } | |||
| public Integer getEnable() { | |||
| return enable; | |||
| return enable; | |||
| } | |||
| public void setEnable(Integer enable) { | |||
| this.enable = enable; | |||
| this.enable = enable; | |||
| } | |||
| public void addExtAttr(String name, String value) { | |||
| this.extAttrs.add(new Attr(name, value)); | |||
| } | |||
| @@ -135,10 +139,6 @@ public class WxCpUser implements Serializable { | |||
| return WxCpGsonBuilder.INSTANCE.create().toJson(this); | |||
| } | |||
| public static WxCpUser fromJson(String json) { | |||
| return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); | |||
| } | |||
| public static class Attr { | |||
| private String name; | |||
| @@ -36,41 +36,41 @@ public class WxCpXmlMessage implements Serializable { | |||
| private Integer agentId; | |||
| @XStreamAlias("ToUserName") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String toUserName; | |||
| @XStreamAlias("FromUserName") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String fromUserName; | |||
| @XStreamAlias("CreateTime") | |||
| private Long createTime; | |||
| @XStreamAlias("MsgType") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String msgType; | |||
| @XStreamAlias("Content") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String content; | |||
| @XStreamAlias("MsgId") | |||
| private Long msgId; | |||
| @XStreamAlias("PicUrl") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String picUrl; | |||
| @XStreamAlias("MediaId") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String mediaId; | |||
| @XStreamAlias("Format") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String format; | |||
| @XStreamAlias("ThumbMediaId") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String thumbMediaId; | |||
| @XStreamAlias("Location_X") | |||
| @@ -83,31 +83,31 @@ public class WxCpXmlMessage implements Serializable { | |||
| private Double scale; | |||
| @XStreamAlias("Label") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String label; | |||
| @XStreamAlias("Title") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String title; | |||
| @XStreamAlias("Description") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String description; | |||
| @XStreamAlias("Url") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String url; | |||
| @XStreamAlias("Event") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String event; | |||
| @XStreamAlias("EventKey") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String eventKey; | |||
| @XStreamAlias("Ticket") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String ticket; | |||
| @XStreamAlias("Latitude") | |||
| @@ -120,7 +120,7 @@ public class WxCpXmlMessage implements Serializable { | |||
| private Double precision; | |||
| @XStreamAlias("Recognition") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String recognition; | |||
| /////////////////////////////////////// | |||
| @@ -130,7 +130,7 @@ public class WxCpXmlMessage implements Serializable { | |||
| * 群发的结果 | |||
| */ | |||
| @XStreamAlias("Status") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String status; | |||
| /** | |||
| * group_id下粉丝数;或者openid_list中的粉丝数 | |||
| @@ -162,6 +162,43 @@ public class WxCpXmlMessage implements Serializable { | |||
| @XStreamAlias("SendLocationInfo") | |||
| private SendLocationInfo sendLocationInfo = new SendLocationInfo(); | |||
| protected static WxCpXmlMessage fromXml(String xml) { | |||
| return XStreamTransformer.fromXml(WxCpXmlMessage.class, xml); | |||
| } | |||
| protected static WxCpXmlMessage fromXml(InputStream is) { | |||
| return XStreamTransformer.fromXml(WxCpXmlMessage.class, is); | |||
| } | |||
| /** | |||
| * 从加密字符串转换 | |||
| * | |||
| * @param encryptedXml | |||
| * @param wxCpConfigStorage | |||
| * @param timestamp | |||
| * @param nonce | |||
| * @param msgSignature | |||
| */ | |||
| public static WxCpXmlMessage fromEncryptedXml( | |||
| String encryptedXml, | |||
| WxCpConfigStorage wxCpConfigStorage, | |||
| String timestamp, String nonce, String msgSignature) { | |||
| WxCpCryptUtil cryptUtil = new WxCpCryptUtil(wxCpConfigStorage); | |||
| String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml); | |||
| return fromXml(plainText); | |||
| } | |||
| public static WxCpXmlMessage fromEncryptedXml( | |||
| InputStream is, | |||
| WxCpConfigStorage wxCpConfigStorage, | |||
| String timestamp, String nonce, String msgSignature) { | |||
| try { | |||
| return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), wxCpConfigStorage, timestamp, nonce, msgSignature); | |||
| } catch (IOException e) { | |||
| throw new RuntimeException(e); | |||
| } | |||
| } | |||
| public Integer getAgentId() { | |||
| return agentId; | |||
| } | |||
| @@ -197,7 +234,6 @@ public class WxCpXmlMessage implements Serializable { | |||
| * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LINK} | |||
| * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_EVENT} | |||
| * </pre> | |||
| * | |||
| */ | |||
| public String getMsgType() { | |||
| return msgType; | |||
| @@ -387,43 +423,6 @@ public class WxCpXmlMessage implements Serializable { | |||
| this.fromUserName = fromUserName; | |||
| } | |||
| protected static WxCpXmlMessage fromXml(String xml) { | |||
| return XStreamTransformer.fromXml(WxCpXmlMessage.class, xml); | |||
| } | |||
| protected static WxCpXmlMessage fromXml(InputStream is) { | |||
| return XStreamTransformer.fromXml(WxCpXmlMessage.class, is); | |||
| } | |||
| /** | |||
| * 从加密字符串转换 | |||
| * | |||
| * @param encryptedXml | |||
| * @param wxCpConfigStorage | |||
| * @param timestamp | |||
| * @param nonce | |||
| * @param msgSignature | |||
| */ | |||
| public static WxCpXmlMessage fromEncryptedXml( | |||
| String encryptedXml, | |||
| WxCpConfigStorage wxCpConfigStorage, | |||
| String timestamp, String nonce, String msgSignature) { | |||
| WxCpCryptUtil cryptUtil = new WxCpCryptUtil(wxCpConfigStorage); | |||
| String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml); | |||
| return fromXml(plainText); | |||
| } | |||
| public static WxCpXmlMessage fromEncryptedXml( | |||
| InputStream is, | |||
| WxCpConfigStorage wxCpConfigStorage, | |||
| String timestamp, String nonce, String msgSignature) { | |||
| try { | |||
| return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), wxCpConfigStorage, timestamp, nonce, msgSignature); | |||
| } catch (IOException e) { | |||
| throw new RuntimeException(e); | |||
| } | |||
| } | |||
| public String getStatus() { | |||
| return status; | |||
| } | |||
| @@ -491,51 +490,51 @@ public class WxCpXmlMessage implements Serializable { | |||
| @Override | |||
| public String toString() { | |||
| return "WxCpXmlMessage{" + | |||
| "agentId=" + agentId + | |||
| ", toUserName='" + toUserName + '\'' + | |||
| ", fromUserName='" + fromUserName + '\'' + | |||
| ", createTime=" + createTime + | |||
| ", msgType='" + msgType + '\'' + | |||
| ", content='" + content + '\'' + | |||
| ", msgId=" + msgId + | |||
| ", picUrl='" + picUrl + '\'' + | |||
| ", mediaId='" + mediaId + '\'' + | |||
| ", format='" + format + '\'' + | |||
| ", thumbMediaId='" + thumbMediaId + '\'' + | |||
| ", locationX=" + locationX + | |||
| ", locationY=" + locationY + | |||
| ", scale=" + scale + | |||
| ", label='" + label + '\'' + | |||
| ", title='" + title + '\'' + | |||
| ", description='" + description + '\'' + | |||
| ", url='" + url + '\'' + | |||
| ", event='" + event + '\'' + | |||
| ", eventKey='" + eventKey + '\'' + | |||
| ", ticket='" + ticket + '\'' + | |||
| ", latitude=" + latitude + | |||
| ", longitude=" + longitude + | |||
| ", precision=" + precision + | |||
| ", recognition='" + recognition + '\'' + | |||
| ", status='" + status + '\'' + | |||
| ", totalCount=" + totalCount + | |||
| ", filterCount=" + filterCount + | |||
| ", sentCount=" + sentCount + | |||
| ", errorCount=" + errorCount + | |||
| ", scanCodeInfo=" + scanCodeInfo + | |||
| ", sendPicsInfo=" + sendPicsInfo + | |||
| ", sendLocationInfo=" + sendLocationInfo + | |||
| '}'; | |||
| "agentId=" + agentId + | |||
| ", toUserName='" + toUserName + '\'' + | |||
| ", fromUserName='" + fromUserName + '\'' + | |||
| ", createTime=" + createTime + | |||
| ", msgType='" + msgType + '\'' + | |||
| ", content='" + content + '\'' + | |||
| ", msgId=" + msgId + | |||
| ", picUrl='" + picUrl + '\'' + | |||
| ", mediaId='" + mediaId + '\'' + | |||
| ", format='" + format + '\'' + | |||
| ", thumbMediaId='" + thumbMediaId + '\'' + | |||
| ", locationX=" + locationX + | |||
| ", locationY=" + locationY + | |||
| ", scale=" + scale + | |||
| ", label='" + label + '\'' + | |||
| ", title='" + title + '\'' + | |||
| ", description='" + description + '\'' + | |||
| ", url='" + url + '\'' + | |||
| ", event='" + event + '\'' + | |||
| ", eventKey='" + eventKey + '\'' + | |||
| ", ticket='" + ticket + '\'' + | |||
| ", latitude=" + latitude + | |||
| ", longitude=" + longitude + | |||
| ", precision=" + precision + | |||
| ", recognition='" + recognition + '\'' + | |||
| ", status='" + status + '\'' + | |||
| ", totalCount=" + totalCount + | |||
| ", filterCount=" + filterCount + | |||
| ", sentCount=" + sentCount + | |||
| ", errorCount=" + errorCount + | |||
| ", scanCodeInfo=" + scanCodeInfo + | |||
| ", sendPicsInfo=" + sendPicsInfo + | |||
| ", sendLocationInfo=" + sendLocationInfo + | |||
| '}'; | |||
| } | |||
| @XStreamAlias("ScanCodeInfo") | |||
| public static class ScanCodeInfo { | |||
| @XStreamAlias("ScanType") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String scanType; | |||
| @XStreamAlias("ScanResult") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String scanResult; | |||
| /** | |||
| @@ -566,11 +565,10 @@ public class WxCpXmlMessage implements Serializable { | |||
| @XStreamAlias("SendPicsInfo") | |||
| public static class SendPicsInfo { | |||
| @XStreamAlias("Count") | |||
| private Long count; | |||
| @XStreamAlias("PicList") | |||
| protected final List<Item> picList = new ArrayList<Item>(); | |||
| @XStreamAlias("Count") | |||
| private Long count; | |||
| public Long getCount() { | |||
| return count; | |||
| @@ -588,7 +586,7 @@ public class WxCpXmlMessage implements Serializable { | |||
| public static class Item { | |||
| @XStreamAlias("PicMd5Sum") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String PicMd5Sum; | |||
| public String getPicMd5Sum() { | |||
| @@ -605,23 +603,23 @@ public class WxCpXmlMessage implements Serializable { | |||
| public static class SendLocationInfo { | |||
| @XStreamAlias("Location_X") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String locationX; | |||
| @XStreamAlias("Location_Y") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String locationY; | |||
| @XStreamAlias("Scale") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String scale; | |||
| @XStreamAlias("Label") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String label; | |||
| @XStreamAlias("Poiname") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String poiname; | |||
| public String getLocationX() { | |||
| @@ -7,15 +7,15 @@ import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; | |||
| @XStreamAlias("xml") | |||
| public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { | |||
| @XStreamAlias("Image") | |||
| @XStreamConverter(value=XStreamMediaIdConverter.class) | |||
| @XStreamConverter(value = XStreamMediaIdConverter.class) | |||
| private String mediaId; | |||
| public WxCpXmlOutImageMessage() { | |||
| this.msgType = WxConsts.XML_MSG_IMAGE; | |||
| } | |||
| public String getMediaId() { | |||
| return mediaId; | |||
| } | |||
| @@ -23,5 +23,5 @@ public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { | |||
| public void setMediaId(String mediaId) { | |||
| this.mediaId = mediaId; | |||
| } | |||
| } | |||
| @@ -12,20 +12,55 @@ import me.chanjar.weixin.cp.util.xml.XStreamTransformer; | |||
| public abstract class WxCpXmlOutMessage { | |||
| @XStreamAlias("ToUserName") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| protected String toUserName; | |||
| @XStreamAlias("FromUserName") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| protected String fromUserName; | |||
| @XStreamAlias("CreateTime") | |||
| protected Long createTime; | |||
| @XStreamAlias("MsgType") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| protected String msgType; | |||
| /** | |||
| * 获得文本消息builder | |||
| */ | |||
| public static TextBuilder TEXT() { | |||
| return new TextBuilder(); | |||
| } | |||
| /** | |||
| * 获得图片消息builder | |||
| */ | |||
| public static ImageBuilder IMAGE() { | |||
| return new ImageBuilder(); | |||
| } | |||
| /** | |||
| * 获得语音消息builder | |||
| */ | |||
| public static VoiceBuilder VOICE() { | |||
| return new VoiceBuilder(); | |||
| } | |||
| /** | |||
| * 获得视频消息builder | |||
| */ | |||
| public static VideoBuilder VIDEO() { | |||
| return new VideoBuilder(); | |||
| } | |||
| /** | |||
| * 获得图文消息builder | |||
| */ | |||
| public static NewsBuilder NEWS() { | |||
| return new NewsBuilder(); | |||
| } | |||
| public String getToUserName() { | |||
| return toUserName; | |||
| } | |||
| @@ -59,7 +94,7 @@ public abstract class WxCpXmlOutMessage { | |||
| } | |||
| protected String toXml() { | |||
| return XStreamTransformer.toXml((Class)this.getClass(), this); | |||
| return XStreamTransformer.toXml((Class) this.getClass(), this); | |||
| } | |||
| /** | |||
| @@ -70,39 +105,4 @@ public abstract class WxCpXmlOutMessage { | |||
| WxCpCryptUtil pc = new WxCpCryptUtil(wxCpConfigStorage); | |||
| return pc.encrypt(plainXml); | |||
| } | |||
| /** | |||
| * 获得文本消息builder | |||
| */ | |||
| public static TextBuilder TEXT() { | |||
| return new TextBuilder(); | |||
| } | |||
| /** | |||
| * 获得图片消息builder | |||
| */ | |||
| public static ImageBuilder IMAGE() { | |||
| return new ImageBuilder(); | |||
| } | |||
| /** | |||
| * 获得语音消息builder | |||
| */ | |||
| public static VoiceBuilder VOICE() { | |||
| return new VoiceBuilder(); | |||
| } | |||
| /** | |||
| * 获得视频消息builder | |||
| */ | |||
| public static VideoBuilder VIDEO() { | |||
| return new VideoBuilder(); | |||
| } | |||
| /** | |||
| * 获得图文消息builder | |||
| */ | |||
| public static NewsBuilder NEWS() { | |||
| return new NewsBuilder(); | |||
| } | |||
| } | |||
| @@ -11,12 +11,11 @@ import java.util.List; | |||
| @XStreamAlias("xml") | |||
| public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | |||
| @XStreamAlias("ArticleCount") | |||
| protected int articleCount; | |||
| @XStreamAlias("Articles") | |||
| protected final List<Item> articles = new ArrayList<Item>(); | |||
| @XStreamAlias("ArticleCount") | |||
| protected int articleCount; | |||
| public WxCpXmlOutNewsMessage() { | |||
| this.msgType = WxConsts.XML_MSG_NEWS; | |||
| } | |||
| @@ -29,31 +28,31 @@ public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | |||
| this.articles.add(item); | |||
| this.articleCount = this.articles.size(); | |||
| } | |||
| public List<Item> getArticles() { | |||
| return articles; | |||
| } | |||
| @XStreamAlias("item") | |||
| public static class Item { | |||
| @XStreamAlias("Title") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String Title; | |||
| @XStreamAlias("Description") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String Description; | |||
| @XStreamAlias("PicUrl") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String PicUrl; | |||
| @XStreamAlias("Url") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String Url; | |||
| public String getTitle() { | |||
| return Title; | |||
| } | |||
| @@ -7,15 +7,15 @@ import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | |||
| @XStreamAlias("xml") | |||
| public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { | |||
| @XStreamAlias("Content") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String content; | |||
| public WxCpXmlOutTextMessage() { | |||
| this.msgType = WxConsts.XML_MSG_TEXT; | |||
| } | |||
| public String getContent() { | |||
| return content; | |||
| } | |||
| @@ -24,5 +24,5 @@ public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { | |||
| this.content = content; | |||
| } | |||
| } | |||
| @@ -38,21 +38,21 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||
| public void setDescription(String description) { | |||
| video.setDescription(description); | |||
| } | |||
| @XStreamAlias("Video") | |||
| public static class Video { | |||
| @XStreamAlias("MediaId") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String mediaId; | |||
| @XStreamAlias("Title") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String title; | |||
| @XStreamAlias("Description") | |||
| @XStreamConverter(value=XStreamCDataConverter.class) | |||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||
| private String description; | |||
| public String getMediaId() { | |||
| @@ -78,7 +78,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||
| public void setDescription(String description) { | |||
| this.description = description; | |||
| } | |||
| } | |||
| } | |||
| @@ -7,15 +7,15 @@ import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; | |||
| @XStreamAlias("xml") | |||
| public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { | |||
| @XStreamAlias("Voice") | |||
| @XStreamConverter(value=XStreamMediaIdConverter.class) | |||
| @XStreamConverter(value = XStreamMediaIdConverter.class) | |||
| private String mediaId; | |||
| public WxCpXmlOutVoiceMessage() { | |||
| this.msgType = WxConsts.XML_MSG_VOICE; | |||
| } | |||
| public String getMediaId() { | |||
| return mediaId; | |||
| } | |||
| @@ -23,5 +23,5 @@ public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { | |||
| public void setMediaId(String mediaId) { | |||
| this.mediaId = mediaId; | |||
| } | |||
| } | |||
| @@ -44,7 +44,7 @@ public class BaseBuilder<T> { | |||
| m.setToParty(this.toParty); | |||
| m.setToTag(this.toTag); | |||
| m.setSafe( | |||
| (this.safe == null || "".equals(this.safe))? WxConsts.CUSTOM_MSG_SAFE_NO: this.safe); | |||
| (this.safe == null || "".equals(this.safe)) ? WxConsts.CUSTOM_MSG_SAFE_NO : this.safe); | |||
| return m; | |||
| } | |||
| @@ -8,8 +8,8 @@ import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| * <pre> | |||
| * 用法: WxCustomMessage m = WxCustomMessage.FILE().mediaId(...).toUser(...).build(); | |||
| * </pre> | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class FileBuilder extends BaseBuilder<FileBuilder> { | |||
| private String mediaId; | |||
| @@ -8,8 +8,8 @@ import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| * <pre> | |||
| * 用法: WxCustomMessage m = WxCustomMessage.IMAGE().mediaId(...).toUser(...).build(); | |||
| * </pre> | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class ImageBuilder extends BaseBuilder<ImageBuilder> { | |||
| private String mediaId; | |||
| @@ -12,13 +12,13 @@ import java.util.List; | |||
| * 用法: | |||
| * WxCustomMessage m = WxCustomMessage.NEWS().addArticle(article).toUser(...).build(); | |||
| * </pre> | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class NewsBuilder extends BaseBuilder<NewsBuilder> { | |||
| private List<WxCpMessage.WxArticle> articles = new ArrayList<WxCpMessage.WxArticle>(); | |||
| public NewsBuilder() { | |||
| this.msgType = WxConsts.CUSTOM_MSG_NEWS; | |||
| } | |||
| @@ -8,8 +8,8 @@ import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| * <pre> | |||
| * 用法: WxCustomMessage m = WxCustomMessage.TEXT().content(...).toUser(...).build(); | |||
| * </pre> | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class TextBuilder extends BaseBuilder<TextBuilder> { | |||
| private String content; | |||
| @@ -14,8 +14,8 @@ import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| * .toUser(...) | |||
| * .build(); | |||
| * </pre> | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class VideoBuilder extends BaseBuilder<VideoBuilder> { | |||
| private String mediaId; | |||
| @@ -8,8 +8,8 @@ import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| * <pre> | |||
| * 用法: WxCustomMessage m = WxCustomMessage.VOICE().mediaId(...).toUser(...).build(); | |||
| * </pre> | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class VoiceBuilder extends BaseBuilder<VoiceBuilder> { | |||
| private String mediaId; | |||
| @@ -3,27 +3,27 @@ package me.chanjar.weixin.cp.bean.outxmlbuilder; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
| public abstract class BaseBuilder<BuilderType, ValueType> { | |||
| protected String toUserName; | |||
| protected String fromUserName; | |||
| public BuilderType toUser(String touser) { | |||
| this.toUserName = touser; | |||
| return (BuilderType) this; | |||
| } | |||
| public BuilderType fromUser(String fromusername) { | |||
| this.fromUserName = fromusername; | |||
| return (BuilderType) this; | |||
| } | |||
| public abstract ValueType build(); | |||
| public void setCommon(WxCpXmlOutMessage m) { | |||
| m.setToUserName(this.toUserName); | |||
| m.setFromUserName(this.fromUserName); | |||
| m.setCreateTime(System.currentTimeMillis() / 1000l); | |||
| } | |||
| } | |||
| @@ -4,6 +4,7 @@ import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage; | |||
| /** | |||
| * 图片消息builder | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class ImageBuilder extends BaseBuilder<ImageBuilder, WxCpXmlOutImageMessage> { | |||
| @@ -21,5 +22,5 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder, WxCpXmlOutImag | |||
| m.setMediaId(this.mediaId); | |||
| return m; | |||
| } | |||
| } | |||
| @@ -8,24 +8,25 @@ import java.util.List; | |||
| /** | |||
| * 图文消息builder | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class NewsBuilder extends BaseBuilder<NewsBuilder, WxCpXmlOutNewsMessage> { | |||
| protected final List<Item> articles = new ArrayList<Item>(); | |||
| public NewsBuilder addArticle(Item item) { | |||
| this.articles.add(item); | |||
| return this; | |||
| } | |||
| public WxCpXmlOutNewsMessage build() { | |||
| WxCpXmlOutNewsMessage m = new WxCpXmlOutNewsMessage(); | |||
| for(Item item : articles) { | |||
| for (Item item : articles) { | |||
| m.addArticle(item); | |||
| } | |||
| setCommon(m); | |||
| return m; | |||
| } | |||
| } | |||
| @@ -4,8 +4,8 @@ import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; | |||
| /** | |||
| * 文本消息builder | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class TextBuilder extends BaseBuilder<TextBuilder, WxCpXmlOutTextMessage> { | |||
| private String content; | |||
| @@ -4,8 +4,8 @@ import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage; | |||
| /** | |||
| * 视频消息builder | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class VideoBuilder extends BaseBuilder<VideoBuilder, WxCpXmlOutVideoMessage> { | |||
| @@ -17,15 +17,17 @@ public final class VideoBuilder extends BaseBuilder<VideoBuilder, WxCpXmlOutVide | |||
| this.title = title; | |||
| return this; | |||
| } | |||
| public VideoBuilder description(String description) { | |||
| this.description = description; | |||
| return this; | |||
| } | |||
| public VideoBuilder mediaId(String mediaId) { | |||
| this.mediaId = mediaId; | |||
| return this; | |||
| } | |||
| public WxCpXmlOutVideoMessage build() { | |||
| WxCpXmlOutVideoMessage m = new WxCpXmlOutVideoMessage(); | |||
| setCommon(m); | |||
| @@ -34,5 +36,5 @@ public final class VideoBuilder extends BaseBuilder<VideoBuilder, WxCpXmlOutVide | |||
| m.setMediaId(mediaId); | |||
| return m; | |||
| } | |||
| } | |||
| @@ -4,6 +4,7 @@ import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage; | |||
| /** | |||
| * 语音消息builder | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public final class VoiceBuilder extends BaseBuilder<VoiceBuilder, WxCpXmlOutVoiceMessage> { | |||
| @@ -14,12 +15,12 @@ public final class VoiceBuilder extends BaseBuilder<VoiceBuilder, WxCpXmlOutVoic | |||
| this.mediaId = mediaId; | |||
| return this; | |||
| } | |||
| public WxCpXmlOutVoiceMessage build() { | |||
| WxCpXmlOutVoiceMessage m = new WxCpXmlOutVoiceMessage(); | |||
| setCommon(m); | |||
| m.setMediaId(mediaId); | |||
| return m; | |||
| } | |||
| } | |||
| @@ -2,6 +2,10 @@ | |||
| * 对公众平台发送给公众账号的消息加解密示例代码. | |||
| * | |||
| * @copyright Copyright (c) 1998-2014 Tencent Inc. | |||
| * <p> | |||
| * 针对org.apache.commons.codec.binary.Base64, | |||
| * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本) | |||
| * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi | |||
| */ | |||
| // ------------------------------------------------------------------------ | |||
| @@ -37,7 +37,7 @@ public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDe | |||
| } | |||
| public WxCpDepart deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||
| throws JsonParseException { | |||
| throws JsonParseException { | |||
| WxCpDepart depart = new WxCpDepart(); | |||
| JsonObject departJson = json.getAsJsonObject(); | |||
| if (departJson.get("id") != null && !departJson.get("id").isJsonNull()) { | |||
| @@ -16,9 +16,7 @@ import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| import java.lang.reflect.Type; | |||
| /** | |||
| * | |||
| * @author Daniel Qian | |||
| * | |||
| */ | |||
| public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||
| @@ -83,7 +81,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||
| newsJsonObject.add("articles", articleJsonArray); | |||
| messageJson.add("news", newsJsonObject); | |||
| } | |||
| return messageJson; | |||
| } | |||
| @@ -27,7 +27,7 @@ public class WxCpTagGsonAdapter implements JsonSerializer<WxCpTag>, JsonDeserial | |||
| } | |||
| public WxCpTag deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||
| throws JsonParseException { | |||
| throws JsonParseException { | |||
| JsonObject jsonObject = json.getAsJsonObject(); | |||
| return new WxCpTag(GsonHelper.getString(jsonObject, "tagid"), GsonHelper.getString(jsonObject, "tagname")); | |||
| } | |||
| @@ -20,13 +20,13 @@ import java.lang.reflect.Type; | |||
| public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSerializer<WxCpUser> { | |||
| public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||
| throws JsonParseException { | |||
| throws JsonParseException { | |||
| JsonObject o = json.getAsJsonObject(); | |||
| WxCpUser user = new WxCpUser(); | |||
| user.setUserId(GsonHelper.getString(o, "userid")); | |||
| user.setName(GsonHelper.getString(o, "name")); | |||
| if(o.get("department") != null) { | |||
| if (o.get("department") != null) { | |||
| JsonArray departJsonArray = o.get("department").getAsJsonArray(); | |||
| Integer[] departIds = new Integer[departJsonArray.size()]; | |||
| int i = 0; | |||
| @@ -49,8 +49,8 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||
| JsonArray attrJsonElements = o.get("extattr").getAsJsonObject().get("attrs").getAsJsonArray(); | |||
| for (JsonElement attrJsonElement : attrJsonElements) { | |||
| WxCpUser.Attr attr = new WxCpUser.Attr( | |||
| GsonHelper.getString(attrJsonElement.getAsJsonObject(), "name"), | |||
| GsonHelper.getString(attrJsonElement.getAsJsonObject(), "value") | |||
| GsonHelper.getString(attrJsonElement.getAsJsonObject(), "name"), | |||
| GsonHelper.getString(attrJsonElement.getAsJsonObject(), "value") | |||
| ); | |||
| user.getExtAttrs().add(attr); | |||
| } | |||
| @@ -29,16 +29,16 @@ public class XStreamTransformer { | |||
| /** | |||
| * 注册扩展消息的解析器 | |||
| * @param clz 类型 | |||
| * | |||
| * @param clz 类型 | |||
| * @param xStream xml解析器 | |||
| */ | |||
| public static void register(Class clz,XStream xStream){ | |||
| CLASS_2_XSTREAM_INSTANCE.put(clz,xStream); | |||
| */ | |||
| public static void register(Class clz, XStream xStream) { | |||
| CLASS_2_XSTREAM_INSTANCE.put(clz, xStream); | |||
| } | |||
| /** | |||
| * pojo -> xml | |||
| * | |||
| */ | |||
| public static <T> String toXml(Class<T> clazz, T object) { | |||
| return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); | |||
| @@ -10,17 +10,6 @@ import java.io.InputStream; | |||
| public class ApiTestModule implements Module { | |||
| @Override | |||
| public void configure(Binder binder) { | |||
| InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); | |||
| WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, is1); | |||
| WxCpServiceImpl wxService = new WxCpServiceImpl(); | |||
| wxService.setWxCpConfigStorage(config); | |||
| binder.bind(WxCpServiceImpl.class).toInstance(wxService); | |||
| binder.bind(WxCpConfigStorage.class).toInstance(config); | |||
| } | |||
| public static <T> T fromXml(Class<T> clazz, InputStream is) { | |||
| XStream xstream = XStreamInitializer.getInstance(); | |||
| xstream.alias("xml", clazz); | |||
| @@ -28,9 +17,20 @@ public class ApiTestModule implements Module { | |||
| return (T) xstream.fromXML(is); | |||
| } | |||
| @Override | |||
| public void configure(Binder binder) { | |||
| InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); | |||
| WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, is1); | |||
| WxCpServiceImpl wxService = new WxCpServiceImpl(); | |||
| wxService.setWxCpConfigStorage(config); | |||
| binder.bind(WxCpServiceImpl.class).toInstance(wxService); | |||
| binder.bind(WxCpConfigStorage.class).toInstance(config); | |||
| } | |||
| @XStreamAlias("xml") | |||
| public static class WxXmlCpInMemoryConfigStorage extends WxCpInMemoryConfigStorage { | |||
| protected String userId; | |||
| protected String departmentId; | |||
| @@ -40,6 +40,7 @@ public class ApiTestModule implements Module { | |||
| public String getUserId() { | |||
| return userId; | |||
| } | |||
| public void setUserId(String userId) { | |||
| this.userId = userId; | |||
| } | |||
| @@ -63,11 +64,11 @@ public class ApiTestModule implements Module { | |||
| @Override | |||
| public String toString() { | |||
| return super.toString() + " > WxXmlCpConfigStorage{" + | |||
| "userId='" + userId + '\'' + | |||
| ", departmentId='" + departmentId + '\'' + | |||
| ", tagId='" + tagId + '\'' + | |||
| '}'; | |||
| "userId='" + userId + '\'' + | |||
| ", departmentId='" + departmentId + '\'' + | |||
| ", tagId='" + tagId + '\'' + | |||
| '}'; | |||
| } | |||
| } | |||
| } | |||
| @@ -9,8 +9,8 @@ import org.testng.annotations.Test; | |||
| /** | |||
| * 基础API测试 | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| @Test(groups = "baseAPI") | |||
| @Guice(modules = ApiTestModule.class) | |||
| @@ -14,7 +14,7 @@ import java.util.concurrent.Future; | |||
| @Test | |||
| public class WxCpBusyRetryTest { | |||
| @DataProvider(name="getService") | |||
| @DataProvider(name = "getService") | |||
| public Object[][] getService() { | |||
| WxCpService service = new WxCpServiceImpl() { | |||
| @@ -28,8 +28,8 @@ public class WxCpBusyRetryTest { | |||
| service.setMaxRetryTimes(3); | |||
| service.setRetrySleepMillis(500); | |||
| return new Object[][] { | |||
| new Object[] { service } | |||
| return new Object[][]{ | |||
| new Object[]{service} | |||
| }; | |||
| } | |||
| @@ -44,7 +44,7 @@ public class WxCpDepartAPITest { | |||
| } | |||
| } | |||
| @Test(dependsOnMethods = { "testDepartGet", "testDepartCreate" }) | |||
| @Test(dependsOnMethods = {"testDepartGet", "testDepartCreate"}) | |||
| public void testDepartUpdate() throws WxErrorException { | |||
| System.out.println("=================更新部门"); | |||
| depart.setName("子部门改名" + System.currentTimeMillis()); | |||
| @@ -16,8 +16,8 @@ import java.util.List; | |||
| /** | |||
| * 测试多媒体文件上传下载 | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| //@Test(groups="mediaAPI", dependsOnGroups="baseAPI") | |||
| @Test | |||
| @@ -28,15 +28,15 @@ public class WxCpMediaAPITest { | |||
| protected WxCpServiceImpl wxService; | |||
| private List<String> media_ids = new ArrayList<String>(); | |||
| @Test(dataProvider="uploadMedia") | |||
| @Test(dataProvider = "uploadMedia") | |||
| public void testUploadMedia(String mediaType, String fileType, String fileName) throws WxErrorException, IOException { | |||
| InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName); | |||
| WxMediaUploadResult res = wxService.mediaUpload(mediaType, fileType, inputStream); | |||
| Assert.assertNotNull(res.getType()); | |||
| Assert.assertNotNull(res.getCreatedAt()); | |||
| Assert.assertTrue(res.getMediaId() != null || res.getThumbMediaId() != null); | |||
| if (res.getMediaId() != null) { | |||
| media_ids.add(res.getMediaId()); | |||
| } | |||
| @@ -44,29 +44,29 @@ public class WxCpMediaAPITest { | |||
| media_ids.add(res.getThumbMediaId()); | |||
| } | |||
| } | |||
| @DataProvider | |||
| public Object[][] uploadMedia() { | |||
| return new Object[][] { | |||
| new Object[] { WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, "mm.jpeg" }, | |||
| new Object[] { WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, "mm.mp3" }, | |||
| new Object[] { WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, "mm.mp4" }, | |||
| new Object[] { WxConsts.MEDIA_FILE, WxConsts.FILE_JPG, "mm.jpeg" } | |||
| return new Object[][]{ | |||
| new Object[]{WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, "mm.jpeg"}, | |||
| new Object[]{WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, "mm.mp3"}, | |||
| new Object[]{WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, "mm.mp4"}, | |||
| new Object[]{WxConsts.MEDIA_FILE, WxConsts.FILE_JPG, "mm.jpeg"} | |||
| }; | |||
| } | |||
| @Test(dependsOnMethods = { "testUploadMedia" }, dataProvider="downloadMedia") | |||
| @Test(dependsOnMethods = {"testUploadMedia"}, dataProvider = "downloadMedia") | |||
| public void testDownloadMedia(String media_id) throws WxErrorException { | |||
| wxService.mediaDownload(media_id); | |||
| } | |||
| @DataProvider | |||
| public Object[][] downloadMedia() { | |||
| Object[][] params = new Object[this.media_ids.size()][]; | |||
| for (int i = 0; i < this.media_ids.size(); i++) { | |||
| params[i] = new Object[] { this.media_ids.get(i) }; | |||
| params[i] = new Object[]{this.media_ids.get(i)}; | |||
| } | |||
| return params; | |||
| } | |||
| } | |||
| @@ -12,7 +12,7 @@ import org.testng.annotations.Test; | |||
| * @author Daniel Qian | |||
| * | |||
| */ | |||
| @Test(groups="customMessageAPI", dependsOnGroups = "baseAPI") | |||
| @Test(groups = "customMessageAPI", dependsOnGroups = "baseAPI") | |||
| @Guice(modules = ApiTestModule.class) | |||
| public class WxCpMessageAPITest { | |||
| @@ -29,11 +29,11 @@ public class WxCpMessageAPITest { | |||
| wxService.messageSend(message1); | |||
| WxCpMessage message2 = WxCpMessage | |||
| .TEXT() | |||
| .agentId(configStorage.getAgentId()) | |||
| .toUser(configStorage.getUserId()) | |||
| .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>") | |||
| .build(); | |||
| .TEXT() | |||
| .agentId(configStorage.getAgentId()) | |||
| .toUser(configStorage.getUserId()) | |||
| .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>") | |||
| .build(); | |||
| wxService.messageSend(message2); | |||
| } | |||
| @@ -13,45 +13,45 @@ import java.util.Map; | |||
| /** | |||
| * 测试消息路由器 | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| @Test | |||
| public class WxCpMessageRouterTest { | |||
| @Test(enabled = false) | |||
| public void prepare(boolean async, StringBuffer sb, WxCpMessageRouter router) { | |||
| router | |||
| .rule() | |||
| .async(async) | |||
| .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1") | |||
| .handler(new WxEchoCpMessageHandler(sb, "COMBINE_4")) | |||
| .end() | |||
| .rule() | |||
| .async(async) | |||
| .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1") | |||
| .handler(new WxEchoCpMessageHandler(sb, "COMBINE_3")) | |||
| .end() | |||
| .rule() | |||
| .async(async) | |||
| .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK) | |||
| .handler(new WxEchoCpMessageHandler(sb, "COMBINE_2")) | |||
| .end() | |||
| .rule().async(async).msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end() | |||
| .rule().async(async).event(WxConsts.EVT_CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EVT_CLICK)).end() | |||
| .rule().async(async).eventKey("KEY_1").handler(new WxEchoCpMessageHandler(sb, "KEY_1")).end() | |||
| .rule().async(async).content("CONTENT_1").handler(new WxEchoCpMessageHandler(sb, "CONTENT_1")).end() | |||
| .rule().async(async).rContent(".*bc.*").handler(new WxEchoCpMessageHandler(sb, "abcd")).end() | |||
| .rule().async(async).matcher(new WxCpMessageMatcher() { | |||
| @Override | |||
| public boolean match(WxCpXmlMessage message) { | |||
| return "strangeformat".equals(message.getFormat()); | |||
| } | |||
| }).handler(new WxEchoCpMessageHandler(sb, "matcher")).end() | |||
| .rule().async(async).handler(new WxEchoCpMessageHandler(sb, "ALL")).end(); | |||
| .rule() | |||
| .async(async) | |||
| .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1") | |||
| .handler(new WxEchoCpMessageHandler(sb, "COMBINE_4")) | |||
| .end() | |||
| .rule() | |||
| .async(async) | |||
| .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1") | |||
| .handler(new WxEchoCpMessageHandler(sb, "COMBINE_3")) | |||
| .end() | |||
| .rule() | |||
| .async(async) | |||
| .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK) | |||
| .handler(new WxEchoCpMessageHandler(sb, "COMBINE_2")) | |||
| .end() | |||
| .rule().async(async).msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end() | |||
| .rule().async(async).event(WxConsts.EVT_CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EVT_CLICK)).end() | |||
| .rule().async(async).eventKey("KEY_1").handler(new WxEchoCpMessageHandler(sb, "KEY_1")).end() | |||
| .rule().async(async).content("CONTENT_1").handler(new WxEchoCpMessageHandler(sb, "CONTENT_1")).end() | |||
| .rule().async(async).rContent(".*bc.*").handler(new WxEchoCpMessageHandler(sb, "abcd")).end() | |||
| .rule().async(async).matcher(new WxCpMessageMatcher() { | |||
| @Override | |||
| public boolean match(WxCpXmlMessage message) { | |||
| return "strangeformat".equals(message.getFormat()); | |||
| } | |||
| }).handler(new WxEchoCpMessageHandler(sb, "matcher")).end() | |||
| .rule().async(async).handler(new WxEchoCpMessageHandler(sb, "ALL")).end(); | |||
| } | |||
| @Test(dataProvider="messages-1") | |||
| @Test(dataProvider = "messages-1") | |||
| public void testSync(WxCpXmlMessage message, String expected) { | |||
| StringBuffer sb = new StringBuffer(); | |||
| WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| @@ -59,27 +59,27 @@ public class WxCpMessageRouterTest { | |||
| router.route(message); | |||
| Assert.assertEquals(sb.toString(), expected); | |||
| } | |||
| @Test(dataProvider="messages-1") | |||
| @Test(dataProvider = "messages-1") | |||
| public void testAsync(WxCpXmlMessage message, String expected) throws InterruptedException { | |||
| StringBuffer sb = new StringBuffer(); | |||
| WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| prepare(true, sb, router); | |||
| prepare(true, sb, router); | |||
| router.route(message); | |||
| Thread.sleep(500l); | |||
| Assert.assertEquals(sb.toString(), expected); | |||
| } | |||
| public void testConcurrency() throws InterruptedException { | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| router.rule().handler(new WxCpMessageHandler() { | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService, | |||
| WxSessionManager sessionManager) { | |||
| WxSessionManager sessionManager) { | |||
| return null; | |||
| } | |||
| }).end(); | |||
| final WxCpXmlMessage m = new WxCpXmlMessage(); | |||
| Runnable r = new Runnable() { | |||
| @Override | |||
| @@ -94,27 +94,27 @@ public class WxCpMessageRouterTest { | |||
| for (int i = 0; i < 10; i++) { | |||
| new Thread(r).start(); | |||
| } | |||
| Thread.sleep(1000l * 2); | |||
| } | |||
| @DataProvider(name="messages-1") | |||
| @DataProvider(name = "messages-1") | |||
| public Object[][] messages2() { | |||
| WxCpXmlMessage message1 = new WxCpXmlMessage(); | |||
| message1.setMsgType(WxConsts.XML_MSG_TEXT); | |||
| WxCpXmlMessage message2 = new WxCpXmlMessage(); | |||
| message2.setEvent(WxConsts.EVT_CLICK); | |||
| WxCpXmlMessage message3 = new WxCpXmlMessage(); | |||
| message3.setEventKey("KEY_1"); | |||
| WxCpXmlMessage message4 = new WxCpXmlMessage(); | |||
| message4.setContent("CONTENT_1"); | |||
| WxCpXmlMessage message5 = new WxCpXmlMessage(); | |||
| message5.setContent("BLA"); | |||
| WxCpXmlMessage message6 = new WxCpXmlMessage(); | |||
| message6.setContent("abcd"); | |||
| @@ -124,12 +124,12 @@ public class WxCpMessageRouterTest { | |||
| WxCpXmlMessage c2 = new WxCpXmlMessage(); | |||
| c2.setMsgType(WxConsts.XML_MSG_TEXT); | |||
| c2.setEvent(WxConsts.EVT_CLICK); | |||
| WxCpXmlMessage c3 = new WxCpXmlMessage(); | |||
| c3.setMsgType(WxConsts.XML_MSG_TEXT); | |||
| c3.setEvent(WxConsts.EVT_CLICK); | |||
| c3.setEventKey("KEY_1"); | |||
| WxCpXmlMessage c4 = new WxCpXmlMessage(); | |||
| c4.setMsgType(WxConsts.XML_MSG_TEXT); | |||
| c4.setEvent(WxConsts.EVT_CLICK); | |||
| @@ -137,37 +137,18 @@ public class WxCpMessageRouterTest { | |||
| c4.setContent("CONTENT_1"); | |||
| return new Object[][] { | |||
| new Object[] { message1, WxConsts.XML_MSG_TEXT + "," }, | |||
| new Object[] { message2, WxConsts.EVT_CLICK + "," }, | |||
| new Object[] { message3, "KEY_1," }, | |||
| new Object[] { message4, "CONTENT_1," }, | |||
| new Object[] { message5, "ALL," }, | |||
| new Object[] { message6, "abcd," }, | |||
| new Object[] { message7, "matcher," }, | |||
| new Object[] { c2, "COMBINE_2," }, | |||
| new Object[] { c3, "COMBINE_3," }, | |||
| new Object[] { c4, "COMBINE_4," } | |||
| return new Object[][]{ | |||
| new Object[]{message1, WxConsts.XML_MSG_TEXT + ","}, | |||
| new Object[]{message2, WxConsts.EVT_CLICK + ","}, | |||
| new Object[]{message3, "KEY_1,"}, | |||
| new Object[]{message4, "CONTENT_1,"}, | |||
| new Object[]{message5, "ALL,"}, | |||
| new Object[]{message6, "abcd,"}, | |||
| new Object[]{message7, "matcher,"}, | |||
| new Object[]{c2, "COMBINE_2,"}, | |||
| new Object[]{c3, "COMBINE_3,"}, | |||
| new Object[]{c4, "COMBINE_4,"} | |||
| }; | |||
| } | |||
| public static class WxEchoCpMessageHandler implements WxCpMessageHandler { | |||
| private StringBuffer sb; | |||
| private String echoStr; | |||
| public WxEchoCpMessageHandler(StringBuffer sb, String echoStr) { | |||
| this.sb = sb; | |||
| this.echoStr = echoStr; | |||
| } | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService, | |||
| WxSessionManager sessionManager) { | |||
| sb.append(this.echoStr).append(','); | |||
| return null; | |||
| } | |||
| } | |||
| @@ -180,8 +161,8 @@ public class WxCpMessageRouterTest { | |||
| ism.setProcessExpiresFrequency(1); | |||
| ism.setBackgroundProcessorDelay(1); | |||
| return new Object[][] { | |||
| new Object[] { ism } | |||
| return new Object[][]{ | |||
| new Object[]{ism} | |||
| }; | |||
| } | |||
| @@ -193,8 +174,8 @@ public class WxCpMessageRouterTest { | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| router.setSessionManager(ism); | |||
| router | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).next() | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).end(); | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).next() | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).end(); | |||
| WxCpXmlMessage msg = new WxCpXmlMessage(); | |||
| msg.setFromUserName("abc"); | |||
| @@ -213,8 +194,8 @@ public class WxCpMessageRouterTest { | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| router.setSessionManager(ism); | |||
| router | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).next() | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).end(); | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).next() | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).end(); | |||
| WxCpXmlMessage msg = new WxCpXmlMessage(); | |||
| msg.setFromUserName("abc"); | |||
| @@ -227,8 +208,8 @@ public class WxCpMessageRouterTest { | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| router.setSessionManager(ism); | |||
| router | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).next() | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).end(); | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).next() | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).end(); | |||
| WxCpXmlMessage msg = new WxCpXmlMessage(); | |||
| msg.setFromUserName("abc"); | |||
| @@ -247,8 +228,8 @@ public class WxCpMessageRouterTest { | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| router.setSessionManager(ism); | |||
| router | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).next() | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).end(); | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).next() | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).end(); | |||
| WxCpXmlMessage msg = new WxCpXmlMessage(); | |||
| msg.setFromUserName("abc"); | |||
| @@ -267,7 +248,7 @@ public class WxCpMessageRouterTest { | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| router.setSessionManager(ism); | |||
| router | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).end(); | |||
| .rule().async(false).handler(new WxSessionMessageHandler()).end(); | |||
| WxCpXmlMessage msg = new WxCpXmlMessage(); | |||
| msg.setFromUserName("abc"); | |||
| @@ -281,7 +262,7 @@ public class WxCpMessageRouterTest { | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| router.setSessionManager(ism); | |||
| router | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).end(); | |||
| .rule().async(true).handler(new WxSessionMessageHandler()).end(); | |||
| WxCpXmlMessage msg = new WxCpXmlMessage(); | |||
| msg.setFromUserName("abc"); | |||
| @@ -292,11 +273,30 @@ public class WxCpMessageRouterTest { | |||
| } | |||
| } | |||
| public static class WxSessionMessageHandler implements WxCpMessageHandler { | |||
| public static class WxEchoCpMessageHandler implements WxCpMessageHandler { | |||
| private StringBuffer sb; | |||
| private String echoStr; | |||
| public WxEchoCpMessageHandler(StringBuffer sb, String echoStr) { | |||
| this.sb = sb; | |||
| this.echoStr = echoStr; | |||
| } | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService, | |||
| WxSessionManager sessionManager) { | |||
| sb.append(this.echoStr).append(','); | |||
| return null; | |||
| } | |||
| } | |||
| public static class WxSessionMessageHandler implements WxCpMessageHandler { | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService, | |||
| WxSessionManager sessionManager) { | |||
| WxSessionManager sessionManager) { | |||
| sessionManager.getSession(wxMessage.getFromUserName()); | |||
| return null; | |||
| } | |||
| @@ -41,7 +41,7 @@ public class WxCpTagAPITest { | |||
| @Test(dependsOnMethods = "testTagGet") | |||
| public void testTagAddUsers() throws Exception { | |||
| List<String> userIds = new ArrayList<String>(); | |||
| userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage)configStorage).getUserId()); | |||
| userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) configStorage).getUserId()); | |||
| wxService.tagAddUsers(tagId, userIds, null); | |||
| } | |||
| @@ -54,7 +54,7 @@ public class WxCpTagAPITest { | |||
| @Test(dependsOnMethods = "testTagGetUsers") | |||
| public void testTagRemoveUsers() throws Exception { | |||
| List<String> userIds = new ArrayList<String>(); | |||
| userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage)configStorage).getUserId()); | |||
| userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) configStorage).getUserId()); | |||
| wxService.tagRemoveUsers(tagId, userIds); | |||
| } | |||
| @@ -28,7 +28,7 @@ public class WxCpUserAPITest { | |||
| WxCpUser user = new WxCpUser(); | |||
| user.setUserId("some.woman"); | |||
| user.setName("Some Woman"); | |||
| user.setDepartIds(new Integer[] { 9, 8 }); | |||
| user.setDepartIds(new Integer[]{9, 8}); | |||
| user.setEmail("none@none.com"); | |||
| user.setGender("女"); | |||
| user.setMobile("13560084979"); | |||
| @@ -1,90 +1,88 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import org.testng.Assert; | |||
| import org.testng.annotations.DataProvider; | |||
| import org.testng.annotations.Guice; | |||
| import org.testng.annotations.Test; | |||
| import com.google.inject.Inject; | |||
| import me.chanjar.weixin.common.api.WxConsts; | |||
| import me.chanjar.weixin.common.bean.menu.WxMenu; | |||
| import me.chanjar.weixin.common.bean.menu.WxMenuButton; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import org.testng.Assert; | |||
| import org.testng.annotations.DataProvider; | |||
| import org.testng.annotations.Guice; | |||
| import org.testng.annotations.Test; | |||
| /** | |||
| * 测试菜单 | |||
| * @author Daniel Qian | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| @Test(groups="menuAPI", dependsOnGroups="baseAPI") | |||
| @Test(groups = "menuAPI", dependsOnGroups = "baseAPI") | |||
| @Guice(modules = ApiTestModule.class) | |||
| public class WxMenuAPITest { | |||
| @Inject | |||
| protected WxCpServiceImpl wxService; | |||
| @Test(dataProvider = "menu") | |||
| public void testCreateMenu(WxMenu wxMenu) throws WxErrorException { | |||
| wxService.menuCreate(wxMenu); | |||
| } | |||
| @Test(dependsOnMethods = { "testCreateMenu"}) | |||
| @Test(dependsOnMethods = {"testCreateMenu"}) | |||
| public void testGetMenu() throws WxErrorException { | |||
| Assert.assertNotNull(wxService.menuGet()); | |||
| } | |||
| @Test(dependsOnMethods = { "testGetMenu"}) | |||
| @Test(dependsOnMethods = {"testGetMenu"}) | |||
| public void testDeleteMenu() throws WxErrorException { | |||
| wxService.menuDelete(); | |||
| } | |||
| @DataProvider(name="menu") | |||
| @DataProvider(name = "menu") | |||
| public Object[][] getMenu() { | |||
| WxMenu menu = new WxMenu(); | |||
| WxMenuButton button1 = new WxMenuButton(); | |||
| button1.setType(WxConsts.BUTTON_CLICK); | |||
| button1.setName("今日歌曲"); | |||
| button1.setKey("V1001_TODAY_MUSIC"); | |||
| WxMenuButton button2 = new WxMenuButton(); | |||
| button2.setType(WxConsts.BUTTON_CLICK); | |||
| button2.setName("歌手简介"); | |||
| button2.setKey("V1001_TODAY_SINGER"); | |||
| WxMenuButton button3 = new WxMenuButton(); | |||
| button3.setName("菜单"); | |||
| menu.getButtons().add(button1); | |||
| menu.getButtons().add(button2); | |||
| menu.getButtons().add(button3); | |||
| WxMenuButton button31 = new WxMenuButton(); | |||
| button31.setType(WxConsts.BUTTON_VIEW); | |||
| button31.setName("搜索"); | |||
| button31.setUrl("http://www.soso.com/"); | |||
| WxMenuButton button32 = new WxMenuButton(); | |||
| button32.setType(WxConsts.BUTTON_VIEW); | |||
| button32.setName("视频"); | |||
| button32.setUrl("http://v.qq.com/"); | |||
| WxMenuButton button33 = new WxMenuButton(); | |||
| button33.setType(WxConsts.BUTTON_CLICK); | |||
| button33.setName("赞一下我们"); | |||
| button33.setKey("V1001_GOOD"); | |||
| button3.getSubButtons().add(button31); | |||
| button3.getSubButtons().add(button32); | |||
| button3.getSubButtons().add(button33); | |||
| return new Object[][] { | |||
| new Object[] { | |||
| menu | |||
| } | |||
| return new Object[][]{ | |||
| new Object[]{ | |||
| menu | |||
| } | |||
| }; | |||
| } | |||
| } | |||
| @@ -15,12 +15,12 @@ public class WxCpMessageTest { | |||
| reply.setContent("sfsfdsdf"); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); | |||
| } | |||
| public void testTextBuild() { | |||
| WxCpMessage reply = WxCpMessage.TEXT().toUser("OPENID").content("sfsfdsdf").build(); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); | |||
| } | |||
| public void testImageReply() { | |||
| WxCpMessage reply = new WxCpMessage(); | |||
| reply.setToUser("OPENID"); | |||
| @@ -28,12 +28,12 @@ public class WxCpMessageTest { | |||
| reply.setMediaId("MEDIA_ID"); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); | |||
| } | |||
| public void testImageBuild() { | |||
| WxCpMessage reply = WxCpMessage.IMAGE().toUser("OPENID").mediaId("MEDIA_ID").build(); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); | |||
| } | |||
| public void testVoiceReply() { | |||
| WxCpMessage reply = new WxCpMessage(); | |||
| reply.setToUser("OPENID"); | |||
| @@ -41,12 +41,12 @@ public class WxCpMessageTest { | |||
| reply.setMediaId("MEDIA_ID"); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); | |||
| } | |||
| public void testVoiceBuild() { | |||
| WxCpMessage reply = WxCpMessage.VOICE().toUser("OPENID").mediaId("MEDIA_ID").build(); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); | |||
| } | |||
| public void testVideoReply() { | |||
| WxCpMessage reply = new WxCpMessage(); | |||
| reply.setToUser("OPENID"); | |||
| @@ -57,24 +57,24 @@ public class WxCpMessageTest { | |||
| reply.setDescription("DESCRIPTION"); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); | |||
| } | |||
| public void testVideoBuild() { | |||
| WxCpMessage reply = WxCpMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID").thumbMediaId("MEDIA_ID").description("DESCRIPTION").build(); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); | |||
| } | |||
| public void testNewsReply() { | |||
| WxCpMessage reply = new WxCpMessage(); | |||
| reply.setToUser("OPENID"); | |||
| reply.setMsgType(WxConsts.CUSTOM_MSG_NEWS); | |||
| WxArticle article1 = new WxArticle(); | |||
| article1.setUrl("URL"); | |||
| article1.setPicUrl("PIC_URL"); | |||
| article1.setDescription("Is Really A Happy Day"); | |||
| article1.setTitle("Happy Day"); | |||
| reply.getArticles().add(article1); | |||
| WxArticle article2 = new WxArticle(); | |||
| article2.setUrl("URL"); | |||
| article2.setPicUrl("PIC_URL"); | |||
| @@ -85,14 +85,14 @@ public class WxCpMessageTest { | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); | |||
| } | |||
| public void testNewsBuild() { | |||
| WxArticle article1 = new WxArticle(); | |||
| article1.setUrl("URL"); | |||
| article1.setPicUrl("PIC_URL"); | |||
| article1.setDescription("Is Really A Happy Day"); | |||
| article1.setTitle("Happy Day"); | |||
| WxArticle article2 = new WxArticle(); | |||
| article2.setUrl("URL"); | |||
| article2.setPicUrl("PIC_URL"); | |||
| @@ -103,5 +103,5 @@ public class WxCpMessageTest { | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); | |||
| } | |||
| } | |||
| @@ -10,49 +10,49 @@ public class WxCpXmlMessageTest { | |||
| public void testFromXml() { | |||
| String xml = "<xml>" | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName> " | |||
| + "<CreateTime>1348831860</CreateTime>" | |||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||
| + "<Content><![CDATA[this is a test]]></Content>" | |||
| + "<MsgId>1234567890123456</MsgId>" | |||
| + "<PicUrl><![CDATA[this is a url]]></PicUrl>" | |||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||
| + "<Format><![CDATA[Format]]></Format>" | |||
| + "<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>" | |||
| + "<Location_X>23.134521</Location_X>" | |||
| + "<Location_Y>113.358803</Location_Y>" | |||
| + "<Scale>20</Scale>" | |||
| + "<Label><![CDATA[位置信息]]></Label>" | |||
| + "<Description><![CDATA[公众平台官网链接]]></Description>" | |||
| + "<Url><![CDATA[url]]></Url>" | |||
| + "<Title><![CDATA[公众平台官网链接]]></Title>" | |||
| + "<Event><![CDATA[subscribe]]></Event>" | |||
| + "<EventKey><![CDATA[qrscene_123123]]></EventKey>" | |||
| + "<Ticket><![CDATA[TICKET]]></Ticket>" | |||
| + "<Latitude>23.137466</Latitude>" | |||
| + "<Longitude>113.352425</Longitude>" | |||
| + "<Precision>119.385040</Precision>" | |||
| + "<ScanCodeInfo>" | |||
| + " <ScanType><![CDATA[qrcode]]></ScanType>" | |||
| + " <ScanResult><![CDATA[1]]></ScanResult>" | |||
| + "</ScanCodeInfo>" | |||
| + "<SendPicsInfo>" | |||
| + " <Count>1</Count>\n" | |||
| + " <PicList>" | |||
| + " <item>" | |||
| + " <PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>" | |||
| + " </item>" | |||
| + " </PicList>" | |||
| + "</SendPicsInfo>" | |||
| + "<SendLocationInfo>" | |||
| + " <Location_X><![CDATA[23]]></Location_X>\n" | |||
| + " <Location_Y><![CDATA[113]]></Location_Y>\n" | |||
| + " <Scale><![CDATA[15]]></Scale>\n" | |||
| + " <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>\n" | |||
| + " <Poiname><![CDATA[wo de poi]]></Poiname>\n" | |||
| + "</SendLocationInfo>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName> " | |||
| + "<CreateTime>1348831860</CreateTime>" | |||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||
| + "<Content><![CDATA[this is a test]]></Content>" | |||
| + "<MsgId>1234567890123456</MsgId>" | |||
| + "<PicUrl><![CDATA[this is a url]]></PicUrl>" | |||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||
| + "<Format><![CDATA[Format]]></Format>" | |||
| + "<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>" | |||
| + "<Location_X>23.134521</Location_X>" | |||
| + "<Location_Y>113.358803</Location_Y>" | |||
| + "<Scale>20</Scale>" | |||
| + "<Label><![CDATA[位置信息]]></Label>" | |||
| + "<Description><![CDATA[公众平台官网链接]]></Description>" | |||
| + "<Url><![CDATA[url]]></Url>" | |||
| + "<Title><![CDATA[公众平台官网链接]]></Title>" | |||
| + "<Event><![CDATA[subscribe]]></Event>" | |||
| + "<EventKey><![CDATA[qrscene_123123]]></EventKey>" | |||
| + "<Ticket><![CDATA[TICKET]]></Ticket>" | |||
| + "<Latitude>23.137466</Latitude>" | |||
| + "<Longitude>113.352425</Longitude>" | |||
| + "<Precision>119.385040</Precision>" | |||
| + "<ScanCodeInfo>" | |||
| + " <ScanType><![CDATA[qrcode]]></ScanType>" | |||
| + " <ScanResult><![CDATA[1]]></ScanResult>" | |||
| + "</ScanCodeInfo>" | |||
| + "<SendPicsInfo>" | |||
| + " <Count>1</Count>\n" | |||
| + " <PicList>" | |||
| + " <item>" | |||
| + " <PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>" | |||
| + " </item>" | |||
| + " </PicList>" | |||
| + "</SendPicsInfo>" | |||
| + "<SendLocationInfo>" | |||
| + " <Location_X><![CDATA[23]]></Location_X>\n" | |||
| + " <Location_Y><![CDATA[113]]></Location_Y>\n" | |||
| + " <Scale><![CDATA[15]]></Scale>\n" | |||
| + " <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>\n" | |||
| + " <Poiname><![CDATA[wo de poi]]></Poiname>\n" | |||
| + "</SendLocationInfo>" | |||
| + "</xml>"; | |||
| WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); | |||
| Assert.assertEquals(wxMessage.getToUserName(), "toUser"); | |||
| Assert.assertEquals(wxMessage.getFromUserName(), "fromUser"); | |||
| @@ -87,5 +87,5 @@ public class WxCpXmlMessageTest { | |||
| Assert.assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); | |||
| Assert.assertEquals(wxMessage.getSendLocationInfo().getPoiname(), "wo de poi"); | |||
| } | |||
| } | |||
| @@ -12,37 +12,37 @@ public class WxCpXmlOutImageMessageTest { | |||
| m.setCreateTime(1122l); | |||
| m.setFromUserName("from"); | |||
| m.setToUserName("to"); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[image]]></MsgType>" | |||
| + "<Image><MediaId><![CDATA[ddfefesfsdfef]]></MediaId></Image>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[image]]></MsgType>" | |||
| + "<Image><MediaId><![CDATA[ddfefesfsdfef]]></MediaId></Image>" | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals(m.toXml().replaceAll("\\s", ""), expected.replaceAll("\\s", "")); | |||
| } | |||
| public void testBuild() { | |||
| WxCpXmlOutImageMessage m = WxCpXmlOutMessage.IMAGE().mediaId("ddfefesfsdfef").fromUser("from").toUser("to").build(); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[image]]></MsgType>" | |||
| + "<Image><MediaId><![CDATA[ddfefesfsdfef]]></MediaId></Image>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[image]]></MsgType>" | |||
| + "<Image><MediaId><![CDATA[ddfefesfsdfef]]></MediaId></Image>" | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals( | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| } | |||
| } | |||
| @@ -11,7 +11,7 @@ public class WxCpXmlOutNewsMessageTest { | |||
| m.setCreateTime(1122l); | |||
| m.setFromUserName("fromUser"); | |||
| m.setToUserName("toUser"); | |||
| WxCpXmlOutNewsMessage.Item item = new WxCpXmlOutNewsMessage.Item(); | |||
| item.setDescription("description"); | |||
| item.setPicUrl("picUrl"); | |||
| @@ -20,74 +20,74 @@ public class WxCpXmlOutNewsMessageTest { | |||
| m.addArticle(item); | |||
| m.addArticle(item); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[news]]></MsgType>" | |||
| + " <ArticleCount>2</ArticleCount>" | |||
| + " <Articles>" | |||
| + " <item>" | |||
| + " <Title><![CDATA[title]]></Title>" | |||
| + " <Description><![CDATA[description]]></Description>" | |||
| + " <PicUrl><![CDATA[picUrl]]></PicUrl>" | |||
| + " <Url><![CDATA[url]]></Url>" | |||
| + " </item>" | |||
| + " <item>" | |||
| + " <Title><![CDATA[title]]></Title>" | |||
| + " <Description><![CDATA[description]]></Description>" | |||
| + " <PicUrl><![CDATA[picUrl]]></PicUrl>" | |||
| + " <Url><![CDATA[url]]></Url>" | |||
| + " </item>" | |||
| + " </Articles>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[news]]></MsgType>" | |||
| + " <ArticleCount>2</ArticleCount>" | |||
| + " <Articles>" | |||
| + " <item>" | |||
| + " <Title><![CDATA[title]]></Title>" | |||
| + " <Description><![CDATA[description]]></Description>" | |||
| + " <PicUrl><![CDATA[picUrl]]></PicUrl>" | |||
| + " <Url><![CDATA[url]]></Url>" | |||
| + " </item>" | |||
| + " <item>" | |||
| + " <Title><![CDATA[title]]></Title>" | |||
| + " <Description><![CDATA[description]]></Description>" | |||
| + " <PicUrl><![CDATA[picUrl]]></PicUrl>" | |||
| + " <Url><![CDATA[url]]></Url>" | |||
| + " </item>" | |||
| + " </Articles>" | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals(m.toXml().replaceAll("\\s", ""), expected.replaceAll("\\s", "")); | |||
| } | |||
| public void testBuild() { | |||
| WxCpXmlOutNewsMessage.Item item = new WxCpXmlOutNewsMessage.Item(); | |||
| item.setDescription("description"); | |||
| item.setPicUrl("picUrl"); | |||
| item.setTitle("title"); | |||
| item.setUrl("url"); | |||
| WxCpXmlOutNewsMessage m = WxCpXmlOutMessage.NEWS() | |||
| .fromUser("fromUser") | |||
| .toUser("toUser") | |||
| .addArticle(item) | |||
| .addArticle(item) | |||
| .build(); | |||
| .fromUser("fromUser") | |||
| .toUser("toUser") | |||
| .addArticle(item) | |||
| .addArticle(item) | |||
| .build(); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[news]]></MsgType>" | |||
| + " <ArticleCount>2</ArticleCount>" | |||
| + " <Articles>" | |||
| + " <item>" | |||
| + " <Title><![CDATA[title]]></Title>" | |||
| + " <Description><![CDATA[description]]></Description>" | |||
| + " <PicUrl><![CDATA[picUrl]]></PicUrl>" | |||
| + " <Url><![CDATA[url]]></Url>" | |||
| + " </item>" | |||
| + " <item>" | |||
| + " <Title><![CDATA[title]]></Title>" | |||
| + " <Description><![CDATA[description]]></Description>" | |||
| + " <PicUrl><![CDATA[picUrl]]></PicUrl>" | |||
| + " <Url><![CDATA[url]]></Url>" | |||
| + " </item>" | |||
| + " </Articles>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[news]]></MsgType>" | |||
| + " <ArticleCount>2</ArticleCount>" | |||
| + " <Articles>" | |||
| + " <item>" | |||
| + " <Title><![CDATA[title]]></Title>" | |||
| + " <Description><![CDATA[description]]></Description>" | |||
| + " <PicUrl><![CDATA[picUrl]]></PicUrl>" | |||
| + " <Url><![CDATA[url]]></Url>" | |||
| + " </item>" | |||
| + " <item>" | |||
| + " <Title><![CDATA[title]]></Title>" | |||
| + " <Description><![CDATA[description]]></Description>" | |||
| + " <PicUrl><![CDATA[picUrl]]></PicUrl>" | |||
| + " <Url><![CDATA[url]]></Url>" | |||
| + " </item>" | |||
| + " </Articles>" | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals( | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| } | |||
| } | |||
| @@ -12,39 +12,39 @@ public class WxCpXmlOutTextMessageTest { | |||
| m.setCreateTime(1122l); | |||
| m.setFromUserName("from"); | |||
| m.setToUserName("to"); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||
| + "<Content><![CDATA[content]]></Content>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||
| + "<Content><![CDATA[content]]></Content>" | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals(m.toXml().replaceAll("\\s", ""), expected.replaceAll("\\s", "")); | |||
| } | |||
| public void testBuild() { | |||
| WxCpXmlOutTextMessage m = WxCpXmlOutMessage.TEXT().content("content").fromUser("from").toUser("to").build(); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||
| + "<Content><![CDATA[content]]></Content>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||
| + "<Content><![CDATA[content]]></Content>" | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals( | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| } | |||
| } | |||
| @@ -14,51 +14,51 @@ public class WxCpXmlOutVideoMessageTest { | |||
| m.setCreateTime(1122l); | |||
| m.setFromUserName("fromUser"); | |||
| m.setToUserName("toUser"); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[video]]></MsgType>" | |||
| + "<Video>" | |||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||
| + "<Title><![CDATA[title]]></Title>" | |||
| + "<Description><![CDATA[ddfff]]></Description>" | |||
| + "</Video> " | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[video]]></MsgType>" | |||
| + "<Video>" | |||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||
| + "<Title><![CDATA[title]]></Title>" | |||
| + "<Description><![CDATA[ddfff]]></Description>" | |||
| + "</Video> " | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals(m.toXml().replaceAll("\\s", ""), expected.replaceAll("\\s", "")); | |||
| } | |||
| public void testBuild() { | |||
| WxCpXmlOutVideoMessage m = WxCpXmlOutMessage.VIDEO() | |||
| .mediaId("media_id") | |||
| .fromUser("fromUser") | |||
| .toUser("toUser") | |||
| .title("title") | |||
| .description("ddfff") | |||
| .build(); | |||
| .mediaId("media_id") | |||
| .fromUser("fromUser") | |||
| .toUser("toUser") | |||
| .title("title") | |||
| .description("ddfff") | |||
| .build(); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[video]]></MsgType>" | |||
| + "<Video>" | |||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||
| + "<Title><![CDATA[title]]></Title>" | |||
| + "<Description><![CDATA[ddfff]]></Description>" | |||
| + "</Video> " | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[video]]></MsgType>" | |||
| + "<Video>" | |||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||
| + "<Title><![CDATA[title]]></Title>" | |||
| + "<Description><![CDATA[ddfff]]></Description>" | |||
| + "</Video> " | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals( | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| } | |||
| } | |||
| @@ -12,37 +12,37 @@ public class WxCpXmlOutVoiceMessageTest { | |||
| m.setCreateTime(1122l); | |||
| m.setFromUserName("from"); | |||
| m.setToUserName("to"); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[voice]]></MsgType>" | |||
| + "<Voice><MediaId><![CDATA[ddfefesfsdfef]]></MediaId></Voice>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[voice]]></MsgType>" | |||
| + "<Voice><MediaId><![CDATA[ddfefesfsdfef]]></MediaId></Voice>" | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals(m.toXml().replaceAll("\\s", ""), expected.replaceAll("\\s", "")); | |||
| } | |||
| public void testBuild() { | |||
| WxCpXmlOutVoiceMessage m = WxCpXmlOutMessage.VOICE().mediaId("ddfefesfsdfef").fromUser("from").toUser("to").build(); | |||
| String expected = "<xml>" | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[voice]]></MsgType>" | |||
| + "<Voice><MediaId><![CDATA[ddfefesfsdfef]]></MediaId></Voice>" | |||
| + "</xml>"; | |||
| + "<ToUserName><![CDATA[to]]></ToUserName>" | |||
| + "<FromUserName><![CDATA[from]]></FromUserName>" | |||
| + "<CreateTime>1122</CreateTime>" | |||
| + "<MsgType><![CDATA[voice]]></MsgType>" | |||
| + "<Voice><MediaId><![CDATA[ddfefesfsdfef]]></MediaId></Voice>" | |||
| + "</xml>"; | |||
| System.out.println(m.toXml()); | |||
| Assert.assertEquals( | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| m | |||
| .toXml() | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", ""), | |||
| expected | |||
| .replaceAll("\\s", "") | |||
| .replaceAll("<CreateTime>.*?</CreateTime>", "") | |||
| ); | |||
| } | |||
| } | |||
| @@ -13,17 +13,16 @@ import java.io.InputStream; | |||
| @XStreamAlias("xml") | |||
| class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage { | |||
| @Override | |||
| public String toString() { | |||
| return "SimpleWxConfigProvider [appidOrCorpid=" + corpId + ", corpSecret=" + corpSecret + ", accessToken=" + accessToken | |||
| + ", expiresTime=" + expiresTime + ", token=" + token + ", aesKey=" + aesKey + "]"; | |||
| } | |||
| public static WxCpDemoInMemoryConfigStorage fromXml(InputStream is) { | |||
| XStream xstream = XStreamInitializer.getInstance(); | |||
| xstream.processAnnotations(WxCpDemoInMemoryConfigStorage.class); | |||
| return (WxCpDemoInMemoryConfigStorage) xstream.fromXML(is); | |||
| } | |||
| @Override | |||
| public String toString() { | |||
| return "SimpleWxConfigProvider [appidOrCorpid=" + corpId + ", corpSecret=" + corpSecret + ", accessToken=" + accessToken | |||
| + ", expiresTime=" + expiresTime + ", token=" + token + ", aesKey=" + aesKey + "]"; | |||
| } | |||
| } | |||
| @@ -37,54 +37,54 @@ public class WxCpDemoServer { | |||
| } | |||
| private static void initWeixin() { | |||
| InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); | |||
| WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1); | |||
| wxCpConfigStorage = config; | |||
| wxCpService = new WxCpServiceImpl(); | |||
| wxCpService.setWxCpConfigStorage(config); | |||
| WxCpMessageHandler handler = new WxCpMessageHandler() { | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, | |||
| WxCpService wxCpService, WxSessionManager sessionManager) { | |||
| WxCpXmlOutTextMessage m = WxCpXmlOutMessage | |||
| .TEXT() | |||
| .content("测试加密消息") | |||
| .fromUser(wxMessage.getToUserName()) | |||
| .toUser(wxMessage.getFromUserName()) | |||
| .build(); | |||
| return m; | |||
| } | |||
| }; | |||
| WxCpMessageHandler oauth2handler = new WxCpMessageHandler() { | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, | |||
| WxCpService wxCpService, WxSessionManager sessionManager) { | |||
| String href = "<a href=\"" + wxCpService.oauth2buildAuthorizationUrl(wxCpConfigStorage.getOauth2redirectUri(), null) | |||
| + "\">测试oauth2</a>"; | |||
| return WxCpXmlOutMessage | |||
| .TEXT() | |||
| .content(href) | |||
| .fromUser(wxMessage.getToUserName()) | |||
| .toUser(wxMessage.getFromUserName()).build(); | |||
| } | |||
| }; | |||
| wxCpMessageRouter = new WxCpMessageRouter(wxCpService); | |||
| wxCpMessageRouter | |||
| .rule() | |||
| .async(false) | |||
| .content("哈哈") // 拦截内容为“哈哈”的消息 | |||
| .handler(handler) | |||
| .end() | |||
| .rule() | |||
| .async(false) | |||
| .content("oauth") | |||
| .handler(oauth2handler) | |||
| .end() | |||
| ; | |||
| InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); | |||
| WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1); | |||
| wxCpConfigStorage = config; | |||
| wxCpService = new WxCpServiceImpl(); | |||
| wxCpService.setWxCpConfigStorage(config); | |||
| WxCpMessageHandler handler = new WxCpMessageHandler() { | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, | |||
| WxCpService wxCpService, WxSessionManager sessionManager) { | |||
| WxCpXmlOutTextMessage m = WxCpXmlOutMessage | |||
| .TEXT() | |||
| .content("测试加密消息") | |||
| .fromUser(wxMessage.getToUserName()) | |||
| .toUser(wxMessage.getFromUserName()) | |||
| .build(); | |||
| return m; | |||
| } | |||
| }; | |||
| WxCpMessageHandler oauth2handler = new WxCpMessageHandler() { | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, | |||
| WxCpService wxCpService, WxSessionManager sessionManager) { | |||
| String href = "<a href=\"" + wxCpService.oauth2buildAuthorizationUrl(wxCpConfigStorage.getOauth2redirectUri(), null) | |||
| + "\">测试oauth2</a>"; | |||
| return WxCpXmlOutMessage | |||
| .TEXT() | |||
| .content(href) | |||
| .fromUser(wxMessage.getToUserName()) | |||
| .toUser(wxMessage.getFromUserName()).build(); | |||
| } | |||
| }; | |||
| wxCpMessageRouter = new WxCpMessageRouter(wxCpService); | |||
| wxCpMessageRouter | |||
| .rule() | |||
| .async(false) | |||
| .content("哈哈") // 拦截内容为“哈哈”的消息 | |||
| .handler(handler) | |||
| .end() | |||
| .rule() | |||
| .async(false) | |||
| .content("oauth") | |||
| .handler(oauth2handler) | |||
| .end() | |||
| ; | |||
| } | |||
| } | |||
| @@ -24,7 +24,7 @@ public class WxCpEndpointServlet extends HttpServlet { | |||
| protected WxCpMessageRouter wxCpMessageRouter; | |||
| public WxCpEndpointServlet(WxCpConfigStorage wxCpConfigStorage, WxCpService wxCpService, | |||
| WxCpMessageRouter wxCpMessageRouter) { | |||
| WxCpMessageRouter wxCpMessageRouter) { | |||
| this.wxCpConfigStorage = wxCpConfigStorage; | |||
| this.wxCpService = wxCpService; | |||
| this.wxCpMessageRouter = wxCpMessageRouter; | |||
| @@ -32,7 +32,7 @@ public class WxCpEndpointServlet extends HttpServlet { | |||
| @Override | |||
| protected void service(HttpServletRequest request, HttpServletResponse response) | |||
| throws ServletException, IOException { | |||
| throws ServletException, IOException { | |||
| response.setContentType("text/html;charset=utf-8"); | |||
| response.setStatus(HttpServletResponse.SC_OK); | |||
| @@ -56,7 +56,7 @@ public class WxCpEndpointServlet extends HttpServlet { | |||
| } | |||
| WxCpXmlMessage inMessage = WxCpXmlMessage | |||
| .fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature); | |||
| .fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature); | |||
| WxCpXmlOutMessage outMessage = wxCpMessageRouter.route(inMessage); | |||
| if (outMessage != null) { | |||
| response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage)); | |||
| @@ -18,8 +18,9 @@ public class WxCpOAuth2Servlet extends HttpServlet { | |||
| this.wxCpService = wxCpService; | |||
| } | |||
| @Override protected void service(HttpServletRequest request, HttpServletResponse response) | |||
| throws ServletException, IOException { | |||
| @Override | |||
| protected void service(HttpServletRequest request, HttpServletResponse response) | |||
| throws ServletException, IOException { | |||
| response.setContentType("text/html;charset=utf-8"); | |||
| response.setStatus(HttpServletResponse.SC_OK); | |||