From daebd85cf64d8c91f8913e4329109ba614705591 Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Wed, 8 Nov 2017 16:14:59 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=96=B9=E5=B9=B3=E5=8F=B0=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 768 +++++++++--------- weixin-java-open/README.md | 86 ++ weixin-java-open/pom.xml | 97 +++ .../open/api/WxOpenComponentService.java | 79 ++ .../weixin/open/api/WxOpenConfigStorage.java | 106 +++ .../weixin/open/api/WxOpenService.java | 22 + .../api/impl/WxOpenComponentServiceImpl.java | 189 +++++ .../api/impl/WxOpenInMemoryConfigStorage.java | 386 +++++++++ .../api/impl/WxOpenInRedisConfigStorage.java | 164 ++++ .../open/api/impl/WxOpenMpServiceImpl.java | 49 ++ .../api/impl/WxOpenServiceAbstractImpl.java | 63 ++ .../WxOpenServiceApacheHttpClientImpl.java | 44 + .../open/api/impl/WxOpenServiceImpl.java | 8 + .../bean/WxOpenAuthorizerAccessToken.java | 35 + .../open/bean/WxOpenComponentAccessToken.java | 35 + .../bean/auth/WxOpenAuthorizationInfo.java | 18 + .../open/bean/auth/WxOpenAuthorizerInfo.java | 22 + .../open/bean/message/WxOpenXmlMessage.java | 100 +++ .../result/WxOpenAuthorizerInfoResult.java | 16 + .../result/WxOpenAuthorizerOptionResult.java | 15 + .../bean/result/WxOpenQueryAuthResult.java | 14 + .../weixin/open/util/WxOpenCryptUtil.java | 28 + .../WxOpenAuthorizationInfoGsonAdapter.java | 45 + ...xOpenAuthorizerAccessTokenGsonAdapter.java | 21 + .../json/WxOpenAuthorizerInfoGsonAdapter.java | 38 + ...WxOpenAuthorizerInfoResultGsonAdapter.java | 32 + ...OpenAuthorizerOptionResultGsonAdapter.java | 22 + ...WxOpenComponentAccessTokenGsonAdapter.java | 21 + .../open/util/json/WxOpenGsonBuilder.java | 36 + .../WxOpenQueryAuthResultGsonAdapter.java | 26 + .../open/util/xml/XStreamTransformer.java | 90 ++ 31 files changed, 2294 insertions(+), 381 deletions(-) create mode 100644 weixin-java-open/README.md create mode 100644 weixin-java-open/pom.xml create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenService.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceAbstractImpl.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenAuthorizerAccessToken.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenComponentAccessToken.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizationInfo.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizerInfo.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerInfoResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerOptionResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenQueryAuthResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/WxOpenCryptUtil.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizationInfoGsonAdapter.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerAccessTokenGsonAdapter.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoGsonAdapter.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoResultGsonAdapter.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerOptionResultGsonAdapter.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenComponentAccessTokenGsonAdapter.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenQueryAuthResultGsonAdapter.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/xml/XStreamTransformer.java diff --git a/pom.xml b/pom.xml index 7eb78c33ca..38d24fd76c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,381 +1,387 @@ - - - 4.0.0 - com.github.binarywang - weixin-java-parent - 2.8.6.BETA - pom - WeiXin Java Tools - Parent - 微信公众号、企业号上级POM - https://github.com/wechat-group/weixin-java-tools - - - - The Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - - Daniel Qian - chanjarster@gmail.com - https://github.com/chanjarster - - - Binary Wang - binarywang@gmail.com - https://github.com/binarywang - - - gaigeshen - gaigeshen@qq.com - https://github.com/gaigeshen - - - Liu Mingbo - liumingbo2008@gmail.com - https://github.com/FirenzesEagle - - - kakotor - kakotor@gmail.com - https://github.com/kakotor - - - xiong - zhaoxiong.tan@gmail.com - https://github.com/ZhaoxiongTan - - - LiuJunGuang - aimilin@yeah.net - https://github.com/aimilin6688 - - - Eric.Tsai - xiaodong.cai.ks@gmail.com - https://github.com/iwareserictsai - - - withinthefog - withinthefog@gmail.com - https://github.com/withinthefog - - - Keung - dongfuqiang1988@163.com - https://github.com/johnnytung - - - Jonk - aimilin@yeah.net - https://github.com/aimilin6688 - - - ecoolper - crskyp@gmail.com - https://github.com/crskyp - - - - - scm:git:https://github.com/wechat-group/weixin-java-tools.git - scm:git:git@github.com:wechat-group/weixin-java-tools.git - https://github.com/wechat-group/weixin-java-tools - - - - weixin-java-common - weixin-java-cp - weixin-java-mp - weixin-java-pay - weixin-java-miniapp - - - - - 1.7 - 1.7 - - UTF-8 - true - true - 4.5 - 9.3.0.RC0 - - - - - - com.github.binarywang - qrcode-utils - 1.1 - - - - org.jodd - jodd-http - 3.7.1 - provided - - - com.squareup.okhttp3 - okhttp - 3.7.0 - provided - - - - org.apache.httpcomponents - httpclient - ${httpclient.version} - - - org.apache.httpcomponents - httpmime - ${httpclient.version} - - - commons-codec - commons-codec - 1.10 - - - commons-io - commons-io - 2.5 - - - org.apache.commons - commons-lang3 - 3.5 - - - org.slf4j - slf4j-api - 1.7.24 - - - com.thoughtworks.xstream - xstream - 1.4.9 - - - - com.google.guava - guava - 20.0 - - - com.google.code.gson - gson - 2.8.0 - - - - - joda-time - joda-time - 2.9.7 - test - - - ch.qos.logback - logback-classic - 1.1.11 - test - - - com.google.inject - guice - 3.0 - test - - - org.testng - testng - 6.10 - test - - - org.mockito - mockito-all - 1.9.5 - test - - - org.eclipse.jetty - jetty-server - ${jetty.version} - test - - - org.eclipse.jetty - jetty-servlet - ${jetty.version} - test - - - redis.clients - jedis - 2.9.0 - provided - - - org.projectlombok - lombok - 1.16.18 - compile - - - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - - doclint-java8-disable - - [1.8,) - - - -Xdoclint:none - - - - - release - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - - ${javadoc.opts} - UTF-8 - zh_CN - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.17 - - true - - - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.3 - true - - ossrh - https://oss.sonatype.org/ - true - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.1 - - true - false - release - deploy - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.6.0 - - UTF-8 - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 2.17 - - quality-checks/google_checks.xml - true - true - true - - - - verify - - check - - - - - - - - + + + 4.0.0 + com.github.binarywang + weixin-java-parent + 2.8.6.BETA + pom + WeiXin Java Tools - Parent + 微信公众号、企业号上级POM + https://github.com/wechat-group/weixin-java-tools + + + + The Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + Daniel Qian + chanjarster@gmail.com + https://github.com/chanjarster + + + Binary Wang + binarywang@gmail.com + https://github.com/binarywang + + + gaigeshen + gaigeshen@qq.com + https://github.com/gaigeshen + + + Liu Mingbo + liumingbo2008@gmail.com + https://github.com/FirenzesEagle + + + kakotor + kakotor@gmail.com + https://github.com/kakotor + + + xiong + zhaoxiong.tan@gmail.com + https://github.com/ZhaoxiongTan + + + LiuJunGuang + aimilin@yeah.net + https://github.com/aimilin6688 + + + Eric.Tsai + xiaodong.cai.ks@gmail.com + https://github.com/iwareserictsai + + + withinthefog + withinthefog@gmail.com + https://github.com/withinthefog + + + Keung + dongfuqiang1988@163.com + https://github.com/johnnytung + + + Jonk + aimilin@yeah.net + https://github.com/aimilin6688 + + + ecoolper + crskyp@gmail.com + https://github.com/crskyp + + + 007 + 007gzs@gmail.com + https://github.com/007gzs + + + + + scm:git:https://github.com/wechat-group/weixin-java-tools.git + scm:git:git@github.com:wechat-group/weixin-java-tools.git + https://github.com/wechat-group/weixin-java-tools + + + + weixin-java-common + weixin-java-cp + weixin-java-mp + weixin-java-pay + weixin-java-miniapp + weixin-java-open + + + + + 1.7 + 1.7 + + UTF-8 + true + true + 4.5 + 9.3.0.RC0 + + + + + + com.github.binarywang + qrcode-utils + 1.1 + + + + org.jodd + jodd-http + 3.7.1 + provided + + + com.squareup.okhttp3 + okhttp + 3.7.0 + provided + + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + org.apache.httpcomponents + httpmime + ${httpclient.version} + + + commons-codec + commons-codec + 1.10 + + + commons-io + commons-io + 2.5 + + + org.apache.commons + commons-lang3 + 3.5 + + + org.slf4j + slf4j-api + 1.7.24 + + + com.thoughtworks.xstream + xstream + 1.4.9 + + + + com.google.guava + guava + 20.0 + + + com.google.code.gson + gson + 2.8.0 + + + + + joda-time + joda-time + 2.9.7 + test + + + ch.qos.logback + logback-classic + 1.1.11 + test + + + com.google.inject + guice + 3.0 + test + + + org.testng + testng + 6.10 + test + + + org.mockito + mockito-all + 1.9.5 + test + + + org.eclipse.jetty + jetty-server + ${jetty.version} + test + + + org.eclipse.jetty + jetty-servlet + ${jetty.version} + test + + + redis.clients + jedis + 2.9.0 + provided + + + org.projectlombok + lombok + 1.16.18 + compile + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + doclint-java8-disable + + [1.8,) + + + -Xdoclint:none + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + ${javadoc.opts} + UTF-8 + zh_CN + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.17 + + true + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + true + + ossrh + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.1 + + true + false + release + deploy + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.0 + + UTF-8 + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.17 + + quality-checks/google_checks.xml + true + true + true + + + + verify + + check + + + + + + + + diff --git a/weixin-java-open/README.md b/weixin-java-open/README.md new file mode 100644 index 0000000000..eef5c00eb4 --- /dev/null +++ b/weixin-java-open/README.md @@ -0,0 +1,86 @@ +消息机制未实现,下面为通知回调中设置的代码部分 +``` +@RestController +@RequestMapping("notify") +public class NotifyController extends WechatThridBaseController { + @Autowired + protected WxOpenServiceDemo wxOpenService; + @RequestMapping("receive_ticket") + public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, @RequestParam("signature") String signature, + @RequestParam(name = "encrypt_type", required = false) String encType, + @RequestParam(name = "msg_signature", required = false) String msgSignature) { + this.logger.info( + "\n接收微信请求:[signature=[{}], encType=[{}], msgSignature=[{}]," + + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", + signature, encType, msgSignature, timestamp, nonce, requestBody); + + if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { + throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); + } + + String out = ""; + // aes加密的消息 + WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); + this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); + if (StringUtils.equalsIgnoreCase(inMessage.getInfoType(), "component_verify_ticket")) { + wxOpenService.getWxOpenComponentService().getWxOpenConfigStorage().setComponentVerifyTicket(inMessage.getComponentVerifyTicket()); + out = "success"; + } + //新增、跟新授权 + if (StringUtils.equalsAnyIgnoreCase(inMessage.getInfoType(), "authorized", "updateauthorized")) { + try { + WxOpenQueryAuthResult queryAuth = wxOpenService.getWxOpenComponentService().getQueryAuth(inMessage.getAuthorizationCode()); + WxOpenAuthorizationInfo authorizationInfo = queryAuth.getAuthorizationInfo(); + wxOpenService.getWxOpenConfigStorage().updateAuthorizerAccessToken(authorizationInfo.getAuthorizerAppid(), + authorizationInfo.getAuthorizerAccessToken(), authorizationInfo.getExpiresIn()); + wxOpenService.getWxOpenConfigStorage().setAuthorizerRefreshToken(authorizationInfo.getAuthorizerAppid(), authorizationInfo.getAuthorizerRefreshToken()); + out = "success"; + } catch (WxErrorException e) { + throw new ResponseException(ErrorCodeEnum.ERROR, e); + } + } + //取消授权 + if (StringUtils.equalsIgnoreCase(inMessage.getInfoType(), "unauthorized")) { + + } + +// WxMpXmlOutMessage outMessage = this.getWxService().route(inMessage); +// if (outMessage == null) { +// return ""; +// } +// +// out = outMessage.toEncryptedXml(wxOpenService.getWxOpenConfigStorage()); + + + this.logger.debug("\n组装回复信息:{}", out); + + return out; + } + @RequestMapping("{appId}/callback") + public Object callback(@RequestBody(required = false)String requestBody, + @PathVariable ("appId") String appId, + @RequestParam("signature") String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, + @RequestParam("openid") String openid, + @RequestParam("encrypt_type") String encType, + @RequestParam("msg_signature") String msgSignature) { + this.logger.info( + "\n接收微信请求:[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}]," + + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", + appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody); + logger.info("query:"+getHttpServletRequest().getQueryString()+"\nbody:"+requestBody); + if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { + throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); + } + + String out = ""; + // aes加密的消息 + WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); + this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); + //wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId); + return out; + } +} +``` diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml new file mode 100644 index 0000000000..d451dce1cd --- /dev/null +++ b/weixin-java-open/pom.xml @@ -0,0 +1,97 @@ + + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.6.BETA + + weixin-java-open + WeiXin Java Tools - Open + 微信开放平台Java SDK + + + 007 + 007gzs@gmail.com + https://github.com/007gzs + + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + com.github.binarywang + weixin-java-mp + ${project.version} + + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + + org.testng + testng + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + joda-time + joda-time + test + + + redis.clients + jedis + + + ch.qos.logback + logback-classic + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + + diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java new file mode 100644 index 0000000000..182d5ef3f4 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -0,0 +1,79 @@ +package me.chanjar.weixin.open.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; + +/** + * @author 007 + */ +public interface WxOpenComponentService { + + String API_COMPONENT_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; + String API_CREATE_PREAUTHCODE_URL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode"; + String API_QUERY_AUTH_URL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth"; + String API_AUTHORIZER_TOKEN_URL = "https://api.weixin.qq.com /cgi-bin/component/api_authorizer_token"; + String API_GET_AUTHORIZER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info"; + String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option"; + String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/ api_set_authorizer_option"; + + + String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; + String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; + + /** + * 用code换取oauth2的access token + */ + String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s"; + /** + * 刷新oauth2的access token + */ + String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid==%s"; + WxMpService getWxMpServiceByAppid(String appid); + + WxOpenConfigStorage getWxOpenConfigStorage(); + + boolean checkSignature(String timestamp, String nonce, String signature); + + String getComponentAccessToken(boolean forceRefresh) throws WxErrorException; + + /** + * 获取用户授权页URL(来路URL和成功跳转URL 的域名都需要为三方平台设置的 登录授权的发起页域名) + */ + String getPreAuthUrl(String redirectURI) throws WxErrorException; + + /** + * 使用授权码换取公众号或小程序的接口调用凭据和授权信息 + */ + WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException; + + /** + * 获取授权方的帐号基本信息 + */ + WxOpenAuthorizerInfoResult getAuthorizerInfo(String authorizerAppid) throws WxErrorException; + + /** + * 获取授权方的选项设置信息 + */ + WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException; + + /** + * 设置授权方的选项信息 + */ + WxError setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException; + + String getAuthorizerAccessToken(String appid, boolean forceRefresh) throws WxErrorException; + + WxMpOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException; + + boolean checkSignature(String appId, String timestamp, String nonce, String signature); + + WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; + + String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state); + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java new file mode 100644 index 0000000000..8f6173b798 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java @@ -0,0 +1,106 @@ +package me.chanjar.weixin.open.api; + +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; + +/** + * @author 007 + */ +public interface WxOpenConfigStorage { + + void setComponentAppId(String componentAppId); + + void setComponentAppSecret(String componentAppSecret); + + void setComponentToken(String componentToken); + + void setComponentAesKey(String componentAesKey); + + String getComponentAppId(); + String getComponentAppSecret(); + String getComponentToken(); + String getComponentAesKey(); + String getComponentVerifyTicket(); + void setComponentVerifyTicket(String componentVerifyTicket); + String getComponentAccessToken(); + boolean isComponentAccessTokenExpired(); + void updateComponentAccessTokent(WxOpenComponentAccessToken componentAccessToken); + WxMpConfigStorage getWxMpConfigStorage(String appId); + /** + * 应该是线程安全的 + * + * @param componentAccessToken 新的accessToken值 + * @param expiresInSeconds 过期时间,以秒为单位 + */ + void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds); + + /** + * 是否自动刷新token + */ + boolean autoRefreshToken(); + + + String getAuthorizerRefreshToken(String appId); + void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken); + String getAuthorizerAccessToken(String appId); + + + boolean isAuthorizerAccessTokenExpired(String appId); + + /** + * 强制将access token过期掉 + */ + void expireAuthorizerAccessToken(String appId); + + /** + * 应该是线程安全的 + * + * @param authorizerAccessToken 要更新的WxAccessToken对象 + */ + void updateAuthorizerAccessToken(String appId, WxOpenAuthorizerAccessToken authorizerAccessToken); + + /** + * 应该是线程安全的 + * + * @param authorizerAccessToken 新的accessToken值 + * @param expiresInSeconds 过期时间,以秒为单位 + */ + void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds); + + String getJsapiTicket(String appId); + + boolean isJsapiTicketExpired(String appId); + + /** + * 强制将jsapi ticket过期掉 + */ + void expireJsapiTicket(String appId); + + /** + * 应该是线程安全的 + * + * @param jsapiTicket 新的jsapi ticket值 + * @param expiresInSeconds 过期时间,以秒为单位 + */ + void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds); + + String getCardApiTicket(String appId); + + + boolean isCardApiTicketExpired(String appId); + + /** + * 强制将卡券api ticket过期掉 + */ + void expireCardApiTicket(String appId); + + /** + * 应该是线程安全的 + * + * @param cardApiTicket 新的cardApi ticket值 + * @param expiresInSeconds 过期时间,以秒为单位 + */ + void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds); + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenService.java new file mode 100644 index 0000000000..c0214d46ef --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenService.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.open.api; + +import me.chanjar.weixin.common.exception.WxErrorException; + +/** + * @author 007 + */ +public interface WxOpenService { + WxOpenComponentService getWxOpenComponentService(); + WxOpenConfigStorage getWxOpenConfigStorage(); + void setWxOpenConfigStorage(WxOpenConfigStorage wxOpenConfigStorage); + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 + */ + String get(String url, String queryParam) throws WxErrorException; + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 + */ + String post(String url, String postData) throws WxErrorException; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java new file mode 100644 index 0000000000..fbfef52e91 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java @@ -0,0 +1,189 @@ +package me.chanjar.weixin.open.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.crypto.SHA1; +import me.chanjar.weixin.common.util.http.URIUtil; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.api.WxOpenService; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Hashtable; +import java.util.Map; + +/** + * @author 007 + */ +public class WxOpenComponentServiceImpl implements WxOpenComponentService { + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + private WxOpenService wxOpenService; + private static final Map wxOpenMpServiceMap = new Hashtable<>(); + + public WxOpenComponentServiceImpl(WxOpenService wxOpenService) { + this.wxOpenService = wxOpenService; + } + + @Override + public WxMpService getWxMpServiceByAppid(String appId) { + WxMpService wxMpService = wxOpenMpServiceMap.get(appId); + if (wxMpService == null) { + synchronized (wxOpenMpServiceMap) { + wxMpService = wxOpenMpServiceMap.get(appId); + if (wxMpService == null) { + wxMpService = new WxOpenMpServiceImpl(this, appId, getWxOpenConfigStorage().getWxMpConfigStorage(appId)); + + wxOpenMpServiceMap.put(appId, wxMpService); + } + } + } + return wxMpService; + } + + public WxOpenService getWxOpenService() { + return wxOpenService; + } + + @Override + public WxOpenConfigStorage getWxOpenConfigStorage() { + return wxOpenService.getWxOpenConfigStorage(); + } + @Override + public boolean checkSignature(String timestamp, String nonce, String signature) { + try { + return SHA1.gen(getWxOpenConfigStorage().getComponentToken(), timestamp, nonce) + .equals(signature); + } catch (Exception e) { + this.log.error("Checking signature failed, and the reason is :" + e.getMessage()); + return false; + } + } + @Override + public String getComponentAccessToken(boolean forceRefresh) throws WxErrorException { + + if (this.getWxOpenConfigStorage().isComponentAccessTokenExpired() || forceRefresh) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("component_appsecret", getWxOpenConfigStorage().getComponentAppSecret()); + jsonObject.addProperty("component_verify_ticket", getWxOpenConfigStorage().getComponentVerifyTicket()); + + String responseContent = this.getWxOpenService().post(API_COMPONENT_TOKEN_URL, jsonObject.toString()); + WxOpenComponentAccessToken componentAccessToken = WxOpenComponentAccessToken.fromJson(responseContent); + getWxOpenConfigStorage().updateComponentAccessTokent(componentAccessToken); + } + return this.getWxOpenConfigStorage().getComponentAccessToken(); + } + + private String post(String uri, String postData) throws WxErrorException { + String componentAccessToken = getComponentAccessToken(false); + String uriWithComponentAccessToken = uri + (uri.contains("?") ? "&" : "?") + "component_access_token=" + componentAccessToken; + return getWxOpenService().post(uriWithComponentAccessToken, postData); + } + + private String get(String uri) throws WxErrorException { + String componentAccessToken = getComponentAccessToken(false); + String uriWithComponentAccessToken = uri + (uri.contains("?") ? "&" : "?") + "component_access_token=" + componentAccessToken; + return getWxOpenService().get(uriWithComponentAccessToken, null); + } + + @Override + public String getPreAuthUrl(String redirectURI) throws WxErrorException { + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + String responseContent = post(API_CREATE_PREAUTHCODE_URL, jsonObject.toString()); + jsonObject = WxGsonBuilder.create().fromJson(responseContent, JsonObject.class); + return String.format(COMPONENT_LOGIN_PAGE_URL, getWxOpenConfigStorage().getComponentAppId(), jsonObject.get("pre_auth_code").getAsString(), URIUtil.encodeURIComponent(redirectURI)); + } + + @Override + public WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorization_code", authorizationCode); + String responseContent = post(API_QUERY_AUTH_URL, jsonObject.toString()); + return WxOpenGsonBuilder.create().fromJson(responseContent, WxOpenQueryAuthResult.class); + } + @Override + public WxOpenAuthorizerInfoResult getAuthorizerInfo(String authorizerAppid) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorizer_appid", authorizerAppid); + String responseContent = post(API_GET_AUTHORIZER_INFO_URL, jsonObject.toString()); + return WxOpenGsonBuilder.create().fromJson(responseContent, WxOpenAuthorizerInfoResult.class); + } + + @Override + public WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorizer_appid", authorizerAppid); + jsonObject.addProperty("option_name", optionName); + String responseContent = post(API_GET_AUTHORIZER_OPTION_URL, jsonObject.toString()); + return WxOpenGsonBuilder.create().fromJson(responseContent, WxOpenAuthorizerOptionResult.class); + } + @Override + public WxError setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorizer_appid", authorizerAppid); + jsonObject.addProperty("option_name", optionName); + jsonObject.addProperty("option_value", optionValue); + String responseContent = post(API_SET_AUTHORIZER_OPTION_URL, jsonObject.toString()); + return WxGsonBuilder.create().fromJson(responseContent, WxError.class); + } + + @Override + public String getAuthorizerAccessToken(String appId, boolean forceRefresh) throws WxErrorException { + + if (this.getWxOpenConfigStorage().isAuthorizerAccessTokenExpired(appId) || forceRefresh) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorizer_appid", appId); + jsonObject.addProperty("authorizer_refresh_token", getWxOpenConfigStorage().getAuthorizerRefreshToken(appId)); + String responseContent = post(API_AUTHORIZER_TOKEN_URL, jsonObject.toString()); + + WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken = WxOpenAuthorizerAccessToken.fromJson(responseContent); + getWxOpenConfigStorage().updateAuthorizerAccessToken(appId, wxOpenAuthorizerAccessToken); + } + return this.getWxOpenConfigStorage().getAuthorizerAccessToken(appId); + } + + @Override + public WxMpOAuth2AccessToken oauth2getAccessToken(String appId, String code) throws WxErrorException { + String url = String.format(OAUTH2_ACCESS_TOKEN_URL, appId, code, getWxOpenConfigStorage().getComponentAppId()); + String responseContent = get(url); + return WxMpOAuth2AccessToken.fromJson(responseContent); + } + + @Override + public boolean checkSignature(String appid, String timestamp, String nonce, String signature) { + return false; + } + + @Override + public WxMpOAuth2AccessToken oauth2refreshAccessToken(String appId, String refreshToken) throws WxErrorException { + String url = String.format(OAUTH2_REFRESH_TOKEN_URL, appId, refreshToken, getWxOpenConfigStorage().getComponentAppId()); + String responseContent = get(url); + return WxMpOAuth2AccessToken.fromJson(responseContent); + } + + @Override + public String oauth2buildAuthorizationUrl(String appId, String redirectURI, String scope, String state) { + return String.format(CONNECT_OAUTH2_AUTHORIZE_URL, + appId, URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state), getWxOpenConfigStorage().getComponentAppId()); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java new file mode 100644 index 0000000000..dc10ee18a5 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java @@ -0,0 +1,386 @@ +package me.chanjar.weixin.open.api.impl; + + +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; + +import java.io.File; +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 + * + * @author 007 + */ +public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { + private String componentAppId; + private String componentAppSecret; + private String componentToken; + private String componentAesKey; + private String componentVerifyTicket; + private String componentAccessToken; + private long componentExpiresTime; + + private Map authorizerRefreshTokens = new Hashtable<>(); + private Map authorizerAccessTokens = new Hashtable<>(); + private Map jsapiTickets = new Hashtable<>(); + private Map cardApiTickets = new Hashtable<>(); + + @Override + public void setComponentAppId(String componentAppId) { + this.componentAppId = componentAppId; + } + @Override + public void setComponentAppSecret(String componentAppSecret) { + this.componentAppSecret = componentAppSecret; + } + @Override + public void setComponentToken(String componentToken) { + this.componentToken = componentToken; + } + @Override + public void setComponentAesKey(String componentAesKey) { + this.componentAesKey = componentAesKey; + } + + @Override + public String getComponentAppId() { + return componentAppId; + } + + @Override + public String getComponentAppSecret() { + return componentAppSecret; + } + + @Override + public String getComponentToken() { + return componentToken; + } + + @Override + public String getComponentAesKey() { + return componentAesKey; + } + + @Override + public String getComponentVerifyTicket() { + return componentVerifyTicket; + } + + @Override + public void setComponentVerifyTicket(String componentVerifyTicket) { + this.componentVerifyTicket = componentVerifyTicket; + } + + @Override + public String getComponentAccessToken() { + return componentAccessToken; + } + + @Override + public boolean isComponentAccessTokenExpired() { + return System.currentTimeMillis() > componentExpiresTime; + } + + @Override + public void updateComponentAccessTokent(WxOpenComponentAccessToken componentAccessToken) { + updateComponentAccessTokent(componentAccessToken.getComponentAccessToken(), componentAccessToken.getExpiresIn()); + } + + @Override + public WxMpConfigStorage getWxMpConfigStorage(String appId) { + return new WxOpenMpConfigStorage(this, appId); + } + + @Override + public void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds) { + this.componentAccessToken = componentAccessToken; + this.componentExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; + } + + @Override + public boolean autoRefreshToken() { + return true; + } + private String getTokenString(Map map, String key){ + Token token = map.get(key); + if(token == null || (token.expiresTime != null && System.currentTimeMillis() > token.expiresTime)){ + return null; + } + return token.token; + } + private void expireToken(Map map, String key){ + Token token = map.get(key); + if(token != null){ + token.expiresTime = 0L; + } + } + private void updateToken(Map map, String key, String tokenString, Integer expiresInSeconds){ + Token token = map.get(key); + if(token == null){ + token = new Token(); + map.put(key, token); + } + token.token = tokenString; + if(expiresInSeconds != null) { + token.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; + } + } + @Override + public String getAuthorizerRefreshToken(String appId) { + return getTokenString(authorizerRefreshTokens, appId); + } + + @Override + public void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken) { + updateToken(authorizerRefreshTokens, appId, authorizerRefreshToken, null); + } + + @Override + public String getAuthorizerAccessToken(String appId) { + return getTokenString(authorizerAccessTokens, appId); + } + + + @Override + public boolean isAuthorizerAccessTokenExpired(String appId) { + return getTokenString(authorizerAccessTokens, appId) == null; + } + + @Override + public void expireAuthorizerAccessToken(String appId) { + expireToken(authorizerAccessTokens, appId); + } + + @Override + public void updateAuthorizerAccessToken(String appId, WxOpenAuthorizerAccessToken authorizerAccessToken) { + updateAuthorizerAccessToken(appId, authorizerAccessToken.getAuthorizerAccessToken(), authorizerAccessToken.getExpiresIn()); + } + + @Override + public void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds) { + updateToken(authorizerAccessTokens, appId, authorizerAccessToken, expiresInSeconds); + } + + @Override + public String getJsapiTicket(String appId) { + return getTokenString(jsapiTickets, appId); + } + + @Override + public boolean isJsapiTicketExpired(String appId) { + return getTokenString(jsapiTickets, appId) == null; + } + + @Override + public void expireJsapiTicket(String appId) { + expireToken(jsapiTickets, appId); + } + + @Override + public void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds) { + updateToken(jsapiTickets, appId, jsapiTicket, expiresInSeconds); + } + + @Override + public String getCardApiTicket(String appId) { + return getTokenString(cardApiTickets, appId); + } + + @Override + public boolean isCardApiTicketExpired(String appId) { + return getTokenString(cardApiTickets, appId) == null; + } + + @Override + public void expireCardApiTicket(String appId) { + expireToken(cardApiTickets, appId); + } + + @Override + public void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds) { + updateToken(cardApiTickets, appId, cardApiTicket, expiresInSeconds); + } + + private static class Token{ + private String token; + private Long expiresTime; + } + private static class WxOpenMpConfigStorage implements WxMpConfigStorage{ + private WxOpenConfigStorage wxOpenConfigStorage; + private String appId; + private WxOpenMpConfigStorage(WxOpenConfigStorage wxOpenConfigStorage, String appId){ + this.wxOpenConfigStorage = wxOpenConfigStorage; + this.appId = appId; + } + + private Lock accessTokenLock = new ReentrantLock(); + private Lock jsapiTicketLock = new ReentrantLock(); + private Lock cardApiTicketLock = new ReentrantLock(); + + + @Override + public String getAccessToken() { + return wxOpenConfigStorage.getAuthorizerAccessToken(appId); + } + + @Override + public Lock getAccessTokenLock() { + return this.accessTokenLock; + } + + @Override + public boolean isAccessTokenExpired() { + return wxOpenConfigStorage.isAuthorizerAccessTokenExpired(appId); + } + + @Override + public synchronized void updateAccessToken(WxAccessToken accessToken) { + updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); + } + + @Override + public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { + wxOpenConfigStorage.updateAuthorizerAccessToken(appId, accessToken, expiresInSeconds); + } + + @Override + public void expireAccessToken() { + wxOpenConfigStorage.expireAuthorizerAccessToken(appId); + } + + @Override + public String getJsapiTicket() { + return wxOpenConfigStorage.getJsapiTicket(appId); + } + + @Override + public Lock getJsapiTicketLock() { + return this.jsapiTicketLock; + } + + @Override + public boolean isJsapiTicketExpired() { + return wxOpenConfigStorage.isJsapiTicketExpired(appId); + } + + @Override + public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { + wxOpenConfigStorage.updateJsapiTicket(appId, jsapiTicket, expiresInSeconds); + } + + @Override + public void expireJsapiTicket() { + wxOpenConfigStorage.expireJsapiTicket(appId); + } + + /** + * 卡券api_ticket + */ + @Override + public String getCardApiTicket() { + return wxOpenConfigStorage.getCardApiTicket(appId); + } + + @Override + public Lock getCardApiTicketLock() { + return this.cardApiTicketLock; + } + + @Override + public boolean isCardApiTicketExpired() { + return wxOpenConfigStorage.isCardApiTicketExpired(appId); + } + + @Override + public synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { + wxOpenConfigStorage.updateCardApiTicket(appId, cardApiTicket, expiresInSeconds); + } + + @Override + public void expireCardApiTicket() { + wxOpenConfigStorage.expireCardApiTicket(appId); + } + + @Override + public String getAppId() { + return this.appId; + } + + @Override + public String getSecret() { + return null; + } + + @Override + public String getToken() { + return null; + } + + @Override + public long getExpiresTime() { + return 0; + } + + + @Override + public String getAesKey() { + return null; + } + + @Override + public String getOauth2redirectUri() { + return null; + } + + @Override + public String getHttpProxyHost() { + return null; + } + + @Override + public int getHttpProxyPort() { + return 0; + } + + @Override + public String getHttpProxyUsername() { + return null; + } + + @Override + public String getHttpProxyPassword() { + return null; + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + @Override + public File getTmpDirFile() { + return null; + } + + @Override + public ApacheHttpClientBuilder getApacheHttpClientBuilder() { + return null; + } + + + @Override + public boolean autoRefreshToken() { + return true; + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java new file mode 100644 index 0000000000..faaa95d84c --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java @@ -0,0 +1,164 @@ +package me.chanjar.weixin.open.api.impl; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +/** + * @author 007 + */ +public class WxOpenInRedisConfigStorage extends WxOpenInMemoryConfigStorage { + + private final static String COMPONENT_VERIFY_TICKET_KEY = "wechat_component_verify_ticket:"; + private final static String COMPONENT_ACCESS_TOKEN_KEY = "wechat_component_access_token:"; + + private final static String AUTHORIZER_REFRESH_TOKEN_KEY = "wechat_authorizer_refresh_token:"; + private final static String AUTHORIZER_ACCESS_TOKEN_KEY = "wechat_authorizer_access_token:"; + private final static String JSAPI_TICKET_KEY = "wechat_jsapi_ticket:"; + private final static String CARD_API_TICKET_KEY = "wechat_card_api_ticket:"; + + + protected final JedisPool jedisPool; + private String componentVerifyTicketKey; + private String componentAccessTokenKey; + private String authorizerRefreshTokenKey; + private String authorizerAccessTokenKey; + private String jsapiTicketKey; + private String cardApiTicket; + public WxOpenInRedisConfigStorage(JedisPool jedisPool) { + this.jedisPool = jedisPool; + } + + @Override + public void setComponentAppId(String componentAppId) { + super.setComponentAppId(componentAppId); + componentVerifyTicketKey = COMPONENT_VERIFY_TICKET_KEY.concat(componentAppId); + componentAccessTokenKey = COMPONENT_ACCESS_TOKEN_KEY.concat(componentAppId); + authorizerRefreshTokenKey = AUTHORIZER_REFRESH_TOKEN_KEY.concat(componentAppId); + authorizerAccessTokenKey = AUTHORIZER_ACCESS_TOKEN_KEY.concat(componentAppId); + jsapiTicketKey = JSAPI_TICKET_KEY.concat(componentAppId); + cardApiTicket = CARD_API_TICKET_KEY.concat(componentAppId); + } + @Override + public String getComponentVerifyTicket(){ + try(Jedis jedis = jedisPool.getResource()){ + return jedis.get(componentVerifyTicketKey); + } + } + @Override + public void setComponentVerifyTicket(String componentVerifyTicket){ + try(Jedis jedis = jedisPool.getResource()){ + jedis.set(componentVerifyTicketKey, componentVerifyTicket); + } + } + @Override + public String getComponentAccessToken(){ + try(Jedis jedis = jedisPool.getResource()){ + return jedis.get(componentAccessTokenKey); + } + } + @Override + public boolean isComponentAccessTokenExpired(){ + try(Jedis jedis = jedisPool.getResource()){ + return jedis.ttl(componentAccessTokenKey) < 2; + } + } + @Override + public void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(componentAccessTokenKey, expiresInSeconds - 200, componentAccessToken); + } + } + private String getKey(String prefix, String appId){ + return prefix.endsWith(":") ? prefix.concat(appId) : prefix.concat(":").concat(appId); + } + + @Override + public String getAuthorizerRefreshToken(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(getKey(authorizerRefreshTokenKey, appId)); + } + } + @Override + public void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.set(getKey(authorizerRefreshTokenKey, appId), authorizerRefreshToken); + } + } + @Override + public String getAuthorizerAccessToken(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(getKey(authorizerAccessTokenKey, appId)); + } + } + + + @Override + public boolean isAuthorizerAccessTokenExpired(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(getKey(authorizerAccessTokenKey, appId)) < 2; + } + } + @Override + public void expireAuthorizerAccessToken(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(getKey(authorizerAccessTokenKey, appId), 0); + } + } + @Override + public void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(getKey(authorizerAccessTokenKey, appId), expiresInSeconds - 200, authorizerAccessToken); + } + } + + @Override + public String getJsapiTicket(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(getKey(jsapiTicketKey, appId)); + } + } + + @Override + public boolean isJsapiTicketExpired(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(getKey(jsapiTicketKey, appId)) < 2; + } + } + @Override + public void expireJsapiTicket(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(getKey(jsapiTicketKey, appId), 0); + } + } + @Override + public void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(getKey(jsapiTicketKey, appId), expiresInSeconds - 200, jsapiTicket); + } + } + + @Override + public String getCardApiTicket(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(getKey(jsapiTicketKey, appId)); + } + } + @Override + public boolean isCardApiTicketExpired(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(getKey(cardApiTicket, appId)) < 2; + } + } + @Override + public void expireCardApiTicket(String appId){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(getKey(cardApiTicket, appId), 0); + } + } + @Override + public void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(getKey(cardApiTicket, appId), expiresInSeconds - 200, cardApiTicket); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java new file mode 100644 index 0000000000..b4baf58581 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java @@ -0,0 +1,49 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.api.WxOpenComponentService; + +/** + * @author 007 + */ +public class WxOpenMpServiceImpl extends WxMpServiceImpl { + private WxOpenComponentService wxOpenComponentService; + private WxMpConfigStorage wxMpConfigStorage; + private String appId; + public WxOpenMpServiceImpl(WxOpenComponentService wxOpenComponentService, String appId, WxMpConfigStorage wxMpConfigStorage){ + this.wxOpenComponentService = wxOpenComponentService; + this.appId = appId; + this.wxMpConfigStorage = wxMpConfigStorage; + } + @Override + public WxMpConfigStorage getWxMpConfigStorage(){ + return wxMpConfigStorage; + } + @Override + public String getAccessToken(boolean forceRefresh) throws WxErrorException { + return wxOpenComponentService.getAuthorizerAccessToken(appId, forceRefresh); + } + + @Override + public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException { + return wxOpenComponentService.oauth2getAccessToken(appId, code); + } + +// @Override +// public boolean checkSignature(String timestamp, String nonce, String signature) { +// return wxOpenComponentService.checkSignature(appId, timestamp, nonce, signature); +// } + + @Override + public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException { + return wxOpenComponentService.oauth2refreshAccessToken(appId, refreshToken); + } + + @Override + public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) { + return wxOpenComponentService.oauth2buildAuthorizationUrl(appId, redirectURI, scope, state); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceAbstractImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceAbstractImpl.java new file mode 100644 index 0000000000..5f937dc5cf --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceAbstractImpl.java @@ -0,0 +1,63 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.api.WxOpenService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * @author 007 + */ +public abstract class WxOpenServiceAbstractImpl implements WxOpenService, RequestHttp { + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + private WxOpenConfigStorage wxOpenConfigStorage; + protected WxOpenComponentService wxOpenComponentService = new WxOpenComponentServiceImpl(this); + @Override + public WxOpenComponentService getWxOpenComponentService() { + return wxOpenComponentService; + } + @Override + public WxOpenConfigStorage getWxOpenConfigStorage(){ + return wxOpenConfigStorage; + } + public void setWxOpenConfigStorage(WxOpenConfigStorage wxOpenConfigStorage){ + this.wxOpenConfigStorage = wxOpenConfigStorage; + } + + protected synchronized T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { + try { + T result = executor.execute(uri, data); + this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uri, data, result); + return result; + } catch (WxErrorException e) { + WxError error = e.getError(); +// /* +// * 发生以下情况时尝试刷新access_token +// * 40001 获取access_token时AppSecret错误,或者access_token无效 +// * 42001 access_token超时 +// * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 +// */ +// if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { +// // 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token +// this.configStorage.expireAccessToken(); +// return execute(executor, uri, data); +// } + + if (error.getErrorCode() != 0) { + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uri, data, error); + throw new WxErrorException(error, e); + } + return null; + } catch (IOException e) { + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uri, data, e.getMessage()); + throw new RuntimeException(e); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java new file mode 100644 index 0000000000..e5b62b3456 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java @@ -0,0 +1,44 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.HttpType; +import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; +import org.apache.http.HttpHost; +import org.apache.http.impl.client.CloseableHttpClient; + +/** + * apache-http方式实现 + * @author 007 + */ +public class WxOpenServiceApacheHttpClientImpl extends WxOpenServiceAbstractImpl { + private CloseableHttpClient httpClient = DefaultApacheHttpClientBuilder.get().build(); + private HttpHost httpProxy = null; + + @Override + public CloseableHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public HttpHost getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpType getRequestType() { + return HttpType.APACHE_HTTP; + } + + @Override + public String get(String url, String queryParam) throws WxErrorException { + return execute(SimpleGetRequestExecutor.create(this), url, queryParam); + } + + @Override + public String post(String url, String postData) throws WxErrorException { + return execute(SimplePostRequestExecutor.create(this), url, postData); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java new file mode 100644 index 0000000000..c807ccdf99 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java @@ -0,0 +1,8 @@ +package me.chanjar.weixin.open.api.impl; + +/** + * @author 007 + */ +public class WxOpenServiceImpl extends WxOpenServiceApacheHttpClientImpl { + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenAuthorizerAccessToken.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenAuthorizerAccessToken.java new file mode 100644 index 0000000000..429aad1779 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenAuthorizerAccessToken.java @@ -0,0 +1,35 @@ +package me.chanjar.weixin.open.bean; + +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; + +import java.io.Serializable; + +/** + * @author 007 + */ +public class WxOpenAuthorizerAccessToken implements Serializable{ + + private String authorizerAccessToken; + + private int expiresIn = -1; + + public static WxOpenAuthorizerAccessToken fromJson(String json) { + return WxOpenGsonBuilder.create().fromJson(json, WxOpenAuthorizerAccessToken.class); + } + + public String getAuthorizerAccessToken() { + return authorizerAccessToken; + } + + public void setAuthorizerAccessToken(String authorizerAccessToken) { + this.authorizerAccessToken = authorizerAccessToken; + } + + public int getExpiresIn() { + return expiresIn; + } + + public void setExpiresIn(int expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenComponentAccessToken.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenComponentAccessToken.java new file mode 100644 index 0000000000..31f79b752f --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenComponentAccessToken.java @@ -0,0 +1,35 @@ +package me.chanjar.weixin.open.bean; + +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; + +import java.io.Serializable; + +/** + * @author 007 + */ +public class WxOpenComponentAccessToken implements Serializable{ + + private String componentAccessToken; + + private int expiresIn = -1; + + public static WxOpenComponentAccessToken fromJson(String json) { + return WxOpenGsonBuilder.create().fromJson(json, WxOpenComponentAccessToken.class); + } + + public String getComponentAccessToken() { + return componentAccessToken; + } + + public void setComponentAccessToken(String componentAccessToken) { + this.componentAccessToken = componentAccessToken; + } + + public int getExpiresIn() { + return expiresIn; + } + + public void setExpiresIn(int expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizationInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizationInfo.java new file mode 100644 index 0000000000..687e31ed6a --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizationInfo.java @@ -0,0 +1,18 @@ +package me.chanjar.weixin.open.bean.auth; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author 007 + */ +@Data +public class WxOpenAuthorizationInfo implements Serializable{ + private String authorizerAppid; + private String authorizerAccessToken; + private int expiresIn; + private String authorizerRefreshToken; + private List funcInfo; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizerInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizerInfo.java new file mode 100644 index 0000000000..b9f63a3e37 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizerInfo.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.open.bean.auth; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author 007 + */ +@Data +public class WxOpenAuthorizerInfo implements Serializable{ + private String nickName; + private String headImg; + private Integer serviceTypeInfo; + private Integer verifyTypeInfo; + private String userName; + private String principalName; + private Map businessInfo; + private String alias; + private String qrcodeUrl; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java new file mode 100644 index 0000000000..afcbd5f118 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java @@ -0,0 +1,100 @@ +package me.chanjar.weixin.open.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.util.WxOpenCryptUtil; +import me.chanjar.weixin.open.util.xml.XStreamTransformer; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +/** + * @author 007 + */ +@XStreamAlias("xml") +@Data +public class WxOpenXmlMessage implements Serializable{ + @XStreamAlias("AppId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String appId; + + @XStreamAlias("CreateTime") + private Long createTime; + + @XStreamAlias("InfoType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String infoType; + + @XStreamAlias("ComponentVerifyTicket") + @XStreamConverter(value = XStreamCDataConverter.class) + private String componentVerifyTicket; + + @XStreamAlias("AuthorizerAppid") + @XStreamConverter(value = XStreamCDataConverter.class) + private String authorizerAppid; + + @XStreamAlias("AuthorizationCode") + @XStreamConverter(value = XStreamCDataConverter.class) + private String authorizationCode; + + @XStreamAlias("AuthorizationCodeExpiredTime") + @XStreamConverter(value = XStreamCDataConverter.class) + private Long authorizationCodeExpiredTime; + + @XStreamAlias("PreAuthCode") + @XStreamConverter(value = XStreamCDataConverter.class) + private String preAuthCode; + + public static WxOpenXmlMessage fromXml(String xml) { + //修改微信变态的消息内容格式,方便解析 + xml = xml.replace("", ""); + return XStreamTransformer.fromXml(WxOpenXmlMessage.class, xml); + } + + public static WxOpenXmlMessage fromXml(InputStream is) { + return XStreamTransformer.fromXml(WxOpenXmlMessage.class, is); + } + + /** + * 从加密字符串转换 + * + * @param encryptedXml 密文 + * @param wxOpenConfigStorage 配置存储器对象 + * @param timestamp 时间戳 + * @param nonce 随机串 + * @param msgSignature 签名串 + */ + public static WxOpenXmlMessage fromEncryptedXml(String encryptedXml, + WxOpenConfigStorage wxOpenConfigStorage, String timestamp, String nonce, + String msgSignature) { + WxOpenCryptUtil cryptUtil = new WxOpenCryptUtil(wxOpenConfigStorage); + String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, + encryptedXml); + return fromXml(plainText); + } + public static WxMpXmlMessage fromEncryptedMpXml(String encryptedXml, + WxOpenConfigStorage wxOpenConfigStorage, String timestamp, String nonce, + String msgSignature) { + WxOpenCryptUtil cryptUtil = new WxOpenCryptUtil(wxOpenConfigStorage); + String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, + encryptedXml); + return WxMpXmlMessage.fromXml(plainText); + } + + public static WxOpenXmlMessage fromEncryptedXml(InputStream is, + WxOpenConfigStorage wxOpenConfigStorage, String timestamp, String nonce, + String msgSignature) { + try { + return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), wxOpenConfigStorage, + timestamp, nonce, msgSignature); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerInfoResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerInfoResult.java new file mode 100644 index 0000000000..040c9f023d --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerInfoResult.java @@ -0,0 +1,16 @@ +package me.chanjar.weixin.open.bean.result; + +import lombok.Data; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; + +import java.io.Serializable; + +/** + * @author 007 + */ +@Data +public class WxOpenAuthorizerInfoResult implements Serializable{ + private WxOpenAuthorizationInfo authorizationInfo; + private WxOpenAuthorizerInfo authorizerInfo; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerOptionResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerOptionResult.java new file mode 100644 index 0000000000..d7bf7aa1de --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerOptionResult.java @@ -0,0 +1,15 @@ +package me.chanjar.weixin.open.bean.result; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author 007 + */ +@Data +public class WxOpenAuthorizerOptionResult implements Serializable{ + String authorizerAppid; + String optionName; + String optionValue; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenQueryAuthResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenQueryAuthResult.java new file mode 100644 index 0000000000..02dab98885 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenQueryAuthResult.java @@ -0,0 +1,14 @@ +package me.chanjar.weixin.open.bean.result; + +import lombok.Data; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; + +import java.io.Serializable; + +/** + * @author 007 + */ +@Data +public class WxOpenQueryAuthResult implements Serializable{ + private WxOpenAuthorizationInfo authorizationInfo; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/WxOpenCryptUtil.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/WxOpenCryptUtil.java new file mode 100644 index 0000000000..0adcdbb3ac --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/WxOpenCryptUtil.java @@ -0,0 +1,28 @@ +package me.chanjar.weixin.open.util; + +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import org.apache.commons.codec.binary.Base64; +/** + * @author 007 + */ +public class WxOpenCryptUtil extends me.chanjar.weixin.common.util.crypto.WxCryptUtil { + /** + * 构造函数 + * + * @param wxOpenConfigStorage + */ + public WxOpenCryptUtil(WxOpenConfigStorage wxOpenConfigStorage) { + /* + * @param token 公众平台上,开发者设置的token + * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey + * @param appId 公众平台appid + */ + String encodingAesKey = wxOpenConfigStorage.getComponentAesKey(); + String token = wxOpenConfigStorage.getComponentToken(); + String appId = wxOpenConfigStorage.getComponentAppId(); + + this.token = token; + this.appidOrCorpid = appId; + this.aesKey = Base64.decodeBase64(encodingAesKey + "="); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizationInfoGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizationInfoGsonAdapter.java new file mode 100644 index 0000000000..7aa0c00c5a --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizationInfoGsonAdapter.java @@ -0,0 +1,45 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * @author 007 + */ +public class WxOpenAuthorizationInfoGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizationInfo deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizationInfo authorizationInfo = new WxOpenAuthorizationInfo(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + authorizationInfo.setAuthorizerAppid(GsonHelper.getString(jsonObject, "authorizer_appid")); + authorizationInfo.setAuthorizerAccessToken(GsonHelper.getString(jsonObject, "authorizer_access_token")); + authorizationInfo.setExpiresIn(GsonHelper.getPrimitiveInteger(jsonObject, "expires_in")); + authorizationInfo.setAuthorizerRefreshToken(GsonHelper.getString(jsonObject, "authorizer_refresh_token")); + List funcInfo = new ArrayList<>(); + JsonArray jsonArray = GsonHelper.getAsJsonArray(jsonObject.get("func_info")); + if(jsonArray != null && !jsonArray.isJsonNull()){ + for(int i = 0; i < jsonArray.size(); i++){ + jsonObject = jsonArray.get(i).getAsJsonObject(); + if(jsonObject == null || jsonObject.isJsonNull()){ + continue; + } + jsonObject = jsonObject.getAsJsonObject("funcscope_category"); + if(jsonObject == null || jsonObject.isJsonNull()){ + continue; + } + Integer id = GsonHelper.getInteger(jsonObject, "id"); + if(id == null) { + continue; + } + funcInfo.add(id); + } + } + authorizationInfo.setFuncInfo(funcInfo); + return authorizationInfo; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerAccessTokenGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerAccessTokenGsonAdapter.java new file mode 100644 index 0000000000..82a04b9ba8 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerAccessTokenGsonAdapter.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenAuthorizerAccessTokenGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizerAccessToken deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizerAccessToken authorizerAccessToken = new WxOpenAuthorizerAccessToken(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + authorizerAccessToken.setAuthorizerAccessToken(GsonHelper.getString(jsonObject, "authorizer_access_token")); + authorizerAccessToken.setExpiresIn(GsonHelper.getPrimitiveInteger(jsonObject, "expires_in")); + return authorizerAccessToken; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoGsonAdapter.java new file mode 100644 index 0000000000..5e1fb6d3e0 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoGsonAdapter.java @@ -0,0 +1,38 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; + +import java.lang.reflect.Type; +import java.util.Map; + +/** + * @author 007 + */ +public class WxOpenAuthorizerInfoGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizerInfo deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizerInfo authorizationInfo = new WxOpenAuthorizerInfo(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + authorizationInfo.setNickName(GsonHelper.getString(jsonObject, "nick_name")); + authorizationInfo.setHeadImg(GsonHelper.getString(jsonObject, "head_img")); + authorizationInfo.setUserName(GsonHelper.getString(jsonObject, "user_name")); + authorizationInfo.setPrincipalName(GsonHelper.getString(jsonObject, "principal_name")); + authorizationInfo.setAlias(GsonHelper.getString(jsonObject, "alias")); + authorizationInfo.setQrcodeUrl(GsonHelper.getString(jsonObject, "qrcode_url")); + if(jsonObject.has("service_type_info")) { + authorizationInfo.setServiceTypeInfo(GsonHelper.getInteger(jsonObject.getAsJsonObject("service_type_info"), "id")); + } + if(jsonObject.has("verify_type_info")) { + authorizationInfo.setVerifyTypeInfo(GsonHelper.getInteger(jsonObject.getAsJsonObject("verify_type_info"), "id")); + } + Map businessInfo = WxOpenGsonBuilder.create().fromJson(jsonObject.get("business_info"), + new TypeToken>() { + }.getType()); + authorizationInfo.setBusinessInfo(businessInfo); + return authorizationInfo; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoResultGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoResultGsonAdapter.java new file mode 100644 index 0000000000..1cef0ff411 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoResultGsonAdapter.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenAuthorizerInfoResultGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizerInfoResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizerInfoResult authorizerInfoResult = new WxOpenAuthorizerInfoResult(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + WxOpenAuthorizationInfo authorizationInfo = WxOpenGsonBuilder.INSTANCE.create().fromJson(jsonObject.get("authorization_info"), + new TypeToken() { + }.getType()); + + authorizerInfoResult.setAuthorizationInfo(authorizationInfo); + WxOpenAuthorizerInfo authorizerInfo = WxOpenGsonBuilder.INSTANCE.create().fromJson(jsonObject.get("authorizer_info"), + new TypeToken() { + }.getType()); + + authorizerInfoResult.setAuthorizerInfo(authorizerInfo); + return authorizerInfoResult; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerOptionResultGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerOptionResultGsonAdapter.java new file mode 100644 index 0000000000..8a2d379c31 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerOptionResultGsonAdapter.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenAuthorizerOptionResultGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizerOptionResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizerOptionResult authorizerOptionResult = new WxOpenAuthorizerOptionResult(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + authorizerOptionResult.setAuthorizerAppid(GsonHelper.getString(jsonObject, "authorizer_appid")); + authorizerOptionResult.setOptionName(GsonHelper.getString(jsonObject, "option_name")); + authorizerOptionResult.setOptionValue(GsonHelper.getString(jsonObject, "option_value")); + return authorizerOptionResult; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenComponentAccessTokenGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenComponentAccessTokenGsonAdapter.java new file mode 100644 index 0000000000..10ed85083c --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenComponentAccessTokenGsonAdapter.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenComponentAccessTokenGsonAdapter implements JsonDeserializer { + @Override + public WxOpenComponentAccessToken deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenComponentAccessToken componentAccessToken = new WxOpenComponentAccessToken(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + componentAccessToken.setComponentAccessToken(GsonHelper.getString(jsonObject, "component_access_token")); + componentAccessToken.setExpiresIn(GsonHelper.getPrimitiveInteger(jsonObject, "expires_in")); + return componentAccessToken; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java new file mode 100644 index 0000000000..2b390adef3 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java @@ -0,0 +1,36 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; + +/** + * @author 007 + */ +public class WxOpenGsonBuilder { + + public static final GsonBuilder INSTANCE = new GsonBuilder(); + + static { + INSTANCE.disableHtmlEscaping(); + INSTANCE.registerTypeAdapter(WxOpenComponentAccessToken.class, new WxOpenComponentAccessTokenGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizerAccessToken.class, new WxOpenAuthorizerAccessTokenGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizationInfo.class, new WxOpenAuthorizationInfoGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizerInfo.class, new WxOpenAuthorizerInfoGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenQueryAuthResult.class, new WxOpenQueryAuthResultGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizerInfoResult.class, new WxOpenAuthorizerInfoResultGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizerOptionResult.class, new WxOpenAuthorizerOptionResultGsonAdapter()); + + } + + public static Gson create() { + return INSTANCE.create(); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenQueryAuthResultGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenQueryAuthResultGsonAdapter.java new file mode 100644 index 0000000000..8868d0fef7 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenQueryAuthResultGsonAdapter.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenQueryAuthResultGsonAdapter implements JsonDeserializer { + @Override + public WxOpenQueryAuthResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenQueryAuthResult queryAuthResult = new WxOpenQueryAuthResult(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + WxOpenAuthorizationInfo authorizationInfo = WxOpenGsonBuilder.INSTANCE.create().fromJson(jsonObject.get("authorization_info"), + new TypeToken() { + }.getType()); + + queryAuthResult.setAuthorizationInfo(authorizationInfo); + return queryAuthResult; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/xml/XStreamTransformer.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/xml/XStreamTransformer.java new file mode 100644 index 0000000000..515c90def0 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/xml/XStreamTransformer.java @@ -0,0 +1,90 @@ +package me.chanjar.weixin.open.util.xml; + +import com.thoughtworks.xstream.XStream; +import me.chanjar.weixin.common.util.xml.XStreamInitializer; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; + +import java.io.InputStream; +import java.util.*; + +/** + * @author 007 + */ +public class XStreamTransformer { + private static final Map, XStream> CLASS_2_XSTREAM_INSTANCE = new HashMap<>(); + + static { + registerClass(WxOpenXmlMessage.class); + } + + /** + * xml -> pojo + */ + @SuppressWarnings("unchecked") + public static T fromXml(Class clazz, String xml) { + T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml); + return object; + } + + @SuppressWarnings("unchecked") + public static T fromXml(Class clazz, InputStream is) { + T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is); + return object; + } + + /** + * pojo -> xml + */ + public static String toXml(Class clazz, T object) { + return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); + } + + /** + * 注册扩展消息的解析器 + * + * @param clz 类型 + * @param xStream xml解析器 + */ + private static void register(Class clz, XStream xStream) { + CLASS_2_XSTREAM_INSTANCE.put(clz, xStream); + } + + /** + * 会自动注册该类及其子类 + * + * @param clz 要注册的类 + */ + private static void registerClass(Class clz) { + XStream xstream = XStreamInitializer.getInstance(); + xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); + + xstream.processAnnotations(clz); + xstream.processAnnotations(getInnerClasses(clz)); + if (clz.equals(WxOpenXmlMessage.class)) { + // 操蛋的微信,模板消息推送成功的消息是MsgID,其他消息推送过来是MsgId + xstream.aliasField("MsgID", WxOpenXmlMessage.class, "msgId"); + } + + register(clz, xstream); + } + + private static Class[] getInnerClasses(Class clz) { + Class[] innerClasses = clz.getClasses(); + if (innerClasses == null) { + return null; + } + + List> result = new ArrayList<>(); + result.addAll(Arrays.asList(innerClasses)); + for (Class inner : innerClasses) { + Class[] innerClz = getInnerClasses(inner); + if (innerClz == null) { + continue; + } + + result.addAll(Arrays.asList(innerClz)); + } + + return result.toArray(new Class[0]); + } +} From 29220ce934af2ad32db7ad8a56c5992fb9a4412a Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Thu, 9 Nov 2017 10:32:19 +0800 Subject: [PATCH 02/13] =?UTF-8?q?WxOpenXmlMessage=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- weixin-java-open/README.md | 34 +++---------------- .../open/api/WxOpenComponentService.java | 3 ++ .../api/impl/WxOpenComponentServiceImpl.java | 29 ++++++++++++++++ 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/weixin-java-open/README.md b/weixin-java-open/README.md index eef5c00eb4..d99b770673 100644 --- a/weixin-java-open/README.md +++ b/weixin-java-open/README.md @@ -19,40 +19,16 @@ public class NotifyController extends WechatThridBaseController { throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); } - String out = ""; // aes加密的消息 WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); - if (StringUtils.equalsIgnoreCase(inMessage.getInfoType(), "component_verify_ticket")) { - wxOpenService.getWxOpenComponentService().getWxOpenConfigStorage().setComponentVerifyTicket(inMessage.getComponentVerifyTicket()); - out = "success"; - } - //新增、跟新授权 - if (StringUtils.equalsAnyIgnoreCase(inMessage.getInfoType(), "authorized", "updateauthorized")) { - try { - WxOpenQueryAuthResult queryAuth = wxOpenService.getWxOpenComponentService().getQueryAuth(inMessage.getAuthorizationCode()); - WxOpenAuthorizationInfo authorizationInfo = queryAuth.getAuthorizationInfo(); - wxOpenService.getWxOpenConfigStorage().updateAuthorizerAccessToken(authorizationInfo.getAuthorizerAppid(), - authorizationInfo.getAuthorizerAccessToken(), authorizationInfo.getExpiresIn()); - wxOpenService.getWxOpenConfigStorage().setAuthorizerRefreshToken(authorizationInfo.getAuthorizerAppid(), authorizationInfo.getAuthorizerRefreshToken()); - out = "success"; - } catch (WxErrorException e) { - throw new ResponseException(ErrorCodeEnum.ERROR, e); - } - } - //取消授权 - if (StringUtils.equalsIgnoreCase(inMessage.getInfoType(), "unauthorized")) { - + String out = null; + try { + out = wxOpenService.getWxOpenComponentService().route(inMessage); + } catch (WxErrorException e) { + throw new ResponseException(ErrorCodeEnum.ERROR, e); } -// WxMpXmlOutMessage outMessage = this.getWxService().route(inMessage); -// if (outMessage == null) { -// return ""; -// } -// -// out = outMessage.toEncryptedXml(wxOpenService.getWxOpenConfigStorage()); - - this.logger.debug("\n组装回复信息:{}", out); return out; diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index 182d5ef3f4..ded17248ed 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -4,6 +4,7 @@ import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; @@ -46,6 +47,8 @@ public interface WxOpenComponentService { */ String getPreAuthUrl(String redirectURI) throws WxErrorException; + String route(WxOpenXmlMessage wxMessage) throws WxErrorException; + /** * 使用授权码换取公众号或小程序的接口调用凭据和授权信息 */ diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java index fbfef52e91..9f797e2f0f 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java @@ -13,6 +13,8 @@ import me.chanjar.weixin.open.api.WxOpenService; import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; @@ -108,6 +110,33 @@ public String getPreAuthUrl(String redirectURI) throws WxErrorException { return String.format(COMPONENT_LOGIN_PAGE_URL, getWxOpenConfigStorage().getComponentAppId(), jsonObject.get("pre_auth_code").getAsString(), URIUtil.encodeURIComponent(redirectURI)); } + @Override + public String route(final WxOpenXmlMessage wxMessage) throws WxErrorException { + if (wxMessage == null) { + throw new NullPointerException("message is empty"); + } + if (StringUtils.equalsIgnoreCase(wxMessage.getInfoType(), "component_verify_ticket")) { + getWxOpenConfigStorage().setComponentVerifyTicket(wxMessage.getComponentVerifyTicket()); + return "success"; + } + //新增、跟新授权 + if (StringUtils.equalsAnyIgnoreCase(wxMessage.getInfoType(), "authorized", "updateauthorized")) { + WxOpenQueryAuthResult queryAuth = wxOpenService.getWxOpenComponentService().getQueryAuth(wxMessage.getAuthorizationCode()); + if (queryAuth == null || queryAuth.getAuthorizationInfo() == null || queryAuth.getAuthorizationInfo().getAuthorizerAppid() == null) { + throw new NullPointerException("getQueryAuth"); + } + WxOpenAuthorizationInfo authorizationInfo = queryAuth.getAuthorizationInfo(); + if (authorizationInfo.getAuthorizerAccessToken() != null) { + getWxOpenConfigStorage().updateAuthorizerAccessToken(authorizationInfo.getAuthorizerAppid(), + authorizationInfo.getAuthorizerAccessToken(), authorizationInfo.getExpiresIn()); + } + if (authorizationInfo.getAuthorizerRefreshToken() != null) { + getWxOpenConfigStorage().setAuthorizerRefreshToken(authorizationInfo.getAuthorizerAppid(), authorizationInfo.getAuthorizerRefreshToken()); + } + return "success"; + } + return null; + } @Override public WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException { JsonObject jsonObject = new JsonObject(); From 35af6064a66a70e05aa0397e1952d07d8c28db5b Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Mon, 13 Nov 2017 13:59:40 +0800 Subject: [PATCH 03/13] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E6=91=87=E5=91=A8?= =?UTF-8?q?=E8=BE=B9=E9=83=A8=E5=88=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpShakeService.java | 34 +++++++++++++++++++ .../mp/api/impl/WxMpShakeServiceImpl.java | 29 +++++++++++++++- .../mp/bean/shake/WxMpDeviceIdentifier.java | 22 ++++++++++++ .../WxMpShakeAroundDeviceBindPageQuery.java | 23 +++++++++++++ .../shake/WxMpShakeAroundPageAddQuery.java | 23 +++++++++++++ .../shake/WxMpShakeAroundPageAddResult.java | 26 ++++++++++++++ .../WxMpShakeAroundRelationSearchQuery.java | 32 +++++++++++++++++ .../WxMpShakeAroundRelationSearchResult.java | 21 ++++++++++++ 8 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java index 87a6747af5..697bfe899d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java @@ -1,8 +1,10 @@ package me.chanjar.weixin.mp.api; +import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; /** * 摇一摇周边的相关接口 @@ -24,4 +26,36 @@ public interface WxMpShakeService { */ WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException; + /** + *
+   * 页面管理
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459246752 + *
+ * @param shakeAroundPageAddQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException; + + /** + *
+   * 配置设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459301931 + *
+ * @param shakeAroundDeviceBindPageQuery + * @return + * @throws WxErrorException + */ + WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException; + + /** + *
+   * 查询设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443447914 + *
+ * @param shakeAroundRelationSearchQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java index bee636fd54..2c90f70e2b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java @@ -1,13 +1,16 @@ package me.chanjar.weixin.mp.api.impl; +import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpShakeService; import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; /** * Created by rememberber on 2017/6/5. + * * @author rememberber */ public class WxMpShakeServiceImpl implements WxMpShakeService { @@ -27,7 +30,7 @@ public WxMpShakeServiceImpl(WxMpService wxMpService) { * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE * * - * @param wxMpShakeQuery 查询参数 + * @param wxMpShakeQuery 查询参数 */ @Override public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException { @@ -36,4 +39,28 @@ public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws Wx String responseContent = this.wxMpService.post(url, postData); return WxMpShakeInfoResult.fromJson(responseContent); } + + @Override + public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/page/add"; + String postData = shakeAroundPageAddQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundPageAddResult.fromJson(responseContent); + } + + @Override + public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/device/bindpage"; + String postData = shakeAroundDeviceBindPageQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxError.fromJson(responseContent); + } + + @Override + public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/relation/search"; + String postData = shakeAroundRelationSearchQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundRelationSearchResult.fromJson(responseContent); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java new file mode 100644 index 0000000000..df500a9671 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpDeviceIdentifier implements Serializable { + private Integer device_id; + private String uuid; + private Integer major; + private Integer minor; + public JsonObject toJsonObject(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("device_id", device_id); + jsonObject.addProperty("uuid", uuid); + jsonObject.addProperty("major", major); + jsonObject.addProperty("minor", minor); + return jsonObject; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java new file mode 100644 index 0000000000..7b30b9e56e --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.Data; + +import java.util.List; + +@Data +public class WxMpShakeAroundDeviceBindPageQuery { + private WxMpDeviceIdentifier deviceIdentifier; + private List pageIds; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + JsonArray jsonArray = new JsonArray(); + for(Integer pageid: pageIds){ + jsonArray.add(pageid); + } + jsonObject.add("page_ids", jsonArray); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java new file mode 100644 index 0000000000..b04ced93bd --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; +@Data +public class WxMpShakeAroundPageAddQuery implements Serializable { + private String title; + private String description; + private String pageUrl; + private String comment; + private String iconUrl; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("title", title); + jsonObject.addProperty("description", description); + jsonObject.addProperty("page_url", pageUrl); + jsonObject.addProperty("comment", comment); + jsonObject.addProperty("icon_url", iconUrl); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java new file mode 100644 index 0000000000..632fe4f351 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundPageAddResult implements Serializable { + private Integer errorCode; + private String errorMsg; + private Integer pageId; + public static WxMpShakeAroundPageAddResult fromJson(String json) { + JsonObject jsonObject = WxMpGsonBuilder.INSTANCE.create().fromJson(json, JsonObject.class); + WxMpShakeAroundPageAddResult result = new WxMpShakeAroundPageAddResult(); + result.setErrorCode(GsonHelper.getInteger(jsonObject, "errcode")); + result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); + jsonObject = jsonObject.getAsJsonObject("data"); + if(jsonObject != null){ + result.setPageId(GsonHelper.getInteger(jsonObject, "page_id")); + } + return result; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java new file mode 100644 index 0000000000..390fe50964 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundRelationSearchQuery implements Serializable { + private int type; + private Integer pageId; + private Integer begin; + private Integer count; + private WxMpDeviceIdentifier deviceIdentifier; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("type", type); + switch (type){ + case 1: + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + break; + case 2: + jsonObject.addProperty("page_id", pageId); + jsonObject.addProperty("begin", begin); + jsonObject.addProperty("count", count); + break; + default: + throw new IllegalArgumentException("type error"); + } + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java new file mode 100644 index 0000000000..cd46a85bd8 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.mp.bean.shake; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +@Data +public class WxMpShakeAroundRelationSearchResult implements Serializable { + private Integer errcode; + private String errmsg; + public static WxMpShakeAroundRelationSearchResult fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); + } + @Data + public static class WxMpShakeAcoundRelationSearch implements Serializable{ + private List relations; + private Integer total_count; + } +} From 4193f20d0281b4e870829f9130774dd3148964d7 Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Mon, 13 Nov 2017 15:56:17 +0800 Subject: [PATCH 04/13] fix --- .../mp/bean/shake/WxMpShakeAroundRelationSearchResult.java | 1 + 1 file changed, 1 insertion(+) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java index cd46a85bd8..2b7269e572 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java @@ -10,6 +10,7 @@ public class WxMpShakeAroundRelationSearchResult implements Serializable { private Integer errcode; private String errmsg; + private WxMpShakeAcoundRelationSearch data; public static WxMpShakeAroundRelationSearchResult fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); } From f3f35adb6f64b0d6c3f97dfd49e6b576c00e2ada Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Mon, 13 Nov 2017 16:06:03 +0800 Subject: [PATCH 05/13] fix --- .../me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java | 1 + .../mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java index df500a9671..e93bf75cf9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java @@ -9,6 +9,7 @@ public class WxMpDeviceIdentifier implements Serializable { private Integer device_id; private String uuid; + private Integer page_id; private Integer major; private Integer minor; public JsonObject toJsonObject(){ diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java index 7b30b9e56e..71da0b1c65 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java @@ -4,12 +4,12 @@ import com.google.gson.JsonObject; import lombok.Data; -import java.util.List; +import java.util.Collection; @Data public class WxMpShakeAroundDeviceBindPageQuery { private WxMpDeviceIdentifier deviceIdentifier; - private List pageIds; + private Collection pageIds; public String toJsonString(){ JsonObject jsonObject = new JsonObject(); jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); From 85c0f11a0fec1fddfc85582700ffb001824bb8d8 Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Mon, 13 Nov 2017 13:59:40 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E6=91=87=E5=91=A8?= =?UTF-8?q?=E8=BE=B9=E9=83=A8=E5=88=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpShakeService.java | 34 +++++++++++++++++++ .../mp/api/impl/WxMpShakeServiceImpl.java | 29 +++++++++++++++- .../mp/bean/shake/WxMpDeviceIdentifier.java | 22 ++++++++++++ .../WxMpShakeAroundDeviceBindPageQuery.java | 23 +++++++++++++ .../shake/WxMpShakeAroundPageAddQuery.java | 23 +++++++++++++ .../shake/WxMpShakeAroundPageAddResult.java | 26 ++++++++++++++ .../WxMpShakeAroundRelationSearchQuery.java | 32 +++++++++++++++++ .../WxMpShakeAroundRelationSearchResult.java | 21 ++++++++++++ 8 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java index 87a6747af5..697bfe899d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java @@ -1,8 +1,10 @@ package me.chanjar.weixin.mp.api; +import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; /** * 摇一摇周边的相关接口 @@ -24,4 +26,36 @@ public interface WxMpShakeService { */ WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException; + /** + *
+   * 页面管理
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459246752 + *
+ * @param shakeAroundPageAddQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException; + + /** + *
+   * 配置设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459301931 + *
+ * @param shakeAroundDeviceBindPageQuery + * @return + * @throws WxErrorException + */ + WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException; + + /** + *
+   * 查询设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443447914 + *
+ * @param shakeAroundRelationSearchQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java index bee636fd54..2c90f70e2b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java @@ -1,13 +1,16 @@ package me.chanjar.weixin.mp.api.impl; +import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpShakeService; import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; /** * Created by rememberber on 2017/6/5. + * * @author rememberber */ public class WxMpShakeServiceImpl implements WxMpShakeService { @@ -27,7 +30,7 @@ public WxMpShakeServiceImpl(WxMpService wxMpService) { * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE * * - * @param wxMpShakeQuery 查询参数 + * @param wxMpShakeQuery 查询参数 */ @Override public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException { @@ -36,4 +39,28 @@ public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws Wx String responseContent = this.wxMpService.post(url, postData); return WxMpShakeInfoResult.fromJson(responseContent); } + + @Override + public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/page/add"; + String postData = shakeAroundPageAddQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundPageAddResult.fromJson(responseContent); + } + + @Override + public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/device/bindpage"; + String postData = shakeAroundDeviceBindPageQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxError.fromJson(responseContent); + } + + @Override + public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/relation/search"; + String postData = shakeAroundRelationSearchQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundRelationSearchResult.fromJson(responseContent); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java new file mode 100644 index 0000000000..df500a9671 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpDeviceIdentifier implements Serializable { + private Integer device_id; + private String uuid; + private Integer major; + private Integer minor; + public JsonObject toJsonObject(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("device_id", device_id); + jsonObject.addProperty("uuid", uuid); + jsonObject.addProperty("major", major); + jsonObject.addProperty("minor", minor); + return jsonObject; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java new file mode 100644 index 0000000000..7b30b9e56e --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.Data; + +import java.util.List; + +@Data +public class WxMpShakeAroundDeviceBindPageQuery { + private WxMpDeviceIdentifier deviceIdentifier; + private List pageIds; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + JsonArray jsonArray = new JsonArray(); + for(Integer pageid: pageIds){ + jsonArray.add(pageid); + } + jsonObject.add("page_ids", jsonArray); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java new file mode 100644 index 0000000000..b04ced93bd --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; +@Data +public class WxMpShakeAroundPageAddQuery implements Serializable { + private String title; + private String description; + private String pageUrl; + private String comment; + private String iconUrl; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("title", title); + jsonObject.addProperty("description", description); + jsonObject.addProperty("page_url", pageUrl); + jsonObject.addProperty("comment", comment); + jsonObject.addProperty("icon_url", iconUrl); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java new file mode 100644 index 0000000000..632fe4f351 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundPageAddResult implements Serializable { + private Integer errorCode; + private String errorMsg; + private Integer pageId; + public static WxMpShakeAroundPageAddResult fromJson(String json) { + JsonObject jsonObject = WxMpGsonBuilder.INSTANCE.create().fromJson(json, JsonObject.class); + WxMpShakeAroundPageAddResult result = new WxMpShakeAroundPageAddResult(); + result.setErrorCode(GsonHelper.getInteger(jsonObject, "errcode")); + result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); + jsonObject = jsonObject.getAsJsonObject("data"); + if(jsonObject != null){ + result.setPageId(GsonHelper.getInteger(jsonObject, "page_id")); + } + return result; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java new file mode 100644 index 0000000000..390fe50964 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundRelationSearchQuery implements Serializable { + private int type; + private Integer pageId; + private Integer begin; + private Integer count; + private WxMpDeviceIdentifier deviceIdentifier; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("type", type); + switch (type){ + case 1: + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + break; + case 2: + jsonObject.addProperty("page_id", pageId); + jsonObject.addProperty("begin", begin); + jsonObject.addProperty("count", count); + break; + default: + throw new IllegalArgumentException("type error"); + } + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java new file mode 100644 index 0000000000..cd46a85bd8 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.mp.bean.shake; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +@Data +public class WxMpShakeAroundRelationSearchResult implements Serializable { + private Integer errcode; + private String errmsg; + public static WxMpShakeAroundRelationSearchResult fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); + } + @Data + public static class WxMpShakeAcoundRelationSearch implements Serializable{ + private List relations; + private Integer total_count; + } +} From 3668b8ba7a5f6f94770352a989caac9aa3d88b60 Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Mon, 13 Nov 2017 15:56:17 +0800 Subject: [PATCH 07/13] fix --- .../mp/bean/shake/WxMpShakeAroundRelationSearchResult.java | 1 + 1 file changed, 1 insertion(+) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java index cd46a85bd8..2b7269e572 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java @@ -10,6 +10,7 @@ public class WxMpShakeAroundRelationSearchResult implements Serializable { private Integer errcode; private String errmsg; + private WxMpShakeAcoundRelationSearch data; public static WxMpShakeAroundRelationSearchResult fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); } From 074873e628482ccede25ed4a1c7d12bfd520d0cb Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Mon, 13 Nov 2017 16:06:03 +0800 Subject: [PATCH 08/13] fix --- .../me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java | 1 + .../mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java index df500a9671..e93bf75cf9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java @@ -9,6 +9,7 @@ public class WxMpDeviceIdentifier implements Serializable { private Integer device_id; private String uuid; + private Integer page_id; private Integer major; private Integer minor; public JsonObject toJsonObject(){ diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java index 7b30b9e56e..71da0b1c65 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java @@ -4,12 +4,12 @@ import com.google.gson.JsonObject; import lombok.Data; -import java.util.List; +import java.util.Collection; @Data public class WxMpShakeAroundDeviceBindPageQuery { private WxMpDeviceIdentifier deviceIdentifier; - private List pageIds; + private Collection pageIds; public String toJsonString(){ JsonObject jsonObject = new JsonObject(); jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); From aea3beb6e161cbdc7dd12e35b0d8b5d301725382 Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Tue, 14 Nov 2017 15:58:26 +0800 Subject: [PATCH 09/13] rebase --- weixin-java-common/pom.xml | 256 ++--- .../weixin/common/bean/WxAccessToken.java | 40 +- .../common/bean/WxCardApiSignature.java | 82 +- .../weixin/common/bean/WxJsapiSignature.java | 48 +- .../weixin/common/bean/menu/WxMenu.java | 106 +- .../weixin/common/bean/menu/WxMenuButton.java | 164 +-- .../weixin/common/bean/menu/WxMenuRule.java | 58 +- .../weixin/common/bean/result/WxError.java | 76 +- .../bean/result/WxMediaUploadResult.java | 54 +- .../chanjar/weixin/common/util/BeanUtils.java | 212 ++-- .../common/util/http/HttpResponseProxy.java | 180 ++-- .../ApacheSimplePostRequestExecutor.java | 118 +-- .../JoddHttpSimplePostRequestExecutor.java | 116 +-- .../common/util/json/WxErrorAdapter.java | 78 +- .../weixin/common/bean/WxErrorTest.java | 72 +- weixin-java-cp/pom.xml | 176 ++-- .../cp/api/impl/WxCpServiceOkHttpImpl.java | 200 ++-- .../me/chanjar/weixin/cp/bean/WxCpDepart.java | 60 +- .../chanjar/weixin/cp/bean/WxCpMessage.java | 238 ++--- .../weixin/cp/bean/WxCpMessageSendResult.java | 136 +-- .../me/chanjar/weixin/cp/bean/WxCpTag.java | 64 +- .../bean/WxCpTagAddOrRemoveUsersResult.java | 114 +-- .../me/chanjar/weixin/cp/bean/WxCpUser.java | 172 ++-- .../weixin/cp/bean/WxCpXmlMessage.java | 604 +++++------ .../cp/bean/WxCpXmlOutImageMessage.java | 44 +- .../weixin/cp/bean/WxCpXmlOutMessage.java | 162 +-- .../weixin/cp/bean/WxCpXmlOutNewsMessage.java | 110 +- .../weixin/cp/bean/WxCpXmlOutTextMessage.java | 44 +- .../cp/bean/WxCpXmlOutVideoMessage.java | 126 +-- .../cp/bean/WxCpXmlOutVoiceMessage.java | 44 +- .../weixin/cp/bean/article/MpnewsArticle.java | 56 +- .../weixin/cp/bean/article/NewArticle.java | 46 +- .../weixin/cp/api/WxCpBusyRetryTest.java | 136 +-- .../weixin/cp/bean/WxCpXmlMessageTest.java | 240 ++--- weixin-java-miniapp/pom.xml | 168 ++-- .../api/impl/WxMaMediaServiceImpl.java | 110 +- .../wx/miniapp/bean/WxMaCodeLineColor.java | 36 +- .../bean/WxMaJscode2SessionResult.java | 72 +- .../wx/miniapp/bean/WxMaKefuMessage.java | 90 +- .../wx/miniapp/bean/WxMaMessage.java | 302 +++--- .../wx/miniapp/bean/WxMaQrcode.java | 64 +- .../wx/miniapp/bean/WxMaTemplateMessage.java | 216 ++-- .../wx/miniapp/bean/WxMaUserInfo.java | 70 +- .../wx/miniapp/bean/WxMaWxcode.java | 66 +- .../wx/miniapp/bean/WxMaWxcodeLimit.java | 68 +- .../api/impl/WxMaMsgServiceImplTest.java | 146 +-- .../miniapp/bean/WxMaTemplateMessageTest.java | 62 +- .../wx/miniapp/demo/WxMaDemoServer.java | 296 +++--- weixin-java-mp/pom.xml | 168 ++-- .../weixin/mp/api/WxMpMassMessageService.java | 238 ++--- .../weixin/mp/api/WxMpShakeService.java | 122 +-- .../mp/api/impl/WxMpCardServiceImpl.java | 478 ++++----- .../mp/api/impl/WxMpKefuServiceImpl.java | 304 +++--- .../api/impl/WxMpMassMessageServiceImpl.java | 134 +-- .../mp/api/impl/WxMpMaterialServiceImpl.java | 302 +++--- .../mp/api/impl/WxMpQrcodeServiceImpl.java | 302 +++--- .../mp/api/impl/WxMpServiceAbstractImpl.java | 938 +++++++++--------- .../mp/api/impl/WxMpServiceOkHttpImpl.java | 186 ++-- .../mp/api/impl/WxMpShakeServiceImpl.java | 132 +-- .../datacube/WxDataCubeArticleResult.java | 246 ++--- .../bean/datacube/WxDataCubeArticleTotal.java | 100 +- .../bean/datacube/WxDataCubeBaseResult.java | 70 +- .../datacube/WxDataCubeInterfaceResult.java | 130 +-- .../mp/bean/datacube/WxDataCubeMsgResult.java | 156 +-- .../weixin/mp/bean/device/BaseResp.java | 62 +- .../weixin/mp/bean/device/RespMsg.java | 42 +- .../weixin/mp/bean/device/TransMsgResp.java | 58 +- .../mp/bean/device/WxDeviceAuthorize.java | 64 +- .../bean/device/WxDeviceAuthorizeResult.java | 48 +- .../weixin/mp/bean/device/WxDeviceBind.java | 44 +- .../bean/device/WxDeviceBindDeviceResult.java | 78 +- .../mp/bean/device/WxDeviceBindResult.java | 48 +- .../weixin/mp/bean/device/WxDeviceMsg.java | 58 +- .../mp/bean/device/WxDeviceOpenIdResult.java | 64 +- .../mp/bean/device/WxDeviceQrCodeResult.java | 60 +- .../bean/message/WxMpXmlOutImageMessage.java | 48 +- .../bean/message/WxMpXmlOutNewsMessage.java | 116 +-- .../bean/message/WxMpXmlOutTextMessage.java | 48 +- .../WxMpXmlOutTransferKefuMessage.java | 70 +- .../bean/message/WxMpXmlOutVoiceMessage.java | 48 +- .../mp/bean/shake/WxMpDeviceIdentifier.java | 46 +- .../WxMpShakeAroundDeviceBindPageQuery.java | 46 +- .../shake/WxMpShakeAroundPageAddQuery.java | 46 +- .../shake/WxMpShakeAroundPageAddResult.java | 52 +- .../WxMpShakeAroundRelationSearchQuery.java | 64 +- .../WxMpShakeAroundRelationSearchResult.java | 44 +- ...lVoiceAndImageDownloadRequestExecutor.java | 72 +- .../mp/util/http/QrCodeRequestExecutor.java | 78 +- .../ApacheMaterialUploadRequestExecutor.java | 154 +-- .../ApacheMediaImgUploadRequestExecutor.java | 120 +-- .../JoddMaterialUploadRequestExecutor.java | 124 +-- .../JoddMediaImgUploadRequestExecutor.java | 98 +- .../OkhttpMaterialUploadRequestExecutor.java | 132 +-- .../weixin/mp/api/WxMpBusyRetryTest.java | 130 +-- .../open/api/WxOpenComponentService.java | 166 ++-- weixin-java-pay/pom.xml | 110 +- 96 files changed, 6321 insertions(+), 6321 deletions(-) diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 25dc5bd1fa..769c0bea6c 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -1,128 +1,128 @@ - - - 4.0.0 - - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - - - weixin-java-common - WeiXin Java Tools - Common - 微信公众号、企业号Java SDK Common - - - - org.jodd - jodd-http - provided - - - com.squareup.okhttp3 - okhttp - provided - - - - org.slf4j - slf4j-api - - - com.thoughtworks.xstream - xstream - - - org.apache.httpcomponents - httpclient - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - httpmime - - - org.slf4j - jcl-over-slf4j - 1.7.24 - - - - com.google.code.gson - gson - - - commons-codec - commons-codec - - - commons-io - commons-io - - - org.apache.commons - commons-lang3 - - - com.google.guava - guava - - - org.projectlombok - lombok - - - - ch.qos.logback - logback-classic - test - - - org.testng - testng - test - - - org.mockito - mockito-all - test - - - com.google.inject - guice - test - - - org.eclipse.jetty - jetty-server - test - - - org.eclipse.jetty - jetty-servlet - test - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - src/test/resources/testng.xml - - - - - - - + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + + + weixin-java-common + WeiXin Java Tools - Common + 微信公众号、企业号Java SDK Common + + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + + org.slf4j + slf4j-api + + + com.thoughtworks.xstream + xstream + + + org.apache.httpcomponents + httpclient + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpmime + + + org.slf4j + jcl-over-slf4j + 1.7.24 + + + + com.google.code.gson + gson + + + commons-codec + commons-codec + + + commons-io + commons-io + + + org.apache.commons + commons-lang3 + + + com.google.guava + guava + + + org.projectlombok + lombok + + + + ch.qos.logback + logback-classic + test + + + org.testng + testng + test + + + org.mockito + mockito-all + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java index 6327965152..3e6d6da197 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java @@ -1,20 +1,20 @@ -package me.chanjar.weixin.common.bean; - -import lombok.Data; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.Serializable; - -@Data -public class WxAccessToken implements Serializable { - private static final long serialVersionUID = 8709719312922168909L; - - private String accessToken; - - private int expiresIn = -1; - - public static WxAccessToken fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxAccessToken.class); - } - -} +package me.chanjar.weixin.common.bean; + +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxAccessToken implements Serializable { + private static final long serialVersionUID = 8709719312922168909L; + + private String accessToken; + + private int expiresIn = -1; + + public static WxAccessToken fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxAccessToken.class); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java index 9d5d7a06dd..19fb06a74c 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java @@ -1,41 +1,41 @@ -package me.chanjar.weixin.common.bean; - -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; - -/** - * 卡券Api签名. - * - * @author YuJian - * @version 15/11/8 - */ -@Data -public class WxCardApiSignature implements Serializable { - private static final long serialVersionUID = 158176707226975979L; - - private String appId; - - private String cardId; - - private String cardType; - - private String locationId; - - private String code; - - private String openId; - - private Long timestamp; - - private String nonceStr; - - private String signature; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.common.bean; + +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; + +import java.io.Serializable; + +/** + * 卡券Api签名. + * + * @author YuJian + * @version 15/11/8 + */ +@Data +public class WxCardApiSignature implements Serializable { + private static final long serialVersionUID = 158176707226975979L; + + private String appId; + + private String cardId; + + private String cardType; + + private String locationId; + + private String code; + + private String openId; + + private Long timestamp; + + private String nonceStr; + + private String signature; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java index 619f0a7504..899a32cf51 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.common.bean; - -import lombok.Data; - -import java.io.Serializable; - -/** - * jspai signature. - */ -@Data -public class WxJsapiSignature implements Serializable { - private static final long serialVersionUID = -1116808193154384804L; - - private String appId; - - private String nonceStr; - - private long timestamp; - - private String url; - - private String signature; - -} +package me.chanjar.weixin.common.bean; + +import lombok.Data; + +import java.io.Serializable; + +/** + * jspai signature. + */ +@Data +public class WxJsapiSignature implements Serializable { + private static final long serialVersionUID = -1116808193154384804L; + + private String appId; + + private String nonceStr; + + private long timestamp; + + private String url; + + private String signature; + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java index 4d349acb25..327c613178 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java @@ -1,53 +1,53 @@ -package me.chanjar.weixin.common.bean.menu; - -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; - -/** - * 菜单(公众号和企业号共用的). - * - * @author Daniel Qian - */ -@Data -public class WxMenu implements Serializable { - private static final long serialVersionUID = -7083914585539687746L; - - private List buttons = new ArrayList<>(); - - private WxMenuRule matchRule; - - /** - * 要用 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html 格式来反序列化 - * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu - */ - public static WxMenu fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxMenu.class); - } - - /** - * 要用 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html 格式来反序列化 - * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu - */ - public static WxMenu fromJson(InputStream is) { - return WxGsonBuilder.create() - .fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class); - } - - public String toJson() { - return WxGsonBuilder.create().toJson(this); - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.common.bean.menu; + +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * 菜单(公众号和企业号共用的). + * + * @author Daniel Qian + */ +@Data +public class WxMenu implements Serializable { + private static final long serialVersionUID = -7083914585539687746L; + + private List buttons = new ArrayList<>(); + + private WxMenuRule matchRule; + + /** + * 要用 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html 格式来反序列化 + * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu + */ + public static WxMenu fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxMenu.class); + } + + /** + * 要用 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html 格式来反序列化 + * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu + */ + public static WxMenu fromJson(InputStream is) { + return WxGsonBuilder.create() + .fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class); + } + + public String toJson() { + return WxGsonBuilder.create().toJson(this); + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java index 2f9276b025..abe3e04a05 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java @@ -1,82 +1,82 @@ -package me.chanjar.weixin.common.bean.menu; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -@Data -public class WxMenuButton implements Serializable { - private static final long serialVersionUID = -1070939403109776555L; - - /** - *
-   * 菜单的响应动作类型.
-   * view表示网页类型,
-   * click表示点击类型,
-   * miniprogram表示小程序类型
-   * 
- */ - private String type; - - /** - * 菜单标题,不超过16个字节,子菜单不超过60个字节. - */ - private String name; - - /** - *
-   * 菜单KEY值,用于消息接口推送,不超过128字节.
-   * click等点击类型必须
-   * 
- */ - private String key; - - /** - *
-   * 网页链接.
-   * 用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
-   * view、miniprogram类型必须
-   * 
- */ - private String url; - - /** - *
-   * 调用新增永久素材接口返回的合法media_id.
-   * media_id类型和view_limited类型必须
-   * 
- */ - @SerializedName("media_id") - private String mediaId; - - /** - *
-   * 小程序的appid.
-   * miniprogram类型必须
-   * 
- */ - @SerializedName("appid") - private String appId; - - /** - *
-   * 小程序的页面路径.
-   * miniprogram类型必须
-   * 
- */ - @SerializedName("pagepath") - private String pagePath; - - @SerializedName("sub_button") - private List subButtons = new ArrayList<>(); - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.common.bean.menu; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@Data +public class WxMenuButton implements Serializable { + private static final long serialVersionUID = -1070939403109776555L; + + /** + *
+   * 菜单的响应动作类型.
+   * view表示网页类型,
+   * click表示点击类型,
+   * miniprogram表示小程序类型
+   * 
+ */ + private String type; + + /** + * 菜单标题,不超过16个字节,子菜单不超过60个字节. + */ + private String name; + + /** + *
+   * 菜单KEY值,用于消息接口推送,不超过128字节.
+   * click等点击类型必须
+   * 
+ */ + private String key; + + /** + *
+   * 网页链接.
+   * 用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
+   * view、miniprogram类型必须
+   * 
+ */ + private String url; + + /** + *
+   * 调用新增永久素材接口返回的合法media_id.
+   * media_id类型和view_limited类型必须
+   * 
+ */ + @SerializedName("media_id") + private String mediaId; + + /** + *
+   * 小程序的appid.
+   * miniprogram类型必须
+   * 
+ */ + @SerializedName("appid") + private String appId; + + /** + *
+   * 小程序的页面路径.
+   * miniprogram类型必须
+   * 
+ */ + @SerializedName("pagepath") + private String pagePath; + + @SerializedName("sub_button") + private List subButtons = new ArrayList<>(); + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java index 16542dec69..6e8ea66b01 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java @@ -1,29 +1,29 @@ -package me.chanjar.weixin.common.bean.menu; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; - -@Data -public class WxMenuRule implements Serializable { - private static final long serialVersionUID = -4587181819499286670L; - - /** - * 变态的微信接口,反序列化时这里反人类的使用和序列化时不一样的名字. - */ - @SerializedName(value = "tag_id", alternate = "group_id") - private String tagId; - private String sex; - private String country; - private String province; - private String city; - private String clientPlatformType; - private String language; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } -} +package me.chanjar.weixin.common.bean.menu; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; + +import java.io.Serializable; + +@Data +public class WxMenuRule implements Serializable { + private static final long serialVersionUID = -4587181819499286670L; + + /** + * 变态的微信接口,反序列化时这里反人类的使用和序列化时不一样的名字. + */ + @SerializedName(value = "tag_id", alternate = "group_id") + private String tagId; + private String sex; + private String country; + private String province; + private String city; + private String clientPlatformType; + private String language; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java index 25a06f4785..5cee70306b 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java @@ -1,38 +1,38 @@ -package me.chanjar.weixin.common.bean.result; - -import lombok.Builder; -import lombok.Data; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.Serializable; - -/** - * 微信错误码说明,请阅读: 全局返回码说明. - * - * @author Daniel Qian - */ -@Data -@Builder -public class WxError implements Serializable { - - private static final long serialVersionUID = 7869786563361406291L; - - private int errorCode; - - private String errorMsg; - - private String json; - - public static WxError fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxError.class); - } - - @Override - public String toString() { - if (this.json != null) { - return this.json; - } - return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; - } - -} +package me.chanjar.weixin.common.bean.result; + +import lombok.Builder; +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +/** + * 微信错误码说明,请阅读: 全局返回码说明. + * + * @author Daniel Qian + */ +@Data +@Builder +public class WxError implements Serializable { + + private static final long serialVersionUID = 7869786563361406291L; + + private int errorCode; + + private String errorMsg; + + private String json; + + public static WxError fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxError.class); + } + + @Override + public String toString() { + if (this.json != null) { + return this.json; + } + return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java index a50018aaef..7359b80763 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java @@ -1,27 +1,27 @@ -package me.chanjar.weixin.common.bean.result; - -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.Serializable; - -@Data -public class WxMediaUploadResult implements Serializable { - private static final long serialVersionUID = 330834334738622341L; - - private String type; - private String mediaId; - private String thumbMediaId; - private long createdAt; - - public static WxMediaUploadResult fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class); - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.common.bean.result; + +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxMediaUploadResult implements Serializable { + private static final long serialVersionUID = 330834334738622341L; + + private String type; + private String mediaId; + private String thumbMediaId; + private long createdAt; + + public static WxMediaUploadResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class); + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java index 12ce3a4e13..222809f34e 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java @@ -1,106 +1,106 @@ -package me.chanjar.weixin.common.util; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import me.chanjar.weixin.common.annotation.Required; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -/** - *
- * bean操作的一些工具类
- * Created by Binary Wang on 2016-10-21.
- * 
- * - * @author binarywang(Binary Wang) - */ -public class BeanUtils { - private static Logger log = LoggerFactory.getLogger(BeanUtils.class); - - /** - * 检查bean里标记为@Required的field是否为空,为空则抛异常 - * - * @param bean 要检查的bean对象 - * @throws WxErrorException - */ - public static void checkRequiredFields(Object bean) throws WxErrorException { - List requiredFields = Lists.newArrayList(); - - List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); - fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); - for (Field field : fields) { - try { - boolean isAccessible = field.isAccessible(); - field.setAccessible(true); - if (field.isAnnotationPresent(Required.class)) { - // 两种情况,一种是值为null, - // 另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值 - boolean isRequiredMissing = field.get(bean) == null - || (field.get(bean) instanceof String - && StringUtils.isBlank(field.get(bean).toString()) - ); - if (isRequiredMissing) { - requiredFields.add(field.getName()); - } - } - field.setAccessible(isAccessible); - } catch (SecurityException | IllegalArgumentException - | IllegalAccessException e) { - log.error(e.getMessage(), e); - } - } - - if (!requiredFields.isEmpty()) { - String msg = "必填字段 " + requiredFields + " 必须提供值"; - log.debug(msg); - throw new WxErrorException(WxError.builder().errorMsg(msg).build()); - } - } - - /** - * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 - * - * @param bean 包含@XStreamAlias的xml bean对象 - * @return map对象 - */ - public static Map xmlBean2Map(Object bean) { - Map result = Maps.newHashMap(); - List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); - fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); - for (Field field : fields) { - try { - boolean isAccessible = field.isAccessible(); - field.setAccessible(true); - if (field.get(bean) == null) { - field.setAccessible(isAccessible); - continue; - } - - if (field.isAnnotationPresent(XStreamAlias.class)) { - result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); - } else if (!Modifier.isStatic(field.getModifiers())) { - //忽略掉静态成员变量 - result.put(field.getName(), field.get(bean).toString()); - } - - field.setAccessible(isAccessible); - } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { - log.error(e.getMessage(), e); - } - - } - - return result; - } -} +package me.chanjar.weixin.common.util; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import me.chanjar.weixin.common.annotation.Required; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + *
+ * bean操作的一些工具类
+ * Created by Binary Wang on 2016-10-21.
+ * 
+ * + * @author binarywang(Binary Wang) + */ +public class BeanUtils { + private static Logger log = LoggerFactory.getLogger(BeanUtils.class); + + /** + * 检查bean里标记为@Required的field是否为空,为空则抛异常 + * + * @param bean 要检查的bean对象 + * @throws WxErrorException + */ + public static void checkRequiredFields(Object bean) throws WxErrorException { + List requiredFields = Lists.newArrayList(); + + List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); + for (Field field : fields) { + try { + boolean isAccessible = field.isAccessible(); + field.setAccessible(true); + if (field.isAnnotationPresent(Required.class)) { + // 两种情况,一种是值为null, + // 另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值 + boolean isRequiredMissing = field.get(bean) == null + || (field.get(bean) instanceof String + && StringUtils.isBlank(field.get(bean).toString()) + ); + if (isRequiredMissing) { + requiredFields.add(field.getName()); + } + } + field.setAccessible(isAccessible); + } catch (SecurityException | IllegalArgumentException + | IllegalAccessException e) { + log.error(e.getMessage(), e); + } + } + + if (!requiredFields.isEmpty()) { + String msg = "必填字段 " + requiredFields + " 必须提供值"; + log.debug(msg); + throw new WxErrorException(WxError.builder().errorMsg(msg).build()); + } + } + + /** + * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 + * + * @param bean 包含@XStreamAlias的xml bean对象 + * @return map对象 + */ + public static Map xmlBean2Map(Object bean) { + Map result = Maps.newHashMap(); + List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); + for (Field field : fields) { + try { + boolean isAccessible = field.isAccessible(); + field.setAccessible(true); + if (field.get(bean) == null) { + field.setAccessible(isAccessible); + continue; + } + + if (field.isAnnotationPresent(XStreamAlias.class)) { + result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); + } else if (!Modifier.isStatic(field.getModifiers())) { + //忽略掉静态成员变量 + result.put(field.getName(), field.get(bean).toString()); + } + + field.setAccessible(isAccessible); + } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { + log.error(e.getMessage(), e); + } + + } + + return result; + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java index 37efdaaf38..08a59b7140 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java @@ -1,90 +1,90 @@ -package me.chanjar.weixin.common.util.http; - -import jodd.http.HttpResponse; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import okhttp3.Response; -import org.apache.http.Header; -import org.apache.http.client.methods.CloseableHttpResponse; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - *
- * 三种http框架的response代理类,方便提取公共方法
- * Created by Binary Wang on 2017-8-3.
- * 
- * - * @author Binary Wang - */ -public class HttpResponseProxy { - private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\""); - - private CloseableHttpResponse apacheHttpResponse; - private HttpResponse joddHttpResponse; - private Response okHttpResponse; - - public HttpResponseProxy(CloseableHttpResponse apacheHttpResponse) { - this.apacheHttpResponse = apacheHttpResponse; - } - - public HttpResponseProxy(HttpResponse joddHttpResponse) { - this.joddHttpResponse = joddHttpResponse; - } - - public HttpResponseProxy(Response okHttpResponse) { - this.okHttpResponse = okHttpResponse; - } - - public String getFileName() throws WxErrorException { - //由于对象只能由一个构造方法实现,因此三个response对象必定且只有一个不为空 - if (this.apacheHttpResponse != null) { - return this.getFileName(this.apacheHttpResponse); - } - - if (this.joddHttpResponse != null) { - return this.getFileName(this.joddHttpResponse); - } - - if (this.okHttpResponse != null) { - return this.getFileName(this.okHttpResponse); - } - - //cannot happen - return null; - } - - private String getFileName(CloseableHttpResponse response) throws WxErrorException { - Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); - if (contentDispositionHeader == null || contentDispositionHeader.length == 0) { - throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); - } - - return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue()); - } - - private String getFileName(HttpResponse response) throws WxErrorException { - String content = response.header("Content-disposition"); - return this.extractFileNameFromContentString(content); - } - - private String getFileName(Response response) throws WxErrorException { - String content = response.header("Content-disposition"); - return this.extractFileNameFromContentString(content); - } - - private String extractFileNameFromContentString(String content) throws WxErrorException { - if (content == null || content.length() == 0) { - throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); - } - - Matcher m = PATTERN.matcher(content); - if (m.matches()) { - return m.group(1); - } - - throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); - } - -} +package me.chanjar.weixin.common.util.http; + +import jodd.http.HttpResponse; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import okhttp3.Response; +import org.apache.http.Header; +import org.apache.http.client.methods.CloseableHttpResponse; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *
+ * 三种http框架的response代理类,方便提取公共方法
+ * Created by Binary Wang on 2017-8-3.
+ * 
+ * + * @author Binary Wang + */ +public class HttpResponseProxy { + private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\""); + + private CloseableHttpResponse apacheHttpResponse; + private HttpResponse joddHttpResponse; + private Response okHttpResponse; + + public HttpResponseProxy(CloseableHttpResponse apacheHttpResponse) { + this.apacheHttpResponse = apacheHttpResponse; + } + + public HttpResponseProxy(HttpResponse joddHttpResponse) { + this.joddHttpResponse = joddHttpResponse; + } + + public HttpResponseProxy(Response okHttpResponse) { + this.okHttpResponse = okHttpResponse; + } + + public String getFileName() throws WxErrorException { + //由于对象只能由一个构造方法实现,因此三个response对象必定且只有一个不为空 + if (this.apacheHttpResponse != null) { + return this.getFileName(this.apacheHttpResponse); + } + + if (this.joddHttpResponse != null) { + return this.getFileName(this.joddHttpResponse); + } + + if (this.okHttpResponse != null) { + return this.getFileName(this.okHttpResponse); + } + + //cannot happen + return null; + } + + private String getFileName(CloseableHttpResponse response) throws WxErrorException { + Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); + if (contentDispositionHeader == null || contentDispositionHeader.length == 0) { + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); + } + + return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue()); + } + + private String getFileName(HttpResponse response) throws WxErrorException { + String content = response.header("Content-disposition"); + return this.extractFileNameFromContentString(content); + } + + private String getFileName(Response response) throws WxErrorException { + String content = response.header("Content-disposition"); + return this.extractFileNameFromContentString(content); + } + + private String extractFileNameFromContentString(String content) throws WxErrorException { + if (content == null || content.length() == 0) { + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); + } + + Matcher m = PATTERN.matcher(content); + if (m.matches()) { + return m.group(1); + } + + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java index 1a8a292b9f..811a631401 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java @@ -1,59 +1,59 @@ -package me.chanjar.weixin.common.util.http.apache; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; -import org.apache.http.Consts; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.IOException; - -/** - * Created by ecoolper on 2017/5/4. - */ -public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor { - - public ApacheSimplePostRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public String execute(String uri, String postEntity) throws WxErrorException, IOException { - HttpPost httpPost = new HttpPost(uri); - if (requestHttp.getRequestHttpProxy() != null) { - RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); - httpPost.setConfig(config); - } - - if (postEntity != null) { - StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); - httpPost.setEntity(entity); - } - - try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - if (responseContent.isEmpty()) { - throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); - } - - if (responseContent.startsWith("")) { - //xml格式输出直接返回 - return responseContent; - } - - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - return responseContent; - } finally { - httpPost.releaseConnection(); - } - } -} +package me.chanjar.weixin.common.util.http.apache; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import org.apache.http.Consts; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.IOException; + +/** + * Created by ecoolper on 2017/5/4. + */ +public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor { + + public ApacheSimplePostRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public String execute(String uri, String postEntity) throws WxErrorException, IOException { + HttpPost httpPost = new HttpPost(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(config); + } + + if (postEntity != null) { + StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); + httpPost.setEntity(entity); + } + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + if (responseContent.isEmpty()) { + throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); + } + + if (responseContent.startsWith("")) { + //xml格式输出直接返回 + return responseContent; + } + + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + return responseContent; + } finally { + httpPost.releaseConnection(); + } + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java index 57207f1b3e..d3456a55f1 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java @@ -1,58 +1,58 @@ -package me.chanjar.weixin.common.util.http.jodd; - -import jodd.http.HttpConnectionProvider; -import jodd.http.HttpRequest; -import jodd.http.HttpResponse; -import jodd.http.ProxyInfo; -import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; - -import java.io.IOException; - -/** - * Created by ecoolper on 2017/5/4. - */ -public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor { - - public JoddHttpSimplePostRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public String execute(String uri, String postEntity) throws WxErrorException, IOException { - HttpConnectionProvider provider = requestHttp.getRequestHttpClient(); - ProxyInfo proxyInfo = requestHttp.getRequestHttpProxy(); - - HttpRequest request = HttpRequest.post(uri); - if (proxyInfo != null) { - provider.useProxy(proxyInfo); - } - request.withConnectionProvider(provider); - if (postEntity != null) { - request.bodyText(postEntity); - } - HttpResponse response = request.send(); - response.charset(StringPool.UTF_8); - - String responseContent = response.bodyText(); - if (responseContent.isEmpty()) { - throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容") - .build()); - } - - if (responseContent.startsWith("")) { - //xml格式输出直接返回 - return responseContent; - } - - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - return responseContent; - } - -} +package me.chanjar.weixin.common.util.http.jodd; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import jodd.util.StringPool; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; + +import java.io.IOException; + +/** + * Created by ecoolper on 2017/5/4. + */ +public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor { + + public JoddHttpSimplePostRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public String execute(String uri, String postEntity) throws WxErrorException, IOException { + HttpConnectionProvider provider = requestHttp.getRequestHttpClient(); + ProxyInfo proxyInfo = requestHttp.getRequestHttpProxy(); + + HttpRequest request = HttpRequest.post(uri); + if (proxyInfo != null) { + provider.useProxy(proxyInfo); + } + request.withConnectionProvider(provider); + if (postEntity != null) { + request.bodyText(postEntity); + } + HttpResponse response = request.send(); + response.charset(StringPool.UTF_8); + + String responseContent = response.bodyText(); + if (responseContent.isEmpty()) { + throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容") + .build()); + } + + if (responseContent.startsWith("")) { + //xml格式输出直接返回 + return responseContent; + } + + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + return responseContent; + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java index abd0da6052..a6363be7e3 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java @@ -1,39 +1,39 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ -package me.chanjar.weixin.common.util.json; - -import com.google.gson.*; -import me.chanjar.weixin.common.bean.result.WxError; - -import java.lang.reflect.Type; - -/** - * @author Daniel Qian. - */ -public class WxErrorAdapter implements JsonDeserializer { - - @Override - public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - WxError.WxErrorBuilder errorBuilder = WxError.builder(); - JsonObject wxErrorJsonObject = json.getAsJsonObject(); - - if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) { - errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode"))); - } - if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) { - errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg"))); - } - - errorBuilder.json(json.toString()); - - return errorBuilder.build(); - } - -} +/* + * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. + * + * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended + * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction + * arose from modification of the original source, or other redistribution of this source + * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. + */ +package me.chanjar.weixin.common.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.bean.result.WxError; + +import java.lang.reflect.Type; + +/** + * @author Daniel Qian. + */ +public class WxErrorAdapter implements JsonDeserializer { + + @Override + public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + WxError.WxErrorBuilder errorBuilder = WxError.builder(); + JsonObject wxErrorJsonObject = json.getAsJsonObject(); + + if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) { + errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode"))); + } + if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) { + errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg"))); + } + + errorBuilder.json(json.toString()); + + return errorBuilder.build(); + } + +} diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java index 1c05ea731e..f9d57d3f28 100644 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java @@ -1,36 +1,36 @@ -package me.chanjar.weixin.common.bean; - -import me.chanjar.weixin.common.bean.result.WxError; -import org.testng.*; -import org.testng.annotations.*; - -@Test -public class WxErrorTest { - - public void testFromJson() { - String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; - WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 40003); - Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); - - } - - public void testFromBadJson1() { - - String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; - WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 40003); - Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); - - } - - public void testFromBadJson2() { - - String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; - WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 0); - Assert.assertEquals(wxError.getErrorMsg(), null); - - } - -} +package me.chanjar.weixin.common.bean; + +import me.chanjar.weixin.common.bean.result.WxError; +import org.testng.*; +import org.testng.annotations.*; + +@Test +public class WxErrorTest { + + public void testFromJson() { + String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; + WxError wxError = WxError.fromJson(json); + Assert.assertTrue(wxError.getErrorCode() == 40003); + Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); + + } + + public void testFromBadJson1() { + + String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; + WxError wxError = WxError.fromJson(json); + Assert.assertTrue(wxError.getErrorCode() == 40003); + Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); + + } + + public void testFromBadJson2() { + + String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; + WxError wxError = WxError.fromJson(json); + Assert.assertTrue(wxError.getErrorCode() == 0); + Assert.assertEquals(wxError.getErrorMsg(), null); + + } + +} diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 96dba9c9d6..776356b94c 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -1,88 +1,88 @@ - - - 4.0.0 - - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - - - weixin-java-cp - WeiXin Java Tools - CP - 微信企业号Java SDK - - - - com.github.binarywang - weixin-java-common - ${project.version} - - - org.jodd - jodd-http - provided - - - com.squareup.okhttp3 - okhttp - provided - - - redis.clients - jedis - - - org.slf4j - slf4j-api - - - - org.testng - testng - test - - - org.mockito - mockito-all - test - - - com.google.inject - guice - test - - - org.eclipse.jetty - jetty-server - test - - - org.eclipse.jetty - jetty-servlet - test - - - ch.qos.logback - logback-classic - test - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - src/test/resources/testng.xml - - - - - - - + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + + + weixin-java-cp + WeiXin Java Tools - CP + 微信企业号Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + redis.clients + jedis + + + org.slf4j + slf4j-api + + + + org.testng + testng + test + + + org.mockito + mockito-all + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + ch.qos.logback + logback-classic + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java index af9219cfe8..b5e2f6e533 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java @@ -1,100 +1,100 @@ -package me.chanjar.weixin.cp.api.impl; - -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.HttpType; -import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import okhttp3.*; - -import java.io.IOException; - -public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl { - protected OkHttpClient httpClient; - protected OkHttpProxyInfo httpProxy; - - - @Override - public OkHttpClient getRequestHttpClient() { - return httpClient; - } - - @Override - public OkHttpProxyInfo getRequestHttpProxy() { - return httpProxy; - } - - @Override - public HttpType getRequestType() { - return HttpType.OK_HTTP; - } - - @Override - public String getAccessToken(boolean forceRefresh) throws WxErrorException { - this.log.debug("WxCpServiceOkHttpImpl is running"); - if (this.configStorage.isAccessTokenExpired() || forceRefresh) { - synchronized (this.globalAccessTokenRefreshLock) { - if (this.configStorage.isAccessTokenExpired()) { - String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" - + "&corpid=" + this.configStorage.getCorpId() - + "&corpsecret=" + this.configStorage.getCorpSecret(); - //得到httpClient - OkHttpClient client = getRequestHttpClient(); - //请求的request - Request request = new Request.Builder().url(url).get().build(); - String resultContent = null; - try { - Response response = client.newCall(request).execute(); - resultContent = response.body().string(); - } catch (IOException e) { - this.log.error(e.getMessage(), e); - } - - WxError error = WxError.fromJson(resultContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); - this.configStorage.updateAccessToken(accessToken.getAccessToken(), - accessToken.getExpiresIn()); - } - } - } - return this.configStorage.getAccessToken(); - } - - @Override - public void initHttp() { - this.log.debug("WxCpServiceOkHttpImpl initHttp"); - //设置代理 - if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { - httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(), - configStorage.getHttpProxyPort(), - configStorage.getHttpProxyUsername(), - configStorage.getHttpProxyPassword()); - } - - OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); - if (httpProxy != null) { - clientBuilder.proxy(getRequestHttpProxy().getProxy()); - - //设置授权 - clientBuilder.authenticator(new Authenticator() { - @Override - public Request authenticate(Route route, Response response) throws IOException { - String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword()); - return response.request().newBuilder() - .header("Authorization", credential) - .build(); - } - }); - } - httpClient = clientBuilder.build(); - } - - @Override - public WxCpConfigStorage getWxCpConfigStorage() { - return this.configStorage; - } -} +package me.chanjar.weixin.cp.api.impl; + +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.HttpType; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.cp.config.WxCpConfigStorage; +import okhttp3.*; + +import java.io.IOException; + +public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl { + protected OkHttpClient httpClient; + protected OkHttpProxyInfo httpProxy; + + + @Override + public OkHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public OkHttpProxyInfo getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpType getRequestType() { + return HttpType.OK_HTTP; + } + + @Override + public String getAccessToken(boolean forceRefresh) throws WxErrorException { + this.log.debug("WxCpServiceOkHttpImpl is running"); + if (this.configStorage.isAccessTokenExpired() || forceRefresh) { + synchronized (this.globalAccessTokenRefreshLock) { + if (this.configStorage.isAccessTokenExpired()) { + String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" + + "&corpid=" + this.configStorage.getCorpId() + + "&corpsecret=" + this.configStorage.getCorpSecret(); + //得到httpClient + OkHttpClient client = getRequestHttpClient(); + //请求的request + Request request = new Request.Builder().url(url).get().build(); + String resultContent = null; + try { + Response response = client.newCall(request).execute(); + resultContent = response.body().string(); + } catch (IOException e) { + this.log.error(e.getMessage(), e); + } + + WxError error = WxError.fromJson(resultContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); + this.configStorage.updateAccessToken(accessToken.getAccessToken(), + accessToken.getExpiresIn()); + } + } + } + return this.configStorage.getAccessToken(); + } + + @Override + public void initHttp() { + this.log.debug("WxCpServiceOkHttpImpl initHttp"); + //设置代理 + if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { + httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(), + configStorage.getHttpProxyPort(), + configStorage.getHttpProxyUsername(), + configStorage.getHttpProxyPassword()); + } + + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + if (httpProxy != null) { + clientBuilder.proxy(getRequestHttpProxy().getProxy()); + + //设置授权 + clientBuilder.authenticator(new Authenticator() { + @Override + public Request authenticate(Route route, Response response) throws IOException { + String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword()); + return response.request().newBuilder() + .header("Authorization", credential) + .build(); + } + }); + } + httpClient = clientBuilder.build(); + } + + @Override + public WxCpConfigStorage getWxCpConfigStorage() { + return this.configStorage; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java index 2890ce61eb..5ff90f7d1c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java @@ -1,30 +1,30 @@ -package me.chanjar.weixin.cp.bean; - -import lombok.Data; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - -import java.io.Serializable; - -/** - * 微信部门. - * - * @author Daniel Qian - */ -@Data -public class WxCpDepart implements Serializable { - - private static final long serialVersionUID = -5028321625140879571L; - private Integer id; - private String name; - private Integer parentId; - private Long order; - - public static WxCpDepart fromJson(String json) { - return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); - } - - public String toJson() { - return WxCpGsonBuilder.create().toJson(this); - } - -} +package me.chanjar.weixin.cp.bean; + +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 微信部门. + * + * @author Daniel Qian + */ +@Data +public class WxCpDepart implements Serializable { + + private static final long serialVersionUID = -5028321625140879571L; + private Integer id; + private String name; + private Integer parentId; + private Long order; + + public static WxCpDepart fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java index 403e9dc365..8ea4fbf8a7 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java @@ -1,119 +1,119 @@ -package me.chanjar.weixin.cp.bean; - -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.bean.article.MpnewsArticle; -import me.chanjar.weixin.cp.bean.article.NewArticle; -import me.chanjar.weixin.cp.bean.messagebuilder.*; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * 消息. - * - * @author Daniel Qian - */ -@Data -public class WxCpMessage implements Serializable { - private static final long serialVersionUID = -2082278303476631708L; - - private String toUser; - private String toParty; - private String toTag; - private Integer agentId; - private String msgType; - private String content; - private String mediaId; - private String thumbMediaId; - private String title; - private String description; - private String musicUrl; - private String hqMusicUrl; - private String safe; - private String url; - private List articles = new ArrayList<>(); - private List mpnewsArticles = new ArrayList<>(); - - /** - * 获得文本消息builder. - */ - public static TextBuilder TEXT() { - return new TextBuilder(); - } - - /** - * 获得文本卡片消息builder. - */ - public static TextCardBuilder TEXTCARD() { - return new TextCardBuilder(); - } - - /** - * 获得图片消息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(); - } - - /** - * 获得mpnews图文消息builder. - */ - public static MpnewsBuilder MPNEWS() { - return new MpnewsBuilder(); - } - - /** - * 获得文件消息builder. - */ - public static FileBuilder FILE() { - return new FileBuilder(); - } - - - /** - *
-   * 请使用
-   * {@link WxConsts.KefuMsgType#TEXT}
-   * {@link WxConsts.KefuMsgType#IMAGE}
-   * {@link WxConsts.KefuMsgType#VOICE}
-   * {@link WxConsts.KefuMsgType#MUSIC}
-   * {@link WxConsts.KefuMsgType#VIDEO}
-   * {@link WxConsts.KefuMsgType#NEWS}
-   * {@link WxConsts.KefuMsgType#MPNEWS}
-   * 
- * - * @param msgType 消息类型 - */ - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - public String toJson() { - return WxCpGsonBuilder.INSTANCE.create().toJson(this); - } - -} +package me.chanjar.weixin.cp.bean; + +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.cp.bean.article.MpnewsArticle; +import me.chanjar.weixin.cp.bean.article.NewArticle; +import me.chanjar.weixin.cp.bean.messagebuilder.*; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 消息. + * + * @author Daniel Qian + */ +@Data +public class WxCpMessage implements Serializable { + private static final long serialVersionUID = -2082278303476631708L; + + private String toUser; + private String toParty; + private String toTag; + private Integer agentId; + private String msgType; + private String content; + private String mediaId; + private String thumbMediaId; + private String title; + private String description; + private String musicUrl; + private String hqMusicUrl; + private String safe; + private String url; + private List articles = new ArrayList<>(); + private List mpnewsArticles = new ArrayList<>(); + + /** + * 获得文本消息builder. + */ + public static TextBuilder TEXT() { + return new TextBuilder(); + } + + /** + * 获得文本卡片消息builder. + */ + public static TextCardBuilder TEXTCARD() { + return new TextCardBuilder(); + } + + /** + * 获得图片消息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(); + } + + /** + * 获得mpnews图文消息builder. + */ + public static MpnewsBuilder MPNEWS() { + return new MpnewsBuilder(); + } + + /** + * 获得文件消息builder. + */ + public static FileBuilder FILE() { + return new FileBuilder(); + } + + + /** + *
+   * 请使用
+   * {@link WxConsts.KefuMsgType#TEXT}
+   * {@link WxConsts.KefuMsgType#IMAGE}
+   * {@link WxConsts.KefuMsgType#VOICE}
+   * {@link WxConsts.KefuMsgType#MUSIC}
+   * {@link WxConsts.KefuMsgType#VIDEO}
+   * {@link WxConsts.KefuMsgType#NEWS}
+   * {@link WxConsts.KefuMsgType#MPNEWS}
+   * 
+ * + * @param msgType 消息类型 + */ + public void setMsgType(String msgType) { + this.msgType = msgType; + } + + public String toJson() { + return WxCpGsonBuilder.INSTANCE.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java index e54a01eccd..d8159c0fd8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java @@ -1,68 +1,68 @@ -package me.chanjar.weixin.cp.bean; - -import com.google.common.base.Splitter; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import org.apache.commons.lang3.StringUtils; - -import java.io.Serializable; -import java.util.Collections; -import java.util.List; - -/** - * 消息发送结果对象类. - * Created by Binary Wang on 2017-6-22. - * - * @author Binary Wang - */ -@Data -public class WxCpMessageSendResult implements Serializable { - private static final long serialVersionUID = 916455987193190004L; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public static WxCpMessageSendResult fromJson(String json) { - return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpMessageSendResult.class); - } - - @SerializedName("errcode") - private Integer errCode; - - @SerializedName("errmsg") - private String errMsg; - - @SerializedName("invaliduser") - private String invalidUser; - - @SerializedName("invalidparty") - private String invalidParty; - - @SerializedName("invalidtag") - private String invalidTag; - - - public List getInvalidUserList() { - return this.content2List(this.invalidUser); - } - - private List content2List(String content) { - if (StringUtils.isBlank(content)) { - return Collections.emptyList(); - } - - return Splitter.on("|").splitToList(content); - } - - public List getInvalidPartyList() { - return this.content2List(this.invalidParty); - } - - public List getInvalidTagList() { - return this.content2List(this.invalidTag); - } -} +package me.chanjar.weixin.cp.bean; + +import com.google.common.base.Splitter; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +/** + * 消息发送结果对象类. + * Created by Binary Wang on 2017-6-22. + * + * @author Binary Wang + */ +@Data +public class WxCpMessageSendResult implements Serializable { + private static final long serialVersionUID = 916455987193190004L; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + public static WxCpMessageSendResult fromJson(String json) { + return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpMessageSendResult.class); + } + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("invaliduser") + private String invalidUser; + + @SerializedName("invalidparty") + private String invalidParty; + + @SerializedName("invalidtag") + private String invalidTag; + + + public List getInvalidUserList() { + return this.content2List(this.invalidUser); + } + + private List content2List(String content) { + if (StringUtils.isBlank(content)) { + return Collections.emptyList(); + } + + return Splitter.on("|").splitToList(content); + } + + public List getInvalidPartyList() { + return this.content2List(this.invalidParty); + } + + public List getInvalidTagList() { + return this.content2List(this.invalidTag); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java index 360ddd28be..7724948160 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java @@ -1,32 +1,32 @@ -package me.chanjar.weixin.cp.bean; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - -import java.io.Serializable; - -/** - * Created by Daniel Qian. - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class WxCpTag implements Serializable { - private static final long serialVersionUID = -7243320279646928402L; - - private String id; - - private String name; - - - public static WxCpTag fromJson(String json) { - return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); - } - - public String toJson() { - return WxCpGsonBuilder.create().toJson(this); - } - -} +package me.chanjar.weixin.cp.bean; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * Created by Daniel Qian. + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class WxCpTag implements Serializable { + private static final long serialVersionUID = -7243320279646928402L; + + private String id; + + private String name; + + + public static WxCpTag fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java index 3d89c073fc..5179fc7f0c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java @@ -1,57 +1,57 @@ -package me.chanjar.weixin.cp.bean; - -import com.google.common.base.Splitter; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import org.apache.commons.lang3.StringUtils; - -import java.io.Serializable; -import java.util.Collections; -import java.util.List; - -/** - * 为标签添加或移除用户结果对象类. - * Created by Binary Wang on 2017-6-22. - * - * @author Binary Wang - */ -@Data -public class WxCpTagAddOrRemoveUsersResult implements Serializable { - private static final long serialVersionUID = 1420065684270213578L; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public static WxCpTagAddOrRemoveUsersResult fromJson(String json) { - return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpTagAddOrRemoveUsersResult.class); - } - - @SerializedName("errcode") - private Integer errCode; - - @SerializedName("errmsg") - private String errMsg; - - @SerializedName("invalidlist") - private String invalidUsers; - - @SerializedName("invalidparty") - private String[] invalidParty; - - public List getInvalidUserList() { - return this.content2List(this.invalidUsers); - } - - private List content2List(String content) { - if (StringUtils.isBlank(content)) { - return Collections.emptyList(); - } - - return Splitter.on("|").splitToList(content); - } - -} +package me.chanjar.weixin.cp.bean; + +import com.google.common.base.Splitter; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +/** + * 为标签添加或移除用户结果对象类. + * Created by Binary Wang on 2017-6-22. + * + * @author Binary Wang + */ +@Data +public class WxCpTagAddOrRemoveUsersResult implements Serializable { + private static final long serialVersionUID = 1420065684270213578L; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + public static WxCpTagAddOrRemoveUsersResult fromJson(String json) { + return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpTagAddOrRemoveUsersResult.class); + } + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("invalidlist") + private String invalidUsers; + + @SerializedName("invalidparty") + private String[] invalidParty; + + public List getInvalidUserList() { + return this.content2List(this.invalidUsers); + } + + private List content2List(String content) { + if (StringUtils.isBlank(content)) { + return Collections.emptyList(); + } + + return Splitter.on("|").splitToList(content); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java index 0a3aaeb7a7..b904b5e12b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java @@ -1,86 +1,86 @@ -package me.chanjar.weixin.cp.bean; - -import lombok.AllArgsConstructor; -import lombok.Data; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * 微信用户信息. - * - * @author Daniel Qian - */ -@Data -public class WxCpUser implements Serializable { - public enum Gender { - MALE("男", "1"), - FEMAIL("女", "2"); - - private String genderName; - private String code; - - Gender(String genderName, String code) { - this.genderName = genderName; - this.code = code; - } - - public String getGenderName() { - return this.genderName; - } - - public String getCode() { - return this.code; - } - - public static Gender fromCode(String code) { - if ("1".equals(code)) { - return Gender.MALE; - } - if ("2".equals(code)) { - return Gender.FEMAIL; - } - - return null; - } - } - - private static final long serialVersionUID = -5696099236344075582L; - private String userId; - private String name; - private Integer[] departIds; - private String position; - private String mobile; - private Gender gender; - private String email; - private String avatar; - private Integer status; - private Integer enable; - private Integer isLeader; - private final List extAttrs = new ArrayList<>(); - private Integer hideMobile; - private String englishName; - private String telephone; - - public void addExtAttr(String name, String value) { - this.extAttrs.add(new Attr(name, value)); - } - - public static WxCpUser fromJson(String json) { - return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); - } - - public String toJson() { - return WxCpGsonBuilder.INSTANCE.create().toJson(this); - } - - @Data - @AllArgsConstructor - public static class Attr { - private String name; - private String value; - } - -} +package me.chanjar.weixin.cp.bean; + +import lombok.AllArgsConstructor; +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 微信用户信息. + * + * @author Daniel Qian + */ +@Data +public class WxCpUser implements Serializable { + public enum Gender { + MALE("男", "1"), + FEMAIL("女", "2"); + + private String genderName; + private String code; + + Gender(String genderName, String code) { + this.genderName = genderName; + this.code = code; + } + + public String getGenderName() { + return this.genderName; + } + + public String getCode() { + return this.code; + } + + public static Gender fromCode(String code) { + if ("1".equals(code)) { + return Gender.MALE; + } + if ("2".equals(code)) { + return Gender.FEMAIL; + } + + return null; + } + } + + private static final long serialVersionUID = -5696099236344075582L; + private String userId; + private String name; + private Integer[] departIds; + private String position; + private String mobile; + private Gender gender; + private String email; + private String avatar; + private Integer status; + private Integer enable; + private Integer isLeader; + private final List extAttrs = new ArrayList<>(); + private Integer hideMobile; + private String englishName; + private String telephone; + + public void addExtAttr(String name, String value) { + this.extAttrs.add(new Attr(name, value)); + } + + public static WxCpUser fromJson(String json) { + return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); + } + + public String toJson() { + return WxCpGsonBuilder.INSTANCE.create().toJson(this); + } + + @Data + @AllArgsConstructor + public static class Attr { + private String name; + private String value; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java index 785884a174..a66b80af5c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java @@ -1,302 +1,302 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; -import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; -import me.chanjar.weixin.cp.util.xml.XStreamTransformer; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - *
- * 微信推送过来的消息,也是同步回复给用户的消息,xml格式
- * 相关字段的解释看微信开发者文档:
- * http://mp.weixin.qq.com/wiki/index.php?title=接收普通消息
- * http://mp.weixin.qq.com/wiki/index.php?title=接收事件推送
- * http://mp.weixin.qq.com/wiki/index.php?title=接收语音识别结果
- * 
- * - * @author Daniel Qian - */ -@XStreamAlias("xml") -@Data -public class WxCpXmlMessage implements Serializable { - private static final long serialVersionUID = -1042994982179476410L; - - /////////////////////// - // 以下都是微信推送过来的消息的xml的element所对应的属性 - /////////////////////// - - @XStreamAlias("AgentID") - private Integer agentId; - - @XStreamAlias("ToUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - private String toUserName; - - @XStreamAlias("FromUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - private String fromUserName; - - @XStreamAlias("CreateTime") - private Long createTime; - - @XStreamAlias("MsgType") - @XStreamConverter(value = XStreamCDataConverter.class) - private String msgType; - - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - @XStreamAlias("MsgId") - private Long msgId; - - @XStreamAlias("PicUrl") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picUrl; - - @XStreamAlias("MediaId") - @XStreamConverter(value = XStreamCDataConverter.class) - private String mediaId; - - @XStreamAlias("Format") - @XStreamConverter(value = XStreamCDataConverter.class) - private String format; - - @XStreamAlias("ThumbMediaId") - @XStreamConverter(value = XStreamCDataConverter.class) - private String thumbMediaId; - - @XStreamAlias("Location_X") - private Double locationX; - - @XStreamAlias("Location_Y") - private Double locationY; - - @XStreamAlias("Scale") - private Double scale; - - @XStreamAlias("Label") - @XStreamConverter(value = XStreamCDataConverter.class) - private String label; - - @XStreamAlias("Title") - @XStreamConverter(value = XStreamCDataConverter.class) - private String title; - - @XStreamAlias("Description") - @XStreamConverter(value = XStreamCDataConverter.class) - private String description; - - @XStreamAlias("Url") - @XStreamConverter(value = XStreamCDataConverter.class) - private String url; - - @XStreamAlias("Event") - @XStreamConverter(value = XStreamCDataConverter.class) - private String event; - - @XStreamAlias("EventKey") - @XStreamConverter(value = XStreamCDataConverter.class) - private String eventKey; - - @XStreamAlias("Ticket") - @XStreamConverter(value = XStreamCDataConverter.class) - private String ticket; - - @XStreamAlias("Latitude") - private Double latitude; - - @XStreamAlias("Longitude") - private Double longitude; - - @XStreamAlias("Precision") - private Double precision; - - @XStreamAlias("Recognition") - @XStreamConverter(value = XStreamCDataConverter.class) - private String recognition; - - /////////////////////////////////////// - // 群发消息返回的结果 - /////////////////////////////////////// - /** - * 群发的结果. - */ - @XStreamAlias("Status") - @XStreamConverter(value = XStreamCDataConverter.class) - private String status; - /** - * group_id下粉丝数;或者openid_list中的粉丝数. - */ - @XStreamAlias("TotalCount") - private Integer totalCount; - /** - * 过滤. - * (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount - */ - @XStreamAlias("FilterCount") - private Integer filterCount; - /** - * 发送成功的粉丝数. - */ - @XStreamAlias("SentCount") - private Integer sentCount; - /** - * 发送失败的粉丝数. - */ - @XStreamAlias("ErrorCount") - private Integer errorCount; - - @XStreamAlias("ScanCodeInfo") - private ScanCodeInfo scanCodeInfo = new ScanCodeInfo(); - - @XStreamAlias("SendPicsInfo") - private SendPicsInfo sendPicsInfo = new SendPicsInfo(); - - @XStreamAlias("SendLocationInfo") - private SendLocationInfo sendLocationInfo = new SendLocationInfo(); - - protected static WxCpXmlMessage fromXml(String xml) { - //修改微信变态的消息内容格式,方便解析 - xml = xml.replace("
", ""); - return XStreamTransformer.fromXml(WxCpXmlMessage.class, xml); - } - - protected static WxCpXmlMessage fromXml(InputStream is) { - return XStreamTransformer.fromXml(WxCpXmlMessage.class, is); - } - - /** - * 从加密字符串转换. - */ - 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); - } - } - - /** - *
-   * 当接受用户消息时,可能会获得以下值:
-   * {@link WxConsts.XmlMsgType#TEXT}
-   * {@link WxConsts.XmlMsgType#IMAGE}
-   * {@link WxConsts.XmlMsgType#VOICE}
-   * {@link WxConsts.XmlMsgType#VIDEO}
-   * {@link WxConsts.XmlMsgType#LOCATION}
-   * {@link WxConsts.XmlMsgType#LINK}
-   * {@link WxConsts.XmlMsgType#EVENT}
-   * 
- */ - public String getMsgType() { - return this.msgType; - } - - /** - *
-   * 当发送消息的时候使用:
-   * {@link WxConsts.XmlMsgType#TEXT}
-   * {@link WxConsts.XmlMsgType#IMAGE}
-   * {@link WxConsts.XmlMsgType#VOICE}
-   * {@link WxConsts.XmlMsgType#VIDEO}
-   * {@link WxConsts.XmlMsgType#NEWS}
-   * 
- */ - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - @Data - @XStreamAlias("ScanCodeInfo") - public static class ScanCodeInfo { - - /** - * 扫描类型,一般是qrcode. - */ - @XStreamAlias("ScanType") - @XStreamConverter(value = XStreamCDataConverter.class) - private String scanType; - - /** - * 扫描结果,即二维码对应的字符串信息. - */ - @XStreamAlias("ScanResult") - @XStreamConverter(value = XStreamCDataConverter.class) - private String scanResult; - } - - @Data - @XStreamAlias("SendPicsInfo") - public static class SendPicsInfo { - @XStreamAlias("PicList") - protected final List picList = new ArrayList<>(); - - @XStreamAlias("Count") - private Long count; - - @XStreamAlias("item") - @Data - public static class Item { - @XStreamAlias("PicMd5Sum") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picMd5Sum; - } - } - - @Data - @XStreamAlias("SendLocationInfo") - public static class SendLocationInfo { - - @XStreamAlias("Location_X") - @XStreamConverter(value = XStreamCDataConverter.class) - private String locationX; - - @XStreamAlias("Location_Y") - @XStreamConverter(value = XStreamCDataConverter.class) - private String locationY; - - @XStreamAlias("Scale") - @XStreamConverter(value = XStreamCDataConverter.class) - private String scale; - - @XStreamAlias("Label") - @XStreamConverter(value = XStreamCDataConverter.class) - private String label; - - @XStreamAlias("Poiname") - @XStreamConverter(value = XStreamCDataConverter.class) - private String poiName; - - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import me.chanjar.weixin.cp.config.WxCpConfigStorage; +import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; +import me.chanjar.weixin.cp.util.xml.XStreamTransformer; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + *
+ * 微信推送过来的消息,也是同步回复给用户的消息,xml格式
+ * 相关字段的解释看微信开发者文档:
+ * http://mp.weixin.qq.com/wiki/index.php?title=接收普通消息
+ * http://mp.weixin.qq.com/wiki/index.php?title=接收事件推送
+ * http://mp.weixin.qq.com/wiki/index.php?title=接收语音识别结果
+ * 
+ * + * @author Daniel Qian + */ +@XStreamAlias("xml") +@Data +public class WxCpXmlMessage implements Serializable { + private static final long serialVersionUID = -1042994982179476410L; + + /////////////////////// + // 以下都是微信推送过来的消息的xml的element所对应的属性 + /////////////////////// + + @XStreamAlias("AgentID") + private Integer agentId; + + @XStreamAlias("ToUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String toUserName; + + @XStreamAlias("FromUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String fromUserName; + + @XStreamAlias("CreateTime") + private Long createTime; + + @XStreamAlias("MsgType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String msgType; + + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + @XStreamAlias("MsgId") + private Long msgId; + + @XStreamAlias("PicUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picUrl; + + @XStreamAlias("MediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mediaId; + + @XStreamAlias("Format") + @XStreamConverter(value = XStreamCDataConverter.class) + private String format; + + @XStreamAlias("ThumbMediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String thumbMediaId; + + @XStreamAlias("Location_X") + private Double locationX; + + @XStreamAlias("Location_Y") + private Double locationY; + + @XStreamAlias("Scale") + private Double scale; + + @XStreamAlias("Label") + @XStreamConverter(value = XStreamCDataConverter.class) + private String label; + + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @XStreamAlias("Description") + @XStreamConverter(value = XStreamCDataConverter.class) + private String description; + + @XStreamAlias("Url") + @XStreamConverter(value = XStreamCDataConverter.class) + private String url; + + @XStreamAlias("Event") + @XStreamConverter(value = XStreamCDataConverter.class) + private String event; + + @XStreamAlias("EventKey") + @XStreamConverter(value = XStreamCDataConverter.class) + private String eventKey; + + @XStreamAlias("Ticket") + @XStreamConverter(value = XStreamCDataConverter.class) + private String ticket; + + @XStreamAlias("Latitude") + private Double latitude; + + @XStreamAlias("Longitude") + private Double longitude; + + @XStreamAlias("Precision") + private Double precision; + + @XStreamAlias("Recognition") + @XStreamConverter(value = XStreamCDataConverter.class) + private String recognition; + + /////////////////////////////////////// + // 群发消息返回的结果 + /////////////////////////////////////// + /** + * 群发的结果. + */ + @XStreamAlias("Status") + @XStreamConverter(value = XStreamCDataConverter.class) + private String status; + /** + * group_id下粉丝数;或者openid_list中的粉丝数. + */ + @XStreamAlias("TotalCount") + private Integer totalCount; + /** + * 过滤. + * (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount + */ + @XStreamAlias("FilterCount") + private Integer filterCount; + /** + * 发送成功的粉丝数. + */ + @XStreamAlias("SentCount") + private Integer sentCount; + /** + * 发送失败的粉丝数. + */ + @XStreamAlias("ErrorCount") + private Integer errorCount; + + @XStreamAlias("ScanCodeInfo") + private ScanCodeInfo scanCodeInfo = new ScanCodeInfo(); + + @XStreamAlias("SendPicsInfo") + private SendPicsInfo sendPicsInfo = new SendPicsInfo(); + + @XStreamAlias("SendLocationInfo") + private SendLocationInfo sendLocationInfo = new SendLocationInfo(); + + protected static WxCpXmlMessage fromXml(String xml) { + //修改微信变态的消息内容格式,方便解析 + xml = xml.replace("
", ""); + return XStreamTransformer.fromXml(WxCpXmlMessage.class, xml); + } + + protected static WxCpXmlMessage fromXml(InputStream is) { + return XStreamTransformer.fromXml(WxCpXmlMessage.class, is); + } + + /** + * 从加密字符串转换. + */ + 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); + } + } + + /** + *
+   * 当接受用户消息时,可能会获得以下值:
+   * {@link WxConsts.XmlMsgType#TEXT}
+   * {@link WxConsts.XmlMsgType#IMAGE}
+   * {@link WxConsts.XmlMsgType#VOICE}
+   * {@link WxConsts.XmlMsgType#VIDEO}
+   * {@link WxConsts.XmlMsgType#LOCATION}
+   * {@link WxConsts.XmlMsgType#LINK}
+   * {@link WxConsts.XmlMsgType#EVENT}
+   * 
+ */ + public String getMsgType() { + return this.msgType; + } + + /** + *
+   * 当发送消息的时候使用:
+   * {@link WxConsts.XmlMsgType#TEXT}
+   * {@link WxConsts.XmlMsgType#IMAGE}
+   * {@link WxConsts.XmlMsgType#VOICE}
+   * {@link WxConsts.XmlMsgType#VIDEO}
+   * {@link WxConsts.XmlMsgType#NEWS}
+   * 
+ */ + public void setMsgType(String msgType) { + this.msgType = msgType; + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + @Data + @XStreamAlias("ScanCodeInfo") + public static class ScanCodeInfo { + + /** + * 扫描类型,一般是qrcode. + */ + @XStreamAlias("ScanType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String scanType; + + /** + * 扫描结果,即二维码对应的字符串信息. + */ + @XStreamAlias("ScanResult") + @XStreamConverter(value = XStreamCDataConverter.class) + private String scanResult; + } + + @Data + @XStreamAlias("SendPicsInfo") + public static class SendPicsInfo { + @XStreamAlias("PicList") + protected final List picList = new ArrayList<>(); + + @XStreamAlias("Count") + private Long count; + + @XStreamAlias("item") + @Data + public static class Item { + @XStreamAlias("PicMd5Sum") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picMd5Sum; + } + } + + @Data + @XStreamAlias("SendLocationInfo") + public static class SendLocationInfo { + + @XStreamAlias("Location_X") + @XStreamConverter(value = XStreamCDataConverter.class) + private String locationX; + + @XStreamAlias("Location_Y") + @XStreamConverter(value = XStreamCDataConverter.class) + private String locationY; + + @XStreamAlias("Scale") + @XStreamConverter(value = XStreamCDataConverter.class) + private String scale; + + @XStreamAlias("Label") + @XStreamConverter(value = XStreamCDataConverter.class) + private String label; + + @XStreamAlias("Poiname") + @XStreamConverter(value = XStreamCDataConverter.class) + private String poiName; + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java index dc77875e7e..5c8300b29d 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = -1099446240667237313L; - - @XStreamAlias("Image") - @XStreamConverter(value = XStreamMediaIdConverter.class) - private String mediaId; - - public WxCpXmlOutImageMessage() { - this.msgType = WxConsts.XmlMsgType.IMAGE; - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = -1099446240667237313L; + + @XStreamAlias("Image") + @XStreamConverter(value = XStreamMediaIdConverter.class) + private String mediaId; + + public WxCpXmlOutImageMessage() { + this.msgType = WxConsts.XmlMsgType.IMAGE; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java index 34c5499f06..3725989238 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java @@ -1,81 +1,81 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; -import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import me.chanjar.weixin.cp.bean.outxmlbuilder.*; -import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; -import me.chanjar.weixin.cp.util.xml.XStreamTransformer; - -import java.io.Serializable; - -@XStreamAlias("xml") -@Data -public abstract class WxCpXmlOutMessage implements Serializable { - private static final long serialVersionUID = 1418629839964153110L; - - @XStreamAlias("ToUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - protected String toUserName; - - @XStreamAlias("FromUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - protected String fromUserName; - - @XStreamAlias("CreateTime") - protected Long createTime; - - @XStreamAlias("MsgType") - @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(); - } - - protected String toXml() { - return XStreamTransformer.toXml((Class) this.getClass(), this); - } - - /** - * 转换成加密的xml格式. - */ - public String toEncryptedXml(WxCpConfigStorage wxCpConfigStorage) { - String plainXml = toXml(); - WxCpCryptUtil pc = new WxCpCryptUtil(wxCpConfigStorage); - return pc.encrypt(plainXml); - } -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import me.chanjar.weixin.cp.config.WxCpConfigStorage; +import me.chanjar.weixin.cp.bean.outxmlbuilder.*; +import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; +import me.chanjar.weixin.cp.util.xml.XStreamTransformer; + +import java.io.Serializable; + +@XStreamAlias("xml") +@Data +public abstract class WxCpXmlOutMessage implements Serializable { + private static final long serialVersionUID = 1418629839964153110L; + + @XStreamAlias("ToUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + protected String toUserName; + + @XStreamAlias("FromUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + protected String fromUserName; + + @XStreamAlias("CreateTime") + protected Long createTime; + + @XStreamAlias("MsgType") + @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(); + } + + protected String toXml() { + return XStreamTransformer.toXml((Class) this.getClass(), this); + } + + /** + * 转换成加密的xml格式. + */ + public String toEncryptedXml(WxCpConfigStorage wxCpConfigStorage) { + String plainXml = toXml(); + WxCpCryptUtil pc = new WxCpCryptUtil(wxCpConfigStorage); + return pc.encrypt(plainXml); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java index 992397981f..e7e17b31d4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java @@ -1,55 +1,55 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -import java.util.ArrayList; -import java.util.List; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = -5796178637883178826L; - - @XStreamAlias("Articles") - protected final List articles = new ArrayList<>(); - - @XStreamAlias("ArticleCount") - protected int articleCount; - - public WxCpXmlOutNewsMessage() { - this.msgType = WxConsts.XmlMsgType.NEWS; - } - - - public void addArticle(Item item) { - this.articles.add(item); - this.articleCount = this.articles.size(); - } - - @XStreamAlias("item") - @Data - public static class Item { - - @XStreamAlias("Title") - @XStreamConverter(value = XStreamCDataConverter.class) - private String title; - - @XStreamAlias("Description") - @XStreamConverter(value = XStreamCDataConverter.class) - private String description; - - @XStreamAlias("PicUrl") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picUrl; - - @XStreamAlias("Url") - @XStreamConverter(value = XStreamCDataConverter.class) - private String url; - - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +import java.util.ArrayList; +import java.util.List; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = -5796178637883178826L; + + @XStreamAlias("Articles") + protected final List articles = new ArrayList<>(); + + @XStreamAlias("ArticleCount") + protected int articleCount; + + public WxCpXmlOutNewsMessage() { + this.msgType = WxConsts.XmlMsgType.NEWS; + } + + + public void addArticle(Item item) { + this.articles.add(item); + this.articleCount = this.articles.size(); + } + + @XStreamAlias("item") + @Data + public static class Item { + + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @XStreamAlias("Description") + @XStreamConverter(value = XStreamCDataConverter.class) + private String description; + + @XStreamAlias("PicUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picUrl; + + @XStreamAlias("Url") + @XStreamConverter(value = XStreamCDataConverter.class) + private String url; + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java index 1c354a12d4..023d11a21a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = 2569239617185930232L; - - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - public WxCpXmlOutTextMessage() { - this.msgType = WxConsts.XmlMsgType.TEXT; - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = 2569239617185930232L; + + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + public WxCpXmlOutTextMessage() { + this.msgType = WxConsts.XmlMsgType.TEXT; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java index 6d3bd0b4d1..839327a306 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java @@ -1,63 +1,63 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = -8672761162722733622L; - - @XStreamAlias("Video") - protected final Video video = new Video(); - - public WxCpXmlOutVideoMessage() { - this.msgType = WxConsts.XmlMsgType.VIDEO; - } - - public String getMediaId() { - return this.video.getMediaId(); - } - - public void setMediaId(String mediaId) { - this.video.setMediaId(mediaId); - } - - public String getTitle() { - return this.video.getTitle(); - } - - public void setTitle(String title) { - this.video.setTitle(title); - } - - public String getDescription() { - return this.video.getDescription(); - } - - public void setDescription(String description) { - this.video.setDescription(description); - } - - @Data - @XStreamAlias("Video") - public static class Video { - - @XStreamAlias("MediaId") - @XStreamConverter(value = XStreamCDataConverter.class) - private String mediaId; - - @XStreamAlias("Title") - @XStreamConverter(value = XStreamCDataConverter.class) - private String title; - - @XStreamAlias("Description") - @XStreamConverter(value = XStreamCDataConverter.class) - private String description; - - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = -8672761162722733622L; + + @XStreamAlias("Video") + protected final Video video = new Video(); + + public WxCpXmlOutVideoMessage() { + this.msgType = WxConsts.XmlMsgType.VIDEO; + } + + public String getMediaId() { + return this.video.getMediaId(); + } + + public void setMediaId(String mediaId) { + this.video.setMediaId(mediaId); + } + + public String getTitle() { + return this.video.getTitle(); + } + + public void setTitle(String title) { + this.video.setTitle(title); + } + + public String getDescription() { + return this.video.getDescription(); + } + + public void setDescription(String description) { + this.video.setDescription(description); + } + + @Data + @XStreamAlias("Video") + public static class Video { + + @XStreamAlias("MediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mediaId; + + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @XStreamAlias("Description") + @XStreamConverter(value = XStreamCDataConverter.class) + private String description; + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java index c880bccfff..63cbde3781 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = -7947384031546099340L; - - @XStreamAlias("Voice") - @XStreamConverter(value = XStreamMediaIdConverter.class) - private String mediaId; - - public WxCpXmlOutVoiceMessage() { - this.msgType = WxConsts.XmlMsgType.VOICE; - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = -7947384031546099340L; + + @XStreamAlias("Voice") + @XStreamConverter(value = XStreamMediaIdConverter.class) + private String mediaId; + + public WxCpXmlOutVoiceMessage() { + this.msgType = WxConsts.XmlMsgType.VOICE; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java index af622fefd8..38950dcc39 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java @@ -1,28 +1,28 @@ -package me.chanjar.weixin.cp.bean.article; - -import lombok.Builder; -import lombok.Data; - -import java.io.Serializable; - -/** - *
- *  Created by BinaryWang on 2017/3/27.
- * 
- * - * @author Binary Wang - */ -@Data -@Builder(builderMethodName = "newBuilder") -public class MpnewsArticle implements Serializable { - private static final long serialVersionUID = 6985871812170756481L; - - private String title; - private String thumbMediaId; - private String author; - private String contentSourceUrl; - private String content; - private String digest; - private String showCoverPic; - -} +package me.chanjar.weixin.cp.bean.article; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ *  Created by BinaryWang on 2017/3/27.
+ * 
+ * + * @author Binary Wang + */ +@Data +@Builder(builderMethodName = "newBuilder") +public class MpnewsArticle implements Serializable { + private static final long serialVersionUID = 6985871812170756481L; + + private String title; + private String thumbMediaId; + private String author; + private String contentSourceUrl; + private String content; + private String digest; + private String showCoverPic; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java index 7f10d363b4..5accf3b42d 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java @@ -1,23 +1,23 @@ -package me.chanjar.weixin.cp.bean.article; - -import lombok.Data; - -import java.io.Serializable; - -/** - *
- *  Created by BinaryWang on 2017/3/27.
- * 
- * - * @author Binary Wang - */ -@Data -public class NewArticle implements Serializable { - private static final long serialVersionUID = 4087852055781140659L; - - private String title; - private String description; - private String url; - private String picUrl; - -} +package me.chanjar.weixin.cp.bean.article; + +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ *  Created by BinaryWang on 2017/3/27.
+ * 
+ * + * @author Binary Wang + */ +@Data +public class NewArticle implements Serializable { + private static final long serialVersionUID = 4087852055781140659L; + + private String title; + private String description; + private String url; + private String picUrl; + +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java index 6d4e8ce893..1e307f0146 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java @@ -1,68 +1,68 @@ -package me.chanjar.weixin.cp.api; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -@Test -public class WxCpBusyRetryTest { - - @DataProvider(name = "getService") - public Object[][] getService() { - WxCpService service = new WxCpServiceImpl() { - - @Override - public synchronized T executeInternal( - RequestExecutor executor, String uri, E data) - throws WxErrorException { - this.log.info("Executed"); - throw new WxErrorException(WxError.builder().errorCode(-1).build()); - } - }; - - service.setMaxRetryTimes(3); - service.setRetrySleepMillis(500); - return new Object[][]{ - new Object[]{service} - }; - } - - @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) - public void testRetry(WxCpService service) throws WxErrorException { - service.execute(null, null, null); - } - - @Test(dataProvider = "getService") - public void testRetryInThreadPool(final WxCpService service) throws InterruptedException, ExecutionException { - // 当线程池中的线程复用的时候,还是能保证相同的重试次数 - ExecutorService executorService = Executors.newFixedThreadPool(1); - Runnable runnable = new Runnable() { - @Override - public void run() { - try { - System.out.println("====================="); - System.out.println(Thread.currentThread().getName() + ": testRetry"); - service.execute(null, null, null); - } catch (WxErrorException e) { - throw new RuntimeException(e); - } catch (RuntimeException e) { - // OK - } - } - }; - Future submit1 = executorService.submit(runnable); - Future submit2 = executorService.submit(runnable); - - submit1.get(); - submit2.get(); - } - -} +package me.chanjar.weixin.cp.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +@Test +public class WxCpBusyRetryTest { + + @DataProvider(name = "getService") + public Object[][] getService() { + WxCpService service = new WxCpServiceImpl() { + + @Override + public synchronized T executeInternal( + RequestExecutor executor, String uri, E data) + throws WxErrorException { + this.log.info("Executed"); + throw new WxErrorException(WxError.builder().errorCode(-1).build()); + } + }; + + service.setMaxRetryTimes(3); + service.setRetrySleepMillis(500); + return new Object[][]{ + new Object[]{service} + }; + } + + @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) + public void testRetry(WxCpService service) throws WxErrorException { + service.execute(null, null, null); + } + + @Test(dataProvider = "getService") + public void testRetryInThreadPool(final WxCpService service) throws InterruptedException, ExecutionException { + // 当线程池中的线程复用的时候,还是能保证相同的重试次数 + ExecutorService executorService = Executors.newFixedThreadPool(1); + Runnable runnable = new Runnable() { + @Override + public void run() { + try { + System.out.println("====================="); + System.out.println(Thread.currentThread().getName() + ": testRetry"); + service.execute(null, null, null); + } catch (WxErrorException e) { + throw new RuntimeException(e); + } catch (RuntimeException e) { + // OK + } + } + }; + Future submit1 = executorService.submit(runnable); + Future submit2 = executorService.submit(runnable); + + submit1.get(); + submit2.get(); + } + +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java index e320d8cb2e..62f8cae583 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java @@ -1,120 +1,120 @@ -package me.chanjar.weixin.cp.bean; - -import me.chanjar.weixin.common.api.WxConsts; -import org.testng.annotations.*; - -import static org.testng.Assert.*; - -@Test -public class WxCpXmlMessageTest { - - public void testFromXml() { - - String xml = "" - + "" - + " " - + "1348831860" - + "" - + "" - + "1234567890123456" - + "" - + "" - + "" - + "" - + "23.134521" - + "113.358803" - + "20" - + "" - + "" - + "" - + "<![CDATA[公众平台官网链接]]>" - + "" - + "" - + "" - + "23.137466" - + "113.352425" - + "119.385040" - + "" - + " " - + " " - + "" - + "" - + " 1\n" - + " " - + " " - + " " - + " " - + " " - + "" - + "" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + "" - + ""; - WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); - assertEquals(wxMessage.getToUserName(), "toUser"); - assertEquals(wxMessage.getFromUserName(), "fromUser"); - assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); - assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); - assertEquals(wxMessage.getContent(), "this is a test"); - assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); - assertEquals(wxMessage.getPicUrl(), "this is a url"); - assertEquals(wxMessage.getMediaId(), "media_id"); - assertEquals(wxMessage.getFormat(), "Format"); - assertEquals(wxMessage.getThumbMediaId(), "thumb_media_id"); - assertEquals(wxMessage.getLocationX(), 23.134521d); - assertEquals(wxMessage.getLocationY(), 113.358803d); - assertEquals(wxMessage.getScale(), 20d); - assertEquals(wxMessage.getLabel(), "位置信息"); - assertEquals(wxMessage.getDescription(), "公众平台官网链接"); - assertEquals(wxMessage.getUrl(), "url"); - assertEquals(wxMessage.getTitle(), "公众平台官网链接"); - assertEquals(wxMessage.getEvent(), "subscribe"); - assertEquals(wxMessage.getEventKey(), "qrscene_123123"); - assertEquals(wxMessage.getTicket(), "TICKET"); - assertEquals(wxMessage.getLatitude(), 23.137466); - assertEquals(wxMessage.getLongitude(), 113.352425); - assertEquals(wxMessage.getPrecision(), 119.385040); - assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); - assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); - assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1l)); - assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); - assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); - assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); - assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); - assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); - assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi"); - } - - public void testSendPicsInfo() { - String xml = "" + - "" + - "" + - "1502012364" + - "" + - "1000004" + - "" + - "" + - "" + - "" + - "" + - "2" + - "" + - ""; - WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml.replace("
","")); - assertEquals(wxMessage.getToUserName(), "wx45a0972125658be9"); - assertEquals(wxMessage.getFromUserName(), "xiaohe"); - assertEquals(wxMessage.getCreateTime(), new Long(1502012364L)); - assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); - assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004)); - assertEquals(wxMessage.getEvent(), "pic_weixin"); - assertEquals(wxMessage.getEventKey(), "faceSimilarity"); - assertNotNull(wxMessage.getSendPicsInfo()); - assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(2L)); - assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "aef52ae501537e552725c5d7f99c1741"); - assertEquals(wxMessage.getSendPicsInfo().getPicList().get(1).getPicMd5Sum(), "c4564632a4fab91378c39bea6aad6f9e"); - } -} +package me.chanjar.weixin.cp.bean; + +import me.chanjar.weixin.common.api.WxConsts; +import org.testng.annotations.*; + +import static org.testng.Assert.*; + +@Test +public class WxCpXmlMessageTest { + + public void testFromXml() { + + String xml = "" + + "" + + " " + + "1348831860" + + "" + + "" + + "1234567890123456" + + "" + + "" + + "" + + "" + + "23.134521" + + "113.358803" + + "20" + + "" + + "" + + "" + + "<![CDATA[公众平台官网链接]]>" + + "" + + "" + + "" + + "23.137466" + + "113.352425" + + "119.385040" + + "" + + " " + + " " + + "" + + "" + + " 1\n" + + " " + + " " + + " " + + " " + + " " + + "" + + "" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "" + + ""; + WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); + assertEquals(wxMessage.getToUserName(), "toUser"); + assertEquals(wxMessage.getFromUserName(), "fromUser"); + assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); + assertEquals(wxMessage.getContent(), "this is a test"); + assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); + assertEquals(wxMessage.getPicUrl(), "this is a url"); + assertEquals(wxMessage.getMediaId(), "media_id"); + assertEquals(wxMessage.getFormat(), "Format"); + assertEquals(wxMessage.getThumbMediaId(), "thumb_media_id"); + assertEquals(wxMessage.getLocationX(), 23.134521d); + assertEquals(wxMessage.getLocationY(), 113.358803d); + assertEquals(wxMessage.getScale(), 20d); + assertEquals(wxMessage.getLabel(), "位置信息"); + assertEquals(wxMessage.getDescription(), "公众平台官网链接"); + assertEquals(wxMessage.getUrl(), "url"); + assertEquals(wxMessage.getTitle(), "公众平台官网链接"); + assertEquals(wxMessage.getEvent(), "subscribe"); + assertEquals(wxMessage.getEventKey(), "qrscene_123123"); + assertEquals(wxMessage.getTicket(), "TICKET"); + assertEquals(wxMessage.getLatitude(), 23.137466); + assertEquals(wxMessage.getLongitude(), 113.352425); + assertEquals(wxMessage.getPrecision(), 119.385040); + assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); + assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); + assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1l)); + assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); + assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); + assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); + assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); + assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); + assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi"); + } + + public void testSendPicsInfo() { + String xml = "" + + "" + + "" + + "1502012364" + + "" + + "1000004" + + "" + + "" + + "" + + "" + + "" + + "2" + + "" + + ""; + WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml.replace("","")); + assertEquals(wxMessage.getToUserName(), "wx45a0972125658be9"); + assertEquals(wxMessage.getFromUserName(), "xiaohe"); + assertEquals(wxMessage.getCreateTime(), new Long(1502012364L)); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); + assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004)); + assertEquals(wxMessage.getEvent(), "pic_weixin"); + assertEquals(wxMessage.getEventKey(), "faceSimilarity"); + assertNotNull(wxMessage.getSendPicsInfo()); + assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(2L)); + assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "aef52ae501537e552725c5d7f99c1741"); + assertEquals(wxMessage.getSendPicsInfo().getPicList().get(1).getPicMd5Sum(), "c4564632a4fab91378c39bea6aad6f9e"); + } +} diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index b7e2f1cb9c..b2ac1061c0 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -1,84 +1,84 @@ - - - 4.0.0 - - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - - weixin-java-miniapp - WeiXin Java Tools - MiniApp - 微信小程序Java SDK - - - - com.github.binarywang - weixin-java-common - ${project.version} - - - - org.jodd - jodd-http - provided - - - com.squareup.okhttp3 - okhttp - provided - - - - org.testng - testng - test - - - ch.qos.logback - logback-classic - test - - - com.google.inject - guice - test - - - org.eclipse.jetty - jetty-server - test - - - org.eclipse.jetty - jetty-servlet - test - - - joda-time - joda-time - test - - - redis.clients - jedis - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - src/test/resources/testng.xml - - - - - - - + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + + weixin-java-miniapp + WeiXin Java Tools - MiniApp + 微信小程序Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + + org.testng + testng + test + + + ch.qos.logback + logback-classic + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + joda-time + joda-time + test + + + redis.clients + jedis + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java index b198fc7a07..95d95a0c42 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java @@ -1,55 +1,55 @@ -package cn.binarywang.wx.miniapp.api.impl; - -import cn.binarywang.wx.miniapp.api.WxMaMediaService; -import cn.binarywang.wx.miniapp.api.WxMaService; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.fs.FileUtils; -import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; -import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; -import me.chanjar.weixin.common.util.http.RequestExecutor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.util.UUID; - -/** - * @author Binary Wang - */ -public class WxMaMediaServiceImpl implements WxMaMediaService { - private WxMaService wxMaService; - - public WxMaMediaServiceImpl(WxMaService wxMaService) { - this.wxMaService = wxMaService; - } - - @Override - public WxMediaUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { - try { - return this.uploadMedia(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); - } catch (IOException e) { - throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); - } - } - - @Override - public WxMediaUploadResult uploadMedia(String mediaType, File file) throws WxErrorException { - String url = String.format(MEDIA_UPLOAD_URL, mediaType); - return this.wxMaService.execute(MediaUploadRequestExecutor.create(this.wxMaService.getRequestHttp()), url, file); - } - - @Override - public File getMedia(String mediaId) throws WxErrorException { - try { - RequestExecutor executor = BaseMediaDownloadRequestExecutor - .create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxma").toFile()); - return this.wxMaService.execute(executor, MEDIA_GET_URL, "media_id=" + mediaId); - } catch (IOException e) { - throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); - } - } - -} +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaMediaService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; +import me.chanjar.weixin.common.util.http.RequestExecutor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.UUID; + +/** + * @author Binary Wang + */ +public class WxMaMediaServiceImpl implements WxMaMediaService { + private WxMaService wxMaService; + + public WxMaMediaServiceImpl(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + @Override + public WxMediaUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { + try { + return this.uploadMedia(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); + } catch (IOException e) { + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); + } + } + + @Override + public WxMediaUploadResult uploadMedia(String mediaType, File file) throws WxErrorException { + String url = String.format(MEDIA_UPLOAD_URL, mediaType); + return this.wxMaService.execute(MediaUploadRequestExecutor.create(this.wxMaService.getRequestHttp()), url, file); + } + + @Override + public File getMedia(String mediaId) throws WxErrorException { + try { + RequestExecutor executor = BaseMediaDownloadRequestExecutor + .create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxma").toFile()); + return this.wxMaService.execute(executor, MEDIA_GET_URL, "media_id=" + mediaId); + } catch (IOException e) { + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); + } + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java index 2afb4c073e..922bbb4b2d 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java @@ -1,18 +1,18 @@ -package cn.binarywang.wx.miniapp.bean; - -import lombok.AllArgsConstructor; -import lombok.Data; - -/** - *
- * lineColor 包装类
- * 用于描述二维码(小程序码)颜色(RGB参数值),
- * 详情请查看文档 https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html
- * 
- * @author Element - */ -@Data -@AllArgsConstructor -public class WxMaCodeLineColor { - private String r = "0", g = "0", b = "0"; -} +package cn.binarywang.wx.miniapp.bean; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + *
+ * lineColor 包装类
+ * 用于描述二维码(小程序码)颜色(RGB参数值),
+ * 详情请查看文档 https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html
+ * 
+ * @author Element + */ +@Data +@AllArgsConstructor +public class WxMaCodeLineColor { + private String r = "0", g = "0", b = "0"; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java index 7d3e2d8de6..50f6f4bba4 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java @@ -1,36 +1,36 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - * {"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","expires_in":2592000,"openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"} - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxMaJscode2SessionResult implements Serializable { - private static final long serialVersionUID = -1060216618475607933L; - - @SerializedName("session_key") - private String sessionKey; - - @SerializedName("expires_in") - private Integer expiresin; - - @SerializedName("openid") - private String openid; - - @SerializedName("unionid") - private String unionid; - - public static WxMaJscode2SessionResult fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaJscode2SessionResult.class); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * {"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","expires_in":2592000,"openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"} + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaJscode2SessionResult implements Serializable { + private static final long serialVersionUID = -1060216618475607933L; + + @SerializedName("session_key") + private String sessionKey; + + @SerializedName("expires_in") + private Integer expiresin; + + @SerializedName("openid") + private String openid; + + @SerializedName("unionid") + private String unionid; + + public static WxMaJscode2SessionResult fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaJscode2SessionResult.class); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java index ec1728db60..3c7e5f1f6d 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java @@ -1,45 +1,45 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.builder.ImageBuilder; -import cn.binarywang.wx.miniapp.builder.TextBuilder; -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import lombok.Data; - -import java.io.Serializable; - -/** - * 客服消息 - * - * @author Binary Wang - */ -@Data -public class WxMaKefuMessage implements Serializable { - private static final long serialVersionUID = -9196732086954365246L; - - private String toUser; - private String msgType; - private String content; - private String mediaId; - private String thumbMediaId; - private String title; - private String description; - - /** - * 获得文本消息builder - */ - public static TextBuilder newTextBuilder() { - return new TextBuilder(); - } - - /** - * 获得图片消息builder - */ - public static ImageBuilder newImageBuilder() { - return new ImageBuilder(); - } - - public String toJson() { - return WxMaGsonBuilder.create().toJson(this); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.builder.ImageBuilder; +import cn.binarywang.wx.miniapp.builder.TextBuilder; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Data; + +import java.io.Serializable; + +/** + * 客服消息 + * + * @author Binary Wang + */ +@Data +public class WxMaKefuMessage implements Serializable { + private static final long serialVersionUID = -9196732086954365246L; + + private String toUser; + private String msgType; + private String content; + private String mediaId; + private String thumbMediaId; + private String title; + private String description; + + /** + * 获得文本消息builder + */ + public static TextBuilder newTextBuilder() { + return new TextBuilder(); + } + + /** + * 获得图片消息builder + */ + public static ImageBuilder newImageBuilder() { + return new ImageBuilder(); + } + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java index cb1fed6923..2bd47d2e57 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java @@ -1,151 +1,151 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.config.WxMaConfig; -import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import cn.binarywang.wx.miniapp.util.xml.XStreamTransformer; -import com.google.gson.annotations.SerializedName; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; - -/** - * @author Binary Wang - */ -@XStreamAlias("xml") -@Data -public class WxMaMessage implements Serializable { - private static final long serialVersionUID = -3586245291677274914L; - - @SerializedName("Encrypt") - @XStreamAlias("Encrypt") - @XStreamConverter(value = XStreamCDataConverter.class) - private String encrypt; - - @SerializedName("ToUserName") - @XStreamAlias("ToUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - private String toUser; - - @SerializedName("FromUserName") - @XStreamAlias("FromUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - private String fromUser; - - @SerializedName("CreateTime") - @XStreamAlias("CreateTime") - @XStreamConverter(value = XStreamCDataConverter.class) - private Integer createTime; - - @SerializedName("MsgDataFormat") - @XStreamAlias("MsgDataFormat") - @XStreamConverter(value = XStreamCDataConverter.class) - private String msgType; - - // 文本消息 - @SerializedName("Content") - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - @SerializedName("MsgId") - @XStreamAlias("MsgId") - @XStreamConverter(value = XStreamCDataConverter.class) - private Long msgId; - - // 图片消息 - @SerializedName("PicUrl") - @XStreamAlias("PicUrl") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picUrl; - - @SerializedName("MediaId") - @XStreamAlias("MediaId") - @XStreamConverter(value = XStreamCDataConverter.class) - private String mediaId; - - // 事件消息 - @SerializedName("Event") - @XStreamAlias("Event") - @XStreamConverter(value = XStreamCDataConverter.class) - private String event; - - @SerializedName("SessionFrom") - @XStreamAlias("SessionFrom") - @XStreamConverter(value = XStreamCDataConverter.class) - private String sessionFrom; - - public static WxMaMessage fromXml(String xml) { - return XStreamTransformer.fromXml(WxMaMessage.class, xml); - } - - public static WxMaMessage fromXml(InputStream is) { - return XStreamTransformer.fromXml(WxMaMessage.class, is); - } - - /** - * 从加密字符串转换 - * - * @param encryptedXml 密文 - * @param wxMaConfig 配置存储器对象 - * @param timestamp 时间戳 - * @param nonce 随机串 - * @param msgSignature 签名串 - */ - public static WxMaMessage fromEncryptedXml(String encryptedXml, - WxMaConfig wxMaConfig, String timestamp, String nonce, - String msgSignature) { - String plainText = new WxMaCryptUtils(wxMaConfig).decrypt(msgSignature, timestamp, nonce, encryptedXml); - return fromXml(plainText); - } - - public static WxMaMessage fromEncryptedXml(InputStream is, WxMaConfig wxMaConfig, String timestamp, - String nonce, String msgSignature) { - try { - return fromEncryptedXml(IOUtils.toString(is, StandardCharsets.UTF_8), wxMaConfig, - timestamp, nonce, msgSignature); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static WxMaMessage fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaMessage.class); - } - - public static WxMaMessage fromEncryptedJson(String encryptedJson, WxMaConfig config) { - try { - WxMaMessage encryptedMessage = fromJson(encryptedJson); - String plainText = new WxMaCryptUtils(config).decrypt(encryptedMessage.getEncrypt()); - return fromJson(plainText); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static WxMaMessage fromEncryptedJson(InputStream inputStream, WxMaConfig config) { - try { - return fromEncryptedJson(IOUtils.toString(inputStream, StandardCharsets.UTF_8), config); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String toJson() { - return WxMaGsonBuilder.create().toJson(this); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import cn.binarywang.wx.miniapp.util.xml.XStreamTransformer; +import com.google.gson.annotations.SerializedName; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; + +/** + * @author Binary Wang + */ +@XStreamAlias("xml") +@Data +public class WxMaMessage implements Serializable { + private static final long serialVersionUID = -3586245291677274914L; + + @SerializedName("Encrypt") + @XStreamAlias("Encrypt") + @XStreamConverter(value = XStreamCDataConverter.class) + private String encrypt; + + @SerializedName("ToUserName") + @XStreamAlias("ToUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String toUser; + + @SerializedName("FromUserName") + @XStreamAlias("FromUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String fromUser; + + @SerializedName("CreateTime") + @XStreamAlias("CreateTime") + @XStreamConverter(value = XStreamCDataConverter.class) + private Integer createTime; + + @SerializedName("MsgDataFormat") + @XStreamAlias("MsgDataFormat") + @XStreamConverter(value = XStreamCDataConverter.class) + private String msgType; + + // 文本消息 + @SerializedName("Content") + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + @SerializedName("MsgId") + @XStreamAlias("MsgId") + @XStreamConverter(value = XStreamCDataConverter.class) + private Long msgId; + + // 图片消息 + @SerializedName("PicUrl") + @XStreamAlias("PicUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picUrl; + + @SerializedName("MediaId") + @XStreamAlias("MediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mediaId; + + // 事件消息 + @SerializedName("Event") + @XStreamAlias("Event") + @XStreamConverter(value = XStreamCDataConverter.class) + private String event; + + @SerializedName("SessionFrom") + @XStreamAlias("SessionFrom") + @XStreamConverter(value = XStreamCDataConverter.class) + private String sessionFrom; + + public static WxMaMessage fromXml(String xml) { + return XStreamTransformer.fromXml(WxMaMessage.class, xml); + } + + public static WxMaMessage fromXml(InputStream is) { + return XStreamTransformer.fromXml(WxMaMessage.class, is); + } + + /** + * 从加密字符串转换 + * + * @param encryptedXml 密文 + * @param wxMaConfig 配置存储器对象 + * @param timestamp 时间戳 + * @param nonce 随机串 + * @param msgSignature 签名串 + */ + public static WxMaMessage fromEncryptedXml(String encryptedXml, + WxMaConfig wxMaConfig, String timestamp, String nonce, + String msgSignature) { + String plainText = new WxMaCryptUtils(wxMaConfig).decrypt(msgSignature, timestamp, nonce, encryptedXml); + return fromXml(plainText); + } + + public static WxMaMessage fromEncryptedXml(InputStream is, WxMaConfig wxMaConfig, String timestamp, + String nonce, String msgSignature) { + try { + return fromEncryptedXml(IOUtils.toString(is, StandardCharsets.UTF_8), wxMaConfig, + timestamp, nonce, msgSignature); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static WxMaMessage fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaMessage.class); + } + + public static WxMaMessage fromEncryptedJson(String encryptedJson, WxMaConfig config) { + try { + WxMaMessage encryptedMessage = fromJson(encryptedJson); + String plainText = new WxMaCryptUtils(config).decrypt(encryptedMessage.getEncrypt()); + return fromJson(plainText); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static WxMaMessage fromEncryptedJson(InputStream inputStream, WxMaConfig config) { + try { + return fromEncryptedJson(IOUtils.toString(inputStream, StandardCharsets.UTF_8), config); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java index 5c17cd1e58..87aa3f8bdf 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java @@ -1,32 +1,32 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxMaQrcode extends AbstractWxMaQrcodeWrapper implements Serializable { - private static final long serialVersionUID = 5777119669111011584L; - private String path; - private int width = 430; - - public WxMaQrcode(String path, int width) { - this.path = path; - this.width = width; - } - - public static WxMaQrcode fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaQrcode.class); - } - - @Override - public String toString() { - return WxMaGsonBuilder.create().toJson(this); - } -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaQrcode extends AbstractWxMaQrcodeWrapper implements Serializable { + private static final long serialVersionUID = 5777119669111011584L; + private String path; + private int width = 430; + + public WxMaQrcode(String path, int width) { + this.path = path; + this.width = width; + } + + public static WxMaQrcode fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaQrcode.class); + } + + @Override + public String toString() { + return WxMaGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java index 32268b4c4b..3e9760395e 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java @@ -1,108 +1,108 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import lombok.Builder; -import lombok.Data; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * 参考 https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#接口说明 模板消息部分 - * - * @author Binary Wang - */ -@Data -@Builder -public class WxMaTemplateMessage implements Serializable { - private static final long serialVersionUID = 5063374783759519418L; - - /** - *
-   * 参数:touser
-   * 是否必填: 是
-   * 描述: 接收者(用户)的 openid
-   * 
- */ - private String toUser; - - /** - *
-   * 参数:template_id
-   * 是否必填: 是
-   * 描述: 所需下发的模板消息的id
-   * 
- */ - private String templateId; - - /** - *
-   * 参数:page
-   * 是否必填: 否
-   * 描述: 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
-   * 
- */ - private String page; - - /** - *
-   * 参数:form_id
-   * 是否必填: 是
-   * 描述: 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id
-   * 
- */ - private String formId; - - /** - *
-   * 参数:data
-   * 是否必填: 是
-   * 描述: 模板内容,不填则下发空模板
-   * 
- */ - @Builder.Default - private final List data = new ArrayList<>(); - - /** - *
-   * 参数:color
-   * 是否必填: 否
-   * 描述: 模板内容字体的颜色,不填默认黑色
-   * 
- */ - private String color; - - /** - *
-   * 参数:emphasis_keyword
-   * 是否必填: 否
-   * 描述: 模板需要放大的关键词,不填则默认无放大
-   * 
- */ - private String emphasisKeyword; - - public String toJson() { - return WxMaGsonBuilder.create().toJson(this); - } - - @lombok.Data - public static class Data { - private String name; - private String value; - private String color; - - public Data(String name, String value) { - this.name = name; - this.value = value; - } - - public Data(String name, String value, String color) { - this.name = name; - this.value = value; - this.color = color; - } - - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 参考 https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#接口说明 模板消息部分 + * + * @author Binary Wang + */ +@Data +@Builder +public class WxMaTemplateMessage implements Serializable { + private static final long serialVersionUID = 5063374783759519418L; + + /** + *
+   * 参数:touser
+   * 是否必填: 是
+   * 描述: 接收者(用户)的 openid
+   * 
+ */ + private String toUser; + + /** + *
+   * 参数:template_id
+   * 是否必填: 是
+   * 描述: 所需下发的模板消息的id
+   * 
+ */ + private String templateId; + + /** + *
+   * 参数:page
+   * 是否必填: 否
+   * 描述: 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
+   * 
+ */ + private String page; + + /** + *
+   * 参数:form_id
+   * 是否必填: 是
+   * 描述: 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id
+   * 
+ */ + private String formId; + + /** + *
+   * 参数:data
+   * 是否必填: 是
+   * 描述: 模板内容,不填则下发空模板
+   * 
+ */ + @Builder.Default + private final List data = new ArrayList<>(); + + /** + *
+   * 参数:color
+   * 是否必填: 否
+   * 描述: 模板内容字体的颜色,不填默认黑色
+   * 
+ */ + private String color; + + /** + *
+   * 参数:emphasis_keyword
+   * 是否必填: 否
+   * 描述: 模板需要放大的关键词,不填则默认无放大
+   * 
+ */ + private String emphasisKeyword; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + + @lombok.Data + public static class Data { + private String name; + private String value; + private String color; + + public Data(String name, String value) { + this.name = name; + this.value = value; + } + + public Data(String name, String value, String color) { + this.name = name; + this.value = value; + this.color = color; + } + + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java index 8b0ed8fe6a..a16fc30a1a 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java @@ -1,35 +1,35 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import lombok.Data; - -import java.io.Serializable; - -/** - * @author Binary Wang - */ -@Data -public class WxMaUserInfo implements Serializable { - private static final long serialVersionUID = 6719822331555402137L; - - private String openId; - private String nickName; - private String gender; - private String language; - private String city; - private String province; - private String country; - private String avatarUrl; - private String unionId; - private Watermark watermark; - - public static WxMaUserInfo fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaUserInfo.class); - } - - @Data - public static class Watermark { - private String timestamp; - private String appid; - } -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author Binary Wang + */ +@Data +public class WxMaUserInfo implements Serializable { + private static final long serialVersionUID = 6719822331555402137L; + + private String openId; + private String nickName; + private String gender; + private String language; + private String city; + private String province; + private String country; + private String avatarUrl; + private String unionId; + private Watermark watermark; + + public static WxMaUserInfo fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaUserInfo.class); + } + + @Data + public static class Watermark { + private String timestamp; + private String appid; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java index 8e629096c6..7d9c60e676 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java @@ -1,33 +1,33 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - * - * @author Element - * @date 2017/7/27 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxMaWxcode extends AbstractWxMaQrcodeWrapper implements Serializable { - private static final long serialVersionUID = 1287399621649210322L; - - private String path; - private int width = 430; - - @SerializedName("auto_color") - private boolean autoColor = true; - - @SerializedName("line_color") - private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); - - public static WxMaWxcode fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaWxcode.class); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * + * @author Element + * @date 2017/7/27 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaWxcode extends AbstractWxMaQrcodeWrapper implements Serializable { + private static final long serialVersionUID = 1287399621649210322L; + + private String path; + private int width = 430; + + @SerializedName("auto_color") + private boolean autoColor = true; + + @SerializedName("line_color") + private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); + + public static WxMaWxcode fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaWxcode.class); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java index 5f76273b54..928e9b7d91 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java @@ -1,34 +1,34 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - * - * @author Element - * @date 2017/7/27 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxMaWxcodeLimit extends AbstractWxMaQrcodeWrapper implements Serializable { - private static final long serialVersionUID = 4782193774524960401L; - private String scene; - private String page; - - private int width = 430; - - @SerializedName("auto_color") - private boolean autoColor = true; - - @SerializedName("line_color") - private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); - - public static WxMaWxcodeLimit fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * + * @author Element + * @date 2017/7/27 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaWxcodeLimit extends AbstractWxMaQrcodeWrapper implements Serializable { + private static final long serialVersionUID = 4782193774524960401L; + private String scene; + private String page; + + private int width = 430; + + @SerializedName("auto_color") + private boolean autoColor = true; + + @SerializedName("line_color") + private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); + + public static WxMaWxcodeLimit fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class); + } + +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java index d6aa31a71f..39475453a0 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java @@ -1,73 +1,73 @@ -package cn.binarywang.wx.miniapp.api.impl; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; -import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; -import cn.binarywang.wx.miniapp.test.ApiTestModule; -import cn.binarywang.wx.miniapp.test.TestConfig; -import com.google.common.collect.Lists; -import com.google.inject.Inject; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.exception.WxErrorException; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; - -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * 测试客服相关接口 - * - * @author Binary Wang - */ -@Test -@Guice(modules = ApiTestModule.class) -public class WxMaMsgServiceImplTest { - - @Inject - protected WxMaService wxService; - - public void testSendKefuMpNewsMessage() throws WxErrorException { - TestConfig configStorage = (TestConfig) this.wxService - .getWxMaConfig(); - WxMaKefuMessage message = new WxMaKefuMessage(); - message.setMsgType(WxConsts.KefuMsgType.MPNEWS); - message.setToUser(configStorage.getOpenid()); - - this.wxService.getMsgService().sendKefuMsg(message); - } - - public void testSendKefuMessage() throws WxErrorException { - TestConfig config = (TestConfig) this.wxService - .getWxMaConfig(); - WxMaKefuMessage message = new WxMaKefuMessage(); - message.setMsgType(WxConsts.KefuMsgType.TEXT); - message.setToUser(config.getOpenid()); - message.setContent( - "欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); - - this.wxService.getMsgService().sendKefuMsg(message); - } - - @Test(invocationCount = 5, threadPoolSize = 3) - public void testSendTemplateMsg() throws WxErrorException { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); - - WxMaTemplateMessage templateMessage = WxMaTemplateMessage.builder() - .toUser(config.getOpenid()) - .formId("FORMID") - .page("index") - .data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), - new WxMaTemplateMessage.Data("keyword2", dateFormat.format(new Date()), "#173177"), - new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), - new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) - .templateId(config.getTemplateId()) - .emphasisKeyword("keyword1.DATA") - .build(); - - this.wxService.getMsgService().sendTemplateMsg(templateMessage); - } - -} +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; +import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import cn.binarywang.wx.miniapp.test.TestConfig; +import com.google.common.collect.Lists; +import com.google.inject.Inject; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.exception.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 测试客服相关接口 + * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaMsgServiceImplTest { + + @Inject + protected WxMaService wxService; + + public void testSendKefuMpNewsMessage() throws WxErrorException { + TestConfig configStorage = (TestConfig) this.wxService + .getWxMaConfig(); + WxMaKefuMessage message = new WxMaKefuMessage(); + message.setMsgType(WxConsts.KefuMsgType.MPNEWS); + message.setToUser(configStorage.getOpenid()); + + this.wxService.getMsgService().sendKefuMsg(message); + } + + public void testSendKefuMessage() throws WxErrorException { + TestConfig config = (TestConfig) this.wxService + .getWxMaConfig(); + WxMaKefuMessage message = new WxMaKefuMessage(); + message.setMsgType(WxConsts.KefuMsgType.TEXT); + message.setToUser(config.getOpenid()); + message.setContent( + "欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); + + this.wxService.getMsgService().sendKefuMsg(message); + } + + @Test(invocationCount = 5, threadPoolSize = 3) + public void testSendTemplateMsg() throws WxErrorException { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); + + WxMaTemplateMessage templateMessage = WxMaTemplateMessage.builder() + .toUser(config.getOpenid()) + .formId("FORMID") + .page("index") + .data(Lists.newArrayList( + new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), + new WxMaTemplateMessage.Data("keyword2", dateFormat.format(new Date()), "#173177"), + new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), + new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) + .templateId(config.getTemplateId()) + .emphasisKeyword("keyword1.DATA") + .build(); + + this.wxService.getMsgService().sendTemplateMsg(templateMessage); + } + +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java index d4464312eb..e1db78f8de 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java @@ -1,31 +1,31 @@ -package cn.binarywang.wx.miniapp.bean; - -import com.google.common.collect.Lists; -import org.testng.annotations.Test; - -import static org.testng.AssertJUnit.assertEquals; - -/** - * @author Binary Wang - */ -public class WxMaTemplateMessageTest { - @Test - public void testToJson() throws Exception { - WxMaTemplateMessage tm = WxMaTemplateMessage.builder() - .toUser("OPENID") - //.color("aaaaa") - .formId("FORMID") - .page("index") - .data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), - new WxMaTemplateMessage.Data("keyword2", "2015年01月05日12:30", "#173177"), - new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), - new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) - .templateId("TEMPLATE_ID") - .emphasisKeyword("keyword1.DATA") - .build(); - - assertEquals(tm.toJson(), "{\"touser\":\"OPENID\",\"template_id\":\"TEMPLATE_ID\",\"page\":\"index\",\"form_id\":\"FORMID\",\"emphasis_keyword\":\"keyword1.DATA\",\"data\":{\"keyword1\":{\"value\":\"339208499\",\"color\":\"#173177\"},\"keyword2\":{\"value\":\"2015年01月05日12:30\",\"color\":\"#173177\"},\"keyword3\":{\"value\":\"粤海喜来登酒店\",\"color\":\"#173177\"},\"keyword4\":{\"value\":\"广州市天河区天河路208号\",\"color\":\"#173177\"}}}"); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import com.google.common.collect.Lists; +import org.testng.annotations.Test; + +import static org.testng.AssertJUnit.assertEquals; + +/** + * @author Binary Wang + */ +public class WxMaTemplateMessageTest { + @Test + public void testToJson() throws Exception { + WxMaTemplateMessage tm = WxMaTemplateMessage.builder() + .toUser("OPENID") + //.color("aaaaa") + .formId("FORMID") + .page("index") + .data(Lists.newArrayList( + new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), + new WxMaTemplateMessage.Data("keyword2", "2015年01月05日12:30", "#173177"), + new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), + new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) + .templateId("TEMPLATE_ID") + .emphasisKeyword("keyword1.DATA") + .build(); + + assertEquals(tm.toJson(), "{\"touser\":\"OPENID\",\"template_id\":\"TEMPLATE_ID\",\"page\":\"index\",\"form_id\":\"FORMID\",\"emphasis_keyword\":\"keyword1.DATA\",\"data\":{\"keyword1\":{\"value\":\"339208499\",\"color\":\"#173177\"},\"keyword2\":{\"value\":\"2015年01月05日12:30\",\"color\":\"#173177\"},\"keyword3\":{\"value\":\"粤海喜来登酒店\",\"color\":\"#173177\"},\"keyword4\":{\"value\":\"广州市天河区天河路208号\",\"color\":\"#173177\"}}}"); + } + +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java index 8d14b261ff..bc0f6bb000 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java @@ -1,148 +1,148 @@ -package cn.binarywang.wx.miniapp.demo; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; -import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; -import cn.binarywang.wx.miniapp.bean.WxMaMessage; -import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; -import cn.binarywang.wx.miniapp.config.WxMaConfig; -import cn.binarywang.wx.miniapp.constant.WxMaConstants; -import cn.binarywang.wx.miniapp.message.WxMaMessageHandler; -import cn.binarywang.wx.miniapp.message.WxMaMessageRouter; -import cn.binarywang.wx.miniapp.test.TestConfig; -import com.google.common.collect.Lists; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.session.WxSessionManager; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletHandler; -import org.eclipse.jetty.servlet.ServletHolder; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.concurrent.locks.ReentrantLock; - -/** - * @author Binary Wang - */ -public class WxMaDemoServer { - - private static final WxMaMessageHandler logHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) throws WxErrorException { - System.out.println("收到消息:" + wxMessage.toString()); - service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson()) - .toUser(wxMessage.getFromUser()).build()); - } - }; - - private static final WxMaMessageHandler textHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) - throws WxErrorException { - service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息") - .toUser(wxMessage.getFromUser()).build()); - } - - }; - - private static final WxMaMessageHandler picHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) throws WxErrorException { - try { - WxMediaUploadResult uploadResult = service.getMediaService() - .uploadMedia(WxMaConstants.MediaType.IMAGE, "png", - ClassLoader.getSystemResourceAsStream("tmp.png")); - service.getMsgService().sendKefuMsg( - WxMaKefuMessage - .newImageBuilder() - .mediaId(uploadResult.getMediaId()) - .toUser(wxMessage.getFromUser()) - .build()); - } catch (WxErrorException e) { - e.printStackTrace(); - } - } - }; - - private static final WxMaMessageHandler qrcodeHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) throws WxErrorException { - try { - final File file = service.getQrcodeService().createQrcode("123", 430); - WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia(WxMaConstants.MediaType.IMAGE, file); - service.getMsgService().sendKefuMsg( - WxMaKefuMessage - .newImageBuilder() - .mediaId(uploadResult.getMediaId()) - .toUser(wxMessage.getFromUser()) - .build()); - } catch (WxErrorException e) { - e.printStackTrace(); - } - } - }; - - private static final WxMaMessageHandler templateMsgHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) - throws WxErrorException { - service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder() - .templateId(templateId).data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"))) - .toUser(wxMessage.getFromUser()) - .formId("自己替换可用的formid") - .build()); - } - - }; - - private static WxMaConfig config; - private static WxMaService service; - private static WxMaMessageRouter router; - private static String templateId; - - public static void main(String[] args) throws Exception { - init(); - - Server server = new Server(8080); - - ServletHandler servletHandler = new ServletHandler(); - server.setHandler(servletHandler); - - ServletHolder endpointServletHolder = new ServletHolder(new WxMaPortalServlet(config, service, router)); - servletHandler.addServletWithMapping(endpointServletHolder, "/*"); - - server.start(); - server.join(); - } - - private static void init() { - try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) { - TestConfig config = TestConfig.fromXml(is1); - config.setAccessTokenLock(new ReentrantLock()); - templateId = config.getTemplateId(); - - WxMaDemoServer.config = config; - service = new WxMaServiceImpl(); - service.setWxMaConfig(config); - - router = new WxMaMessageRouter(service); - - router.rule().handler(logHandler).next() - .rule().async(false).content("模板").handler(templateMsgHandler).end() - .rule().async(false).content("文本").handler(textHandler).end() - .rule().async(false).content("图片").handler(picHandler).end() - .rule().async(false).content("二维码").handler(qrcodeHandler).end(); - } catch (IOException e) { - e.printStackTrace(); - } - } -} +package cn.binarywang.wx.miniapp.demo; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; +import cn.binarywang.wx.miniapp.bean.WxMaMessage; +import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.constant.WxMaConstants; +import cn.binarywang.wx.miniapp.message.WxMaMessageHandler; +import cn.binarywang.wx.miniapp.message.WxMaMessageRouter; +import cn.binarywang.wx.miniapp.test.TestConfig; +import com.google.common.collect.Lists; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.session.WxSessionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author Binary Wang + */ +public class WxMaDemoServer { + + private static final WxMaMessageHandler logHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) throws WxErrorException { + System.out.println("收到消息:" + wxMessage.toString()); + service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson()) + .toUser(wxMessage.getFromUser()).build()); + } + }; + + private static final WxMaMessageHandler textHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) + throws WxErrorException { + service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息") + .toUser(wxMessage.getFromUser()).build()); + } + + }; + + private static final WxMaMessageHandler picHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) throws WxErrorException { + try { + WxMediaUploadResult uploadResult = service.getMediaService() + .uploadMedia(WxMaConstants.MediaType.IMAGE, "png", + ClassLoader.getSystemResourceAsStream("tmp.png")); + service.getMsgService().sendKefuMsg( + WxMaKefuMessage + .newImageBuilder() + .mediaId(uploadResult.getMediaId()) + .toUser(wxMessage.getFromUser()) + .build()); + } catch (WxErrorException e) { + e.printStackTrace(); + } + } + }; + + private static final WxMaMessageHandler qrcodeHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) throws WxErrorException { + try { + final File file = service.getQrcodeService().createQrcode("123", 430); + WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia(WxMaConstants.MediaType.IMAGE, file); + service.getMsgService().sendKefuMsg( + WxMaKefuMessage + .newImageBuilder() + .mediaId(uploadResult.getMediaId()) + .toUser(wxMessage.getFromUser()) + .build()); + } catch (WxErrorException e) { + e.printStackTrace(); + } + } + }; + + private static final WxMaMessageHandler templateMsgHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) + throws WxErrorException { + service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder() + .templateId(templateId).data(Lists.newArrayList( + new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"))) + .toUser(wxMessage.getFromUser()) + .formId("自己替换可用的formid") + .build()); + } + + }; + + private static WxMaConfig config; + private static WxMaService service; + private static WxMaMessageRouter router; + private static String templateId; + + public static void main(String[] args) throws Exception { + init(); + + Server server = new Server(8080); + + ServletHandler servletHandler = new ServletHandler(); + server.setHandler(servletHandler); + + ServletHolder endpointServletHolder = new ServletHolder(new WxMaPortalServlet(config, service, router)); + servletHandler.addServletWithMapping(endpointServletHolder, "/*"); + + server.start(); + server.join(); + } + + private static void init() { + try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) { + TestConfig config = TestConfig.fromXml(is1); + config.setAccessTokenLock(new ReentrantLock()); + templateId = config.getTemplateId(); + + WxMaDemoServer.config = config; + service = new WxMaServiceImpl(); + service.setWxMaConfig(config); + + router = new WxMaMessageRouter(service); + + router.rule().handler(logHandler).next() + .rule().async(false).content("模板").handler(templateMsgHandler).end() + .rule().async(false).content("文本").handler(textHandler).end() + .rule().async(false).content("图片").handler(picHandler).end() + .rule().async(false).content("二维码").handler(qrcodeHandler).end(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 81bf0008c5..0b492b5a82 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -1,84 +1,84 @@ - - - 4.0.0 - - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - - weixin-java-mp - WeiXin Java Tools - MP - 微信公众号Java SDK - - - - com.github.binarywang - weixin-java-common - ${project.version} - - - - org.jodd - jodd-http - provided - - - com.squareup.okhttp3 - okhttp - provided - - - - org.testng - testng - test - - - com.google.inject - guice - test - - - org.eclipse.jetty - jetty-server - test - - - org.eclipse.jetty - jetty-servlet - test - - - joda-time - joda-time - test - - - redis.clients - jedis - - - ch.qos.logback - logback-classic - test - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - src/test/resources/testng.xml - - - - - - - + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + + weixin-java-mp + WeiXin Java Tools - MP + 微信公众号Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + + org.testng + testng + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + joda-time + joda-time + test + + + redis.clients + jedis + + + ch.qos.logback + logback-classic + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java index a7aacd544c..36ca511b6d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java @@ -1,119 +1,119 @@ -package me.chanjar.weixin.mp.api; - -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.*; -import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; - -/** - *
- * 群发消息服务类
- * Created by Binary Wang on 2017-8-16.
- * 
- * - * @author Binary Wang - */ -public interface WxMpMassMessageService { - /** - * 上传群发用的图文消息 - */ - String MEDIA_UPLOAD_NEWS_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; - /** - * 上传群发用的视频 - */ - String MEDIA_UPLOAD_VIDEO_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadvideo"; - /** - * 分组群发消息 - */ - String MESSAGE_MASS_SENDALL_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall"; - /** - * 按openId列表群发消息 - */ - String MESSAGE_MASS_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/send"; - /** - * 群发消息预览接口 - */ - String MESSAGE_MASS_PREVIEW_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/preview"; - /** - * 删除群发接口 - */ - String MESSAGE_MASS_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/delete"; - - /** - *
-   * 上传群发用的图文消息,上传后才能群发图文消息
-   *
-   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- * - * @see #massGroupMessageSend(WxMpMassTagMessage) - * @see #massOpenIdsMessageSend(WxMpMassOpenIdsMessage) - */ - WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException; - - /** - *
-   * 上传群发用的视频,上传后才能群发视频消息
-   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- * - * @see #massGroupMessageSend(WxMpMassTagMessage) - * @see #massOpenIdsMessageSend(WxMpMassOpenIdsMessage) - */ - WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException; - - /** - *
-   * 分组群发消息
-   * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
-   * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
-   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- */ - WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException; - - /** - *
-   * 按openId列表群发消息
-   * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
-   * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
-   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- */ - WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException; - - /** - *
-   * 群发消息预览接口
-   * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100次),请勿滥用。
-   * 接口调用请求说明
-   *  http请求方式: POST
-   *  https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN
-   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- * - * @return wxMpMassSendResult - */ - WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException; - - /** - *
-   * 删除群发
-   * 群发之后,随时可以通过该接口删除群发。
-   * 请注意:
-   * 1、只有已经发送成功的消息才能删除
-   * 2、删除消息是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片。
-   * 3、删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。
-   * 4、如果多次群发发送的是一个图文消息,那么删除其中一次群发,就会删除掉这个图文消息也,导致所有群发都失效
-   * 接口调用请求说明:
-   *  http请求方式: POST
-   *  https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=ACCESS_TOKEN
-   * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1481187827_i0l21
-   * 
- * - * @param msgId 发送出去的消息ID - * @param articleIndex 要删除的文章在图文消息中的位置,第一篇编号为1,该字段不填或填0会删除全部文章 - */ - void delete(Integer msgId, Integer articleIndex) throws WxErrorException; - -} +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; +import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; + +/** + *
+ * 群发消息服务类
+ * Created by Binary Wang on 2017-8-16.
+ * 
+ * + * @author Binary Wang + */ +public interface WxMpMassMessageService { + /** + * 上传群发用的图文消息 + */ + String MEDIA_UPLOAD_NEWS_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; + /** + * 上传群发用的视频 + */ + String MEDIA_UPLOAD_VIDEO_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadvideo"; + /** + * 分组群发消息 + */ + String MESSAGE_MASS_SENDALL_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall"; + /** + * 按openId列表群发消息 + */ + String MESSAGE_MASS_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/send"; + /** + * 群发消息预览接口 + */ + String MESSAGE_MASS_PREVIEW_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/preview"; + /** + * 删除群发接口 + */ + String MESSAGE_MASS_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/delete"; + + /** + *
+   * 上传群发用的图文消息,上传后才能群发图文消息
+   *
+   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ * + * @see #massGroupMessageSend(WxMpMassTagMessage) + * @see #massOpenIdsMessageSend(WxMpMassOpenIdsMessage) + */ + WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException; + + /** + *
+   * 上传群发用的视频,上传后才能群发视频消息
+   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ * + * @see #massGroupMessageSend(WxMpMassTagMessage) + * @see #massOpenIdsMessageSend(WxMpMassOpenIdsMessage) + */ + WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException; + + /** + *
+   * 分组群发消息
+   * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
+   * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
+   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ */ + WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException; + + /** + *
+   * 按openId列表群发消息
+   * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
+   * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
+   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ */ + WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException; + + /** + *
+   * 群发消息预览接口
+   * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100次),请勿滥用。
+   * 接口调用请求说明
+   *  http请求方式: POST
+   *  https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN
+   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ * + * @return wxMpMassSendResult + */ + WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException; + + /** + *
+   * 删除群发
+   * 群发之后,随时可以通过该接口删除群发。
+   * 请注意:
+   * 1、只有已经发送成功的消息才能删除
+   * 2、删除消息是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片。
+   * 3、删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。
+   * 4、如果多次群发发送的是一个图文消息,那么删除其中一次群发,就会删除掉这个图文消息也,导致所有群发都失效
+   * 接口调用请求说明:
+   *  http请求方式: POST
+   *  https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=ACCESS_TOKEN
+   * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1481187827_i0l21
+   * 
+ * + * @param msgId 发送出去的消息ID + * @param articleIndex 要删除的文章在图文消息中的位置,第一篇编号为1,该字段不填或填0会删除全部文章 + */ + void delete(Integer msgId, Integer articleIndex) throws WxErrorException; + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java index 697bfe899d..3d423b0feb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java @@ -1,61 +1,61 @@ -package me.chanjar.weixin.mp.api; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; -import me.chanjar.weixin.mp.bean.WxMpShakeQuery; -import me.chanjar.weixin.mp.bean.shake.*; - -/** - * 摇一摇周边的相关接口 - * - * @author rememberber - */ -public interface WxMpShakeService { - - /** - *
-   * 获取设备及用户信息
- * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 - * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963 - * http请求方式: POST(请使用https协议) - * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE - *
- * - * @param wxMpShakeQuery 查询参数 - */ - WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException; - - /** - *
-   * 页面管理
- * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459246752 - *
- * @param shakeAroundPageAddQuery - * @return - * @throws WxErrorException - */ - WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException; - - /** - *
-   * 配置设备与页面的关联关系
- * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459301931 - *
- * @param shakeAroundDeviceBindPageQuery - * @return - * @throws WxErrorException - */ - WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException; - - /** - *
-   * 查询设备与页面的关联关系
- * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443447914 - *
- * @param shakeAroundRelationSearchQuery - * @return - * @throws WxErrorException - */ - WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException; -} +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; +import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; + +/** + * 摇一摇周边的相关接口 + * + * @author rememberber + */ +public interface WxMpShakeService { + + /** + *
+   * 获取设备及用户信息
+ * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 + * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963 + * http请求方式: POST(请使用https协议) + * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE + *
+ * + * @param wxMpShakeQuery 查询参数 + */ + WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException; + + /** + *
+   * 页面管理
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459246752 + *
+ * @param shakeAroundPageAddQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException; + + /** + *
+   * 配置设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459301931 + *
+ * @param shakeAroundDeviceBindPageQuery + * @return + * @throws WxErrorException + */ + WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException; + + /** + *
+   * 查询设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443447914 + *
+ * @param shakeAroundRelationSearchQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java index 49ed7589f3..4fe596442c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java @@ -1,239 +1,239 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; -import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.bean.WxCardApiSignature; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.RandomUtils; -import me.chanjar.weixin.common.util.crypto.SHA1; -import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; -import me.chanjar.weixin.mp.api.WxMpCardService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpCardResult; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; -import java.util.concurrent.locks.Lock; - -/** - * Created by Binary Wang on 2016/7/27. - */ -public class WxMpCardServiceImpl implements WxMpCardService { - - private final Logger log = LoggerFactory.getLogger(WxMpCardServiceImpl.class); - - private WxMpService wxMpService; - - public WxMpCardServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public WxMpService getWxMpService() { - return this.wxMpService; - } - - /** - * 获得卡券api_ticket,不强制刷新卡券api_ticket - * - * @return 卡券api_ticket - * @see #getCardApiTicket(boolean) - */ - @Override - public String getCardApiTicket() throws WxErrorException { - return getCardApiTicket(false); - } - - /** - *
-   * 获得卡券api_ticket
-   * 获得时会检查卡券apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
-   *
-   * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
-   * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
-   * .9F.E6.88.90.E7.AE.97.E6.B3.95
-   * 
- * - * @param forceRefresh 强制刷新 - * @return 卡券api_ticket - */ - @Override - public String getCardApiTicket(boolean forceRefresh) throws WxErrorException { - Lock lock = getWxMpService().getWxMpConfigStorage().getCardApiTicketLock(); - try { - lock.lock(); - - if (forceRefresh) { - this.getWxMpService().getWxMpConfigStorage().expireCardApiTicket(); - } - - if (this.getWxMpService().getWxMpConfigStorage().isCardApiTicketExpired()) { - String responseContent = this.wxMpService.execute(SimpleGetRequestExecutor.create(this.getWxMpService().getRequestHttp()), CARD_GET_TICKET, null); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); - String cardApiTicket = tmpJsonObject.get("ticket").getAsString(); - int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); - this.getWxMpService().getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds); - } - } finally { - lock.unlock(); - } - return this.getWxMpService().getWxMpConfigStorage().getCardApiTicket(); - } - - /** - *
-   * 创建调用卡券api时所需要的签名
-   *
-   * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
-   * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
-   * .9F.E6.88.90.E7.AE.97.E6.B3.95
-   * 
- * - * @param optionalSignParam 参与签名的参数数组。 - * 可以为下列字段:app_id, card_id, card_type, code, openid, location_id - *
注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空 - * @return 卡券Api签名对象 - */ - @Override - public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws - WxErrorException { - long timestamp = System.currentTimeMillis() / 1000; - String nonceStr = RandomUtils.getRandomStr(); - String cardApiTicket = getCardApiTicket(false); - - String[] signParam = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3); - signParam[optionalSignParam.length] = String.valueOf(timestamp); - signParam[optionalSignParam.length + 1] = nonceStr; - signParam[optionalSignParam.length + 2] = cardApiTicket; - String signature = SHA1.gen(signParam); - WxCardApiSignature cardApiSignature = new WxCardApiSignature(); - cardApiSignature.setTimestamp(timestamp); - cardApiSignature.setNonceStr(nonceStr); - cardApiSignature.setSignature(signature); - return cardApiSignature; - } - - /** - * 卡券Code解码 - * - * @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得 - * @return 解密后的Code - */ - @Override - public String decryptCardCode(String encryptCode) throws WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("encrypt_code", encryptCode); - String responseContent = this.wxMpService.post(CARD_CODE_DECRYPT, param.toString()); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); - JsonPrimitive jsonPrimitive = tmpJsonObject.getAsJsonPrimitive("code"); - return jsonPrimitive.getAsString(); - } - - /** - * 卡券Code查询 - * - * @param cardId 卡券ID代表一类卡券 - * @param code 单张卡券的唯一标准 - * @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同 - * @return WxMpCardResult对象 - */ - @Override - public WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume) throws WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("card_id", cardId); - param.addProperty("code", code); - param.addProperty("check_consume", checkConsume); - String responseContent = this.wxMpService.post(CARD_CODE_GET, param.toString()); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, - new TypeToken() { - }.getType()); - } - - /** - * 卡券Code核销。核销失败会抛出异常 - * - * @param code 单张卡券的唯一标准 - * @return 调用返回的JSON字符串。 - *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 - */ - @Override - public String consumeCardCode(String code) throws WxErrorException { - return consumeCardCode(code, null); - } - - /** - * 卡券Code核销。核销失败会抛出异常 - * - * @param code 单张卡券的唯一标准 - * @param cardId 当自定义Code卡券时需要传入card_id - * @return 调用返回的JSON字符串。 - *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 - */ - @Override - public String consumeCardCode(String code, String cardId) throws WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("code", code); - - if (cardId != null && !"".equals(cardId)) { - param.addProperty("card_id", cardId); - } - - return this.wxMpService.post(CARD_CODE_CONSUME, param.toString()); - } - - /** - * 卡券Mark接口。 - * 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住), - * 才能进一步调用核销接口,否则报错。 - * - * @param code 卡券的code码 - * @param cardId 卡券的ID - * @param openId 用券用户的openid - * @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用 - */ - @Override - public void markCardCode(String code, String cardId, String openId, boolean isMark) throws - WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("code", code); - param.addProperty("card_id", cardId); - param.addProperty("openid", openId); - param.addProperty("is_mark", isMark); - String responseContent = this.getWxMpService().post(CARD_CODE_MARK, param.toString()); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - WxMpCardResult cardResult = WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, - new TypeToken() { - }.getType()); - if (!cardResult.getErrorCode().equals("0")) { - this.log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg()); - } - } - - @Override - public String getCardDetail(String cardId) throws WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("card_id", cardId); - String responseContent = this.wxMpService.post(CARD_GET, param.toString()); - - // 判断返回值 - JsonObject json = (new JsonParser()).parse(responseContent).getAsJsonObject(); - String errcode = json.get("errcode").getAsString(); - if (!"0".equals(errcode)) { - String errmsg = json.get("errmsg").getAsString(); - throw new WxErrorException(WxError.builder() - .errorCode(Integer.valueOf(errcode)).errorMsg(errmsg) - .build()); - } - - return responseContent; - } -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.bean.WxCardApiSignature; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.RandomUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; +import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; +import me.chanjar.weixin.mp.api.WxMpCardService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpCardResult; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.concurrent.locks.Lock; + +/** + * Created by Binary Wang on 2016/7/27. + */ +public class WxMpCardServiceImpl implements WxMpCardService { + + private final Logger log = LoggerFactory.getLogger(WxMpCardServiceImpl.class); + + private WxMpService wxMpService; + + public WxMpCardServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMpService getWxMpService() { + return this.wxMpService; + } + + /** + * 获得卡券api_ticket,不强制刷新卡券api_ticket + * + * @return 卡券api_ticket + * @see #getCardApiTicket(boolean) + */ + @Override + public String getCardApiTicket() throws WxErrorException { + return getCardApiTicket(false); + } + + /** + *
+   * 获得卡券api_ticket
+   * 获得时会检查卡券apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
+   *
+   * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
+   * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
+   * .9F.E6.88.90.E7.AE.97.E6.B3.95
+   * 
+ * + * @param forceRefresh 强制刷新 + * @return 卡券api_ticket + */ + @Override + public String getCardApiTicket(boolean forceRefresh) throws WxErrorException { + Lock lock = getWxMpService().getWxMpConfigStorage().getCardApiTicketLock(); + try { + lock.lock(); + + if (forceRefresh) { + this.getWxMpService().getWxMpConfigStorage().expireCardApiTicket(); + } + + if (this.getWxMpService().getWxMpConfigStorage().isCardApiTicketExpired()) { + String responseContent = this.wxMpService.execute(SimpleGetRequestExecutor.create(this.getWxMpService().getRequestHttp()), CARD_GET_TICKET, null); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); + String cardApiTicket = tmpJsonObject.get("ticket").getAsString(); + int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); + this.getWxMpService().getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds); + } + } finally { + lock.unlock(); + } + return this.getWxMpService().getWxMpConfigStorage().getCardApiTicket(); + } + + /** + *
+   * 创建调用卡券api时所需要的签名
+   *
+   * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
+   * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
+   * .9F.E6.88.90.E7.AE.97.E6.B3.95
+   * 
+ * + * @param optionalSignParam 参与签名的参数数组。 + * 可以为下列字段:app_id, card_id, card_type, code, openid, location_id + *
注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空 + * @return 卡券Api签名对象 + */ + @Override + public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws + WxErrorException { + long timestamp = System.currentTimeMillis() / 1000; + String nonceStr = RandomUtils.getRandomStr(); + String cardApiTicket = getCardApiTicket(false); + + String[] signParam = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3); + signParam[optionalSignParam.length] = String.valueOf(timestamp); + signParam[optionalSignParam.length + 1] = nonceStr; + signParam[optionalSignParam.length + 2] = cardApiTicket; + String signature = SHA1.gen(signParam); + WxCardApiSignature cardApiSignature = new WxCardApiSignature(); + cardApiSignature.setTimestamp(timestamp); + cardApiSignature.setNonceStr(nonceStr); + cardApiSignature.setSignature(signature); + return cardApiSignature; + } + + /** + * 卡券Code解码 + * + * @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得 + * @return 解密后的Code + */ + @Override + public String decryptCardCode(String encryptCode) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("encrypt_code", encryptCode); + String responseContent = this.wxMpService.post(CARD_CODE_DECRYPT, param.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); + JsonPrimitive jsonPrimitive = tmpJsonObject.getAsJsonPrimitive("code"); + return jsonPrimitive.getAsString(); + } + + /** + * 卡券Code查询 + * + * @param cardId 卡券ID代表一类卡券 + * @param code 单张卡券的唯一标准 + * @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同 + * @return WxMpCardResult对象 + */ + @Override + public WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("card_id", cardId); + param.addProperty("code", code); + param.addProperty("check_consume", checkConsume); + String responseContent = this.wxMpService.post(CARD_CODE_GET, param.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, + new TypeToken() { + }.getType()); + } + + /** + * 卡券Code核销。核销失败会抛出异常 + * + * @param code 单张卡券的唯一标准 + * @return 调用返回的JSON字符串。 + *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 + */ + @Override + public String consumeCardCode(String code) throws WxErrorException { + return consumeCardCode(code, null); + } + + /** + * 卡券Code核销。核销失败会抛出异常 + * + * @param code 单张卡券的唯一标准 + * @param cardId 当自定义Code卡券时需要传入card_id + * @return 调用返回的JSON字符串。 + *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 + */ + @Override + public String consumeCardCode(String code, String cardId) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("code", code); + + if (cardId != null && !"".equals(cardId)) { + param.addProperty("card_id", cardId); + } + + return this.wxMpService.post(CARD_CODE_CONSUME, param.toString()); + } + + /** + * 卡券Mark接口。 + * 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住), + * 才能进一步调用核销接口,否则报错。 + * + * @param code 卡券的code码 + * @param cardId 卡券的ID + * @param openId 用券用户的openid + * @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用 + */ + @Override + public void markCardCode(String code, String cardId, String openId, boolean isMark) throws + WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("code", code); + param.addProperty("card_id", cardId); + param.addProperty("openid", openId); + param.addProperty("is_mark", isMark); + String responseContent = this.getWxMpService().post(CARD_CODE_MARK, param.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + WxMpCardResult cardResult = WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, + new TypeToken() { + }.getType()); + if (!cardResult.getErrorCode().equals("0")) { + this.log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg()); + } + } + + @Override + public String getCardDetail(String cardId) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("card_id", cardId); + String responseContent = this.wxMpService.post(CARD_GET, param.toString()); + + // 判断返回值 + JsonObject json = (new JsonParser()).parse(responseContent).getAsJsonObject(); + String errcode = json.get("errcode").getAsString(); + if (!"0".equals(errcode)) { + String errmsg = json.get("errmsg").getAsString(); + throw new WxErrorException(WxError.builder() + .errorCode(Integer.valueOf(errcode)).errorMsg(errmsg) + .build()); + } + + return responseContent; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java index 6bda9e5caf..4301bc2c73 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java @@ -1,152 +1,152 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonObject; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; -import me.chanjar.weixin.mp.api.WxMpKefuService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; -import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; -import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest; -import me.chanjar.weixin.mp.bean.kefu.result.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.Date; - -/** - * @author Binary Wang - */ -public class WxMpKefuServiceImpl implements WxMpKefuService { - protected final Logger log = LoggerFactory.getLogger(this.getClass()); - private WxMpService wxMpService; - - public WxMpKefuServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public boolean sendKefuMessage(WxMpKefuMessage message) throws WxErrorException { - String responseContent = this.wxMpService.post(MESSAGE_CUSTOM_SEND, message.toJson()); - return responseContent != null; - } - - @Override - public WxMpKfList kfList() throws WxErrorException { - String responseContent = this.wxMpService.get(GET_KF_LIST, null); - return WxMpKfList.fromJson(responseContent); - } - - @Override - public WxMpKfOnlineList kfOnlineList() throws WxErrorException { - String responseContent = this.wxMpService.get(GET_ONLINE_KF_LIST, null); - return WxMpKfOnlineList.fromJson(responseContent); - } - - @Override - public boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException { - String responseContent = this.wxMpService.post(KFACCOUNT_ADD, request.toJson()); - return responseContent != null; - } - - @Override - public boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException { - String responseContent = this.wxMpService.post(KFACCOUNT_UPDATE, request.toJson()); - return responseContent != null; - } - - @Override - public boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException { - String responseContent = this.wxMpService.post(KFACCOUNT_INVITE_WORKER, request.toJson()); - return responseContent != null; - } - - @Override - public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException { - WxMediaUploadResult responseContent = this.wxMpService - .execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), String.format(KFACCOUNT_UPLOAD_HEAD_IMG, kfAccount), imgFile); - return responseContent != null; - } - - @Override - public boolean kfAccountDel(String kfAccount) throws WxErrorException { - String responseContent = this.wxMpService.get(String.format(KFACCOUNT_DEL, kfAccount), null); - return responseContent != null; - } - - @Override - public boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException { - WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); - String responseContent = this.wxMpService.post(KFSESSION_CREATE, request.toJson()); - return responseContent != null; - } - - @Override - public boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException { - WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); - String responseContent = this.wxMpService.post(KFSESSION_CLOSE, request.toJson()); - return responseContent != null; - } - - @Override - public WxMpKfSessionGetResult kfSessionGet(String openid) throws WxErrorException { - String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION, openid), null); - return WxMpKfSessionGetResult.fromJson(responseContent); - } - - @Override - public WxMpKfSessionList kfSessionList(String kfAccount) throws WxErrorException { - String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION_LIST, kfAccount), null); - return WxMpKfSessionList.fromJson(responseContent); - } - - @Override - public WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException { - String responseContent = this.wxMpService.get(KFSESSION_GET_WAIT_CASE, null); - return WxMpKfSessionWaitCaseList.fromJson(responseContent); - } - - @Override - public WxMpKfMsgList kfMsgList(Date startTime, Date endTime, Long msgId, Integer number) throws WxErrorException { - if (number > 10000) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法参数请求,每次最多查询10000条记录!").build()); - } - - if (startTime.after(endTime)) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("起始时间不能晚于结束时间!").build()); - } - - JsonObject param = new JsonObject(); - param.addProperty("starttime", startTime.getTime() / 1000); //starttime 起始时间,unix时间戳 - param.addProperty("endtime", endTime.getTime() / 1000); //endtime 结束时间,unix时间戳,每次查询时段不能超过24小时 - param.addProperty("msgid", msgId); //msgid 消息id顺序从小到大,从1开始 - param.addProperty("number", number); //number 每次获取条数,最多10000条 - - String responseContent = this.wxMpService.post(MSGRECORD_GET_MSG_LIST, param.toString()); - - return WxMpKfMsgList.fromJson(responseContent); - } - - @Override - public WxMpKfMsgList kfMsgList(Date startTime, Date endTime) throws WxErrorException { - int number = 10000; - WxMpKfMsgList result = this.kfMsgList(startTime, endTime, 1L, number); - - if (result != null && result.getNumber() == number) { - Long msgId = result.getMsgId(); - WxMpKfMsgList followingResult = this.kfMsgList(startTime, endTime, msgId, number); - while (followingResult != null && followingResult.getRecords().size() > 0) { - result.getRecords().addAll(followingResult.getRecords()); - result.setNumber(result.getNumber() + followingResult.getNumber()); - result.setMsgId(followingResult.getMsgId()); - followingResult = this.kfMsgList(startTime, endTime, followingResult.getMsgId(), number); - } - } - - return result; - } - -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; +import me.chanjar.weixin.mp.api.WxMpKefuService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; +import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; +import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest; +import me.chanjar.weixin.mp.bean.kefu.result.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.Date; + +/** + * @author Binary Wang + */ +public class WxMpKefuServiceImpl implements WxMpKefuService { + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + private WxMpService wxMpService; + + public WxMpKefuServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public boolean sendKefuMessage(WxMpKefuMessage message) throws WxErrorException { + String responseContent = this.wxMpService.post(MESSAGE_CUSTOM_SEND, message.toJson()); + return responseContent != null; + } + + @Override + public WxMpKfList kfList() throws WxErrorException { + String responseContent = this.wxMpService.get(GET_KF_LIST, null); + return WxMpKfList.fromJson(responseContent); + } + + @Override + public WxMpKfOnlineList kfOnlineList() throws WxErrorException { + String responseContent = this.wxMpService.get(GET_ONLINE_KF_LIST, null); + return WxMpKfOnlineList.fromJson(responseContent); + } + + @Override + public boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException { + String responseContent = this.wxMpService.post(KFACCOUNT_ADD, request.toJson()); + return responseContent != null; + } + + @Override + public boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException { + String responseContent = this.wxMpService.post(KFACCOUNT_UPDATE, request.toJson()); + return responseContent != null; + } + + @Override + public boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException { + String responseContent = this.wxMpService.post(KFACCOUNT_INVITE_WORKER, request.toJson()); + return responseContent != null; + } + + @Override + public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException { + WxMediaUploadResult responseContent = this.wxMpService + .execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), String.format(KFACCOUNT_UPLOAD_HEAD_IMG, kfAccount), imgFile); + return responseContent != null; + } + + @Override + public boolean kfAccountDel(String kfAccount) throws WxErrorException { + String responseContent = this.wxMpService.get(String.format(KFACCOUNT_DEL, kfAccount), null); + return responseContent != null; + } + + @Override + public boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException { + WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); + String responseContent = this.wxMpService.post(KFSESSION_CREATE, request.toJson()); + return responseContent != null; + } + + @Override + public boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException { + WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); + String responseContent = this.wxMpService.post(KFSESSION_CLOSE, request.toJson()); + return responseContent != null; + } + + @Override + public WxMpKfSessionGetResult kfSessionGet(String openid) throws WxErrorException { + String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION, openid), null); + return WxMpKfSessionGetResult.fromJson(responseContent); + } + + @Override + public WxMpKfSessionList kfSessionList(String kfAccount) throws WxErrorException { + String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION_LIST, kfAccount), null); + return WxMpKfSessionList.fromJson(responseContent); + } + + @Override + public WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException { + String responseContent = this.wxMpService.get(KFSESSION_GET_WAIT_CASE, null); + return WxMpKfSessionWaitCaseList.fromJson(responseContent); + } + + @Override + public WxMpKfMsgList kfMsgList(Date startTime, Date endTime, Long msgId, Integer number) throws WxErrorException { + if (number > 10000) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法参数请求,每次最多查询10000条记录!").build()); + } + + if (startTime.after(endTime)) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("起始时间不能晚于结束时间!").build()); + } + + JsonObject param = new JsonObject(); + param.addProperty("starttime", startTime.getTime() / 1000); //starttime 起始时间,unix时间戳 + param.addProperty("endtime", endTime.getTime() / 1000); //endtime 结束时间,unix时间戳,每次查询时段不能超过24小时 + param.addProperty("msgid", msgId); //msgid 消息id顺序从小到大,从1开始 + param.addProperty("number", number); //number 每次获取条数,最多10000条 + + String responseContent = this.wxMpService.post(MSGRECORD_GET_MSG_LIST, param.toString()); + + return WxMpKfMsgList.fromJson(responseContent); + } + + @Override + public WxMpKfMsgList kfMsgList(Date startTime, Date endTime) throws WxErrorException { + int number = 10000; + WxMpKfMsgList result = this.kfMsgList(startTime, endTime, 1L, number); + + if (result != null && result.getNumber() == number) { + Long msgId = result.getMsgId(); + WxMpKfMsgList followingResult = this.kfMsgList(startTime, endTime, msgId, number); + while (followingResult != null && followingResult.getRecords().size() > 0) { + result.getRecords().addAll(followingResult.getRecords()); + result.setNumber(result.getNumber() + followingResult.getNumber()); + result.setMsgId(followingResult.getMsgId()); + followingResult = this.kfMsgList(startTime, endTime, followingResult.getMsgId(), number); + } + } + + return result; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java index 779bbc4d9d..21555628d1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java @@ -1,67 +1,67 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonObject; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpMassMessageService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.*; -import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - *
- * 群发消息服务类
- * Created by Binary Wang on 2017-8-16.
- * 
- * - * @author Binary Wang - */ -public class WxMpMassMessageServiceImpl implements WxMpMassMessageService { - protected final Logger log = LoggerFactory.getLogger(this.getClass()); - private WxMpService wxMpService; - - public WxMpMassMessageServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException { - String responseContent = this.wxMpService.post(MEDIA_UPLOAD_NEWS_URL, news.toJson()); - return WxMpMassUploadResult.fromJson(responseContent); - } - - @Override - public WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException { - String responseContent = this.wxMpService.post(MEDIA_UPLOAD_VIDEO_URL, video.toJson()); - return WxMpMassUploadResult.fromJson(responseContent); - } - - @Override - public WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException { - String responseContent = this.wxMpService.post(WxMpMassMessageService.MESSAGE_MASS_SENDALL_URL, message.toJson()); - return WxMpMassSendResult.fromJson(responseContent); - } - - @Override - public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException { - String responseContent = this.wxMpService.post(MESSAGE_MASS_SEND_URL, message.toJson()); - return WxMpMassSendResult.fromJson(responseContent); - } - - @Override - public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException { - String responseContent = this.wxMpService.post(MESSAGE_MASS_PREVIEW_URL, wxMpMassPreviewMessage.toJson()); - return WxMpMassSendResult.fromJson(responseContent); - } - - @Override - public void delete(Integer msgId, Integer articleIndex) throws WxErrorException { - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("msg_id", msgId); - jsonObject.addProperty("article_idx", articleIndex); - this.wxMpService.post(MESSAGE_MASS_DELETE_URL, jsonObject.toString()); - } - -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpMassMessageService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; +import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *
+ * 群发消息服务类
+ * Created by Binary Wang on 2017-8-16.
+ * 
+ * + * @author Binary Wang + */ +public class WxMpMassMessageServiceImpl implements WxMpMassMessageService { + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + private WxMpService wxMpService; + + public WxMpMassMessageServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException { + String responseContent = this.wxMpService.post(MEDIA_UPLOAD_NEWS_URL, news.toJson()); + return WxMpMassUploadResult.fromJson(responseContent); + } + + @Override + public WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException { + String responseContent = this.wxMpService.post(MEDIA_UPLOAD_VIDEO_URL, video.toJson()); + return WxMpMassUploadResult.fromJson(responseContent); + } + + @Override + public WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException { + String responseContent = this.wxMpService.post(WxMpMassMessageService.MESSAGE_MASS_SENDALL_URL, message.toJson()); + return WxMpMassSendResult.fromJson(responseContent); + } + + @Override + public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException { + String responseContent = this.wxMpService.post(MESSAGE_MASS_SEND_URL, message.toJson()); + return WxMpMassSendResult.fromJson(responseContent); + } + + @Override + public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException { + String responseContent = this.wxMpService.post(MESSAGE_MASS_PREVIEW_URL, wxMpMassPreviewMessage.toJson()); + return WxMpMassSendResult.fromJson(responseContent); + } + + @Override + public void delete(Integer msgId, Integer articleIndex) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("msg_id", msgId); + jsonObject.addProperty("article_idx", articleIndex); + this.wxMpService.post(MESSAGE_MASS_DELETE_URL, jsonObject.toString()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java index 520f69ea0d..e5283a7b28 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java @@ -1,151 +1,151 @@ -package me.chanjar.weixin.mp.api.impl; - -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.fs.FileUtils; -import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; -import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.api.WxMpMaterialService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.material.*; -import me.chanjar.weixin.mp.util.http.*; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -/** - * Created by Binary Wang on 2016/7/21. - */ -public class WxMpMaterialServiceImpl implements WxMpMaterialService { - - private WxMpService wxMpService; - - public WxMpMaterialServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { - try { - return this.mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); - } catch (IOException e) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build(), e); - } - } - - @Override - public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { - String url = String.format(MEDIA_UPLOAD_URL, mediaType); - return this.wxMpService.execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, file); - } - - @Override - public File mediaDownload(String mediaId) throws WxErrorException { - return this.wxMpService.execute( - BaseMediaDownloadRequestExecutor.create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), - MEDIA_GET_URL, - "media_id=" + mediaId); - } - - @Override - public WxMediaImgUploadResult mediaImgUpload(File file) throws WxErrorException { - return this.wxMpService.execute(MediaImgUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), IMG_UPLOAD_URL, file); - } - - @Override - public WxMpMaterialUploadResult materialFileUpload(String mediaType, WxMpMaterial material) throws WxErrorException { - String url = String.format(MATERIAL_ADD_URL, mediaType); - return this.wxMpService.execute(MaterialUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, material); - } - - @Override - public WxMpMaterialUploadResult materialNewsUpload(WxMpMaterialNews news) throws WxErrorException { - if (news == null || news.isEmpty()) { - throw new IllegalArgumentException("news is empty!"); - } - String responseContent = this.wxMpService.post(NEWS_ADD_URL, news.toJson()); - return WxMpMaterialUploadResult.fromJson(responseContent); - } - - @Override - public InputStream materialImageOrVoiceDownload(String mediaId) throws WxErrorException { - return this.wxMpService.execute(MaterialVoiceAndImageDownloadRequestExecutor - .create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), MATERIAL_GET_URL, mediaId); - } - - @Override - public WxMpMaterialVideoInfoResult materialVideoInfo(String mediaId) throws WxErrorException { - return this.wxMpService.execute(MaterialVideoInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId); - } - - @Override - public WxMpMaterialNews materialNewsInfo(String mediaId) throws WxErrorException { - return this.wxMpService.execute(MaterialNewsInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId); - } - - @Override - public boolean materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException { - String responseText = this.wxMpService.post(NEWS_UPDATE_URL, wxMpMaterialArticleUpdate.toJson()); - WxError wxError = WxError.fromJson(responseText); - if (wxError.getErrorCode() == 0) { - return true; - } else { - throw new WxErrorException(wxError); - } - } - - @Override - public boolean materialDelete(String mediaId) throws WxErrorException { - return this.wxMpService.execute(MaterialDeleteRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_DEL_URL, mediaId); - } - - @Override - public WxMpMaterialCountResult materialCount() throws WxErrorException { - String responseText = this.wxMpService.get(MATERIAL_GET_COUNT_URL, null); - WxError wxError = WxError.fromJson(responseText); - if (wxError.getErrorCode() == 0) { - return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialCountResult.class); - } else { - throw new WxErrorException(wxError); - } - } - - @Override - public WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException { - Map params = new HashMap<>(); - params.put("type", WxConsts.MaterialType.NEWS); - params.put("offset", offset); - params.put("count", count); - String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); - WxError wxError = WxError.fromJson(responseText); - if (wxError.getErrorCode() == 0) { - return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialNewsBatchGetResult.class); - } else { - throw new WxErrorException(wxError); - } - } - - @Override - public WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offset, int count) throws WxErrorException { - Map params = new HashMap<>(); - params.put("type", type); - params.put("offset", offset); - params.put("count", count); - String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); - WxError wxError = WxError.fromJson(responseText); - if (wxError.getErrorCode() == 0) { - return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialFileBatchGetResult.class); - } else { - throw new WxErrorException(wxError); - } - } - -} +package me.chanjar.weixin.mp.api.impl; + +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.api.WxMpMaterialService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.material.*; +import me.chanjar.weixin.mp.util.http.*; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Created by Binary Wang on 2016/7/21. + */ +public class WxMpMaterialServiceImpl implements WxMpMaterialService { + + private WxMpService wxMpService; + + public WxMpMaterialServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { + try { + return this.mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); + } catch (IOException e) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build(), e); + } + } + + @Override + public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { + String url = String.format(MEDIA_UPLOAD_URL, mediaType); + return this.wxMpService.execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, file); + } + + @Override + public File mediaDownload(String mediaId) throws WxErrorException { + return this.wxMpService.execute( + BaseMediaDownloadRequestExecutor.create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), + MEDIA_GET_URL, + "media_id=" + mediaId); + } + + @Override + public WxMediaImgUploadResult mediaImgUpload(File file) throws WxErrorException { + return this.wxMpService.execute(MediaImgUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), IMG_UPLOAD_URL, file); + } + + @Override + public WxMpMaterialUploadResult materialFileUpload(String mediaType, WxMpMaterial material) throws WxErrorException { + String url = String.format(MATERIAL_ADD_URL, mediaType); + return this.wxMpService.execute(MaterialUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, material); + } + + @Override + public WxMpMaterialUploadResult materialNewsUpload(WxMpMaterialNews news) throws WxErrorException { + if (news == null || news.isEmpty()) { + throw new IllegalArgumentException("news is empty!"); + } + String responseContent = this.wxMpService.post(NEWS_ADD_URL, news.toJson()); + return WxMpMaterialUploadResult.fromJson(responseContent); + } + + @Override + public InputStream materialImageOrVoiceDownload(String mediaId) throws WxErrorException { + return this.wxMpService.execute(MaterialVoiceAndImageDownloadRequestExecutor + .create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), MATERIAL_GET_URL, mediaId); + } + + @Override + public WxMpMaterialVideoInfoResult materialVideoInfo(String mediaId) throws WxErrorException { + return this.wxMpService.execute(MaterialVideoInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId); + } + + @Override + public WxMpMaterialNews materialNewsInfo(String mediaId) throws WxErrorException { + return this.wxMpService.execute(MaterialNewsInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId); + } + + @Override + public boolean materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException { + String responseText = this.wxMpService.post(NEWS_UPDATE_URL, wxMpMaterialArticleUpdate.toJson()); + WxError wxError = WxError.fromJson(responseText); + if (wxError.getErrorCode() == 0) { + return true; + } else { + throw new WxErrorException(wxError); + } + } + + @Override + public boolean materialDelete(String mediaId) throws WxErrorException { + return this.wxMpService.execute(MaterialDeleteRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_DEL_URL, mediaId); + } + + @Override + public WxMpMaterialCountResult materialCount() throws WxErrorException { + String responseText = this.wxMpService.get(MATERIAL_GET_COUNT_URL, null); + WxError wxError = WxError.fromJson(responseText); + if (wxError.getErrorCode() == 0) { + return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialCountResult.class); + } else { + throw new WxErrorException(wxError); + } + } + + @Override + public WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException { + Map params = new HashMap<>(); + params.put("type", WxConsts.MaterialType.NEWS); + params.put("offset", offset); + params.put("count", count); + String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if (wxError.getErrorCode() == 0) { + return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialNewsBatchGetResult.class); + } else { + throw new WxErrorException(wxError); + } + } + + @Override + public WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offset, int count) throws WxErrorException { + Map params = new HashMap<>(); + params.put("type", type); + params.put("offset", offset); + params.put("count", count); + String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if (wxError.getErrorCode() == 0) { + return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialFileBatchGetResult.class); + } else { + throw new WxErrorException(wxError); + } + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java index f6af96e5f8..0c2ca1b142 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java @@ -1,151 +1,151 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonObject; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpQrcodeService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; -import org.apache.commons.lang3.StringUtils; - -import java.io.File; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; - -/** - * Created by Binary Wang on 2016/7/21. - */ -public class WxMpQrcodeServiceImpl implements WxMpQrcodeService { - private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/qrcode"; - private WxMpService wxMpService; - - public WxMpQrcodeServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds) throws WxErrorException { - if (sceneId == 0) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为0!").build()); - } - - //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 - if (expireSeconds != null && expireSeconds > 2592000) { - throw new WxErrorException(WxError.builder().errorCode(-1) - .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); - } - - if (expireSeconds == null) { - expireSeconds = 30; - } - - String url = API_URL_PREFIX + "/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_SCENE"); - json.addProperty("expire_seconds", expireSeconds); - - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_id", sceneId); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = this.wxMpService.post(url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - - @Override - public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSeconds) throws WxErrorException { - if (StringUtils.isBlank(sceneStr)) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为空!").build()); - } - - //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 - if (expireSeconds != null && expireSeconds > 2592000) { - throw new WxErrorException(WxError.builder().errorCode(-1) - .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); - } - - if (expireSeconds == null) { - expireSeconds = 30; - } - - String url = API_URL_PREFIX + "/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_STR_SCENE"); - json.addProperty("expire_seconds", expireSeconds); - - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_str", sceneStr); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = this.wxMpService.post(url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - - @Override - public WxMpQrCodeTicket qrCodeCreateLastTicket(int sceneId) throws WxErrorException { - if (sceneId < 1 || sceneId > 100000) { - throw new WxErrorException(WxError.builder().errorCode(-1) - .errorMsg("永久二维码的场景值目前只支持1--100000!") - .build()); - } - - String url = API_URL_PREFIX + "/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_LIMIT_SCENE"); - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_id", sceneId); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = this.wxMpService.post(url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - @Override - public WxMpQrCodeTicket qrCodeCreateLastTicket(String sceneStr) throws WxErrorException { - String url = API_URL_PREFIX + "/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_LIMIT_STR_SCENE"); - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_str", sceneStr); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = this.wxMpService.post(url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - @Override - public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { - String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; - return this.wxMpService.execute(QrCodeRequestExecutor.create(this.wxMpService.getRequestHttp()), url, ticket); - } - - @Override - public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException { - String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s"; - try { - String resultUrl = String.format(url, - URLEncoder.encode(ticket, StandardCharsets.UTF_8.name())); - if (needShortUrl) { - return this.wxMpService.shortUrl(resultUrl); - } - - return resultUrl; - } catch (UnsupportedEncodingException e) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build()); - } - } - - @Override - public String qrCodePictureUrl(String ticket) throws WxErrorException { - return qrCodePictureUrl(ticket, false); - } - -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpQrcodeService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +/** + * Created by Binary Wang on 2016/7/21. + */ +public class WxMpQrcodeServiceImpl implements WxMpQrcodeService { + private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/qrcode"; + private WxMpService wxMpService; + + public WxMpQrcodeServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds) throws WxErrorException { + if (sceneId == 0) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为0!").build()); + } + + //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 + if (expireSeconds != null && expireSeconds > 2592000) { + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); + } + + if (expireSeconds == null) { + expireSeconds = 30; + } + + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_SCENE"); + json.addProperty("expire_seconds", expireSeconds); + + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_id", sceneId); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.post(url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + + @Override + public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSeconds) throws WxErrorException { + if (StringUtils.isBlank(sceneStr)) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为空!").build()); + } + + //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 + if (expireSeconds != null && expireSeconds > 2592000) { + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); + } + + if (expireSeconds == null) { + expireSeconds = 30; + } + + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_STR_SCENE"); + json.addProperty("expire_seconds", expireSeconds); + + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_str", sceneStr); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.post(url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + + @Override + public WxMpQrCodeTicket qrCodeCreateLastTicket(int sceneId) throws WxErrorException { + if (sceneId < 1 || sceneId > 100000) { + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("永久二维码的场景值目前只支持1--100000!") + .build()); + } + + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_LIMIT_SCENE"); + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_id", sceneId); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.post(url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + @Override + public WxMpQrCodeTicket qrCodeCreateLastTicket(String sceneStr) throws WxErrorException { + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_LIMIT_STR_SCENE"); + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_str", sceneStr); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.post(url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + @Override + public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { + String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; + return this.wxMpService.execute(QrCodeRequestExecutor.create(this.wxMpService.getRequestHttp()), url, ticket); + } + + @Override + public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException { + String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s"; + try { + String resultUrl = String.format(url, + URLEncoder.encode(ticket, StandardCharsets.UTF_8.name())); + if (needShortUrl) { + return this.wxMpService.shortUrl(resultUrl); + } + + return resultUrl; + } catch (UnsupportedEncodingException e) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build()); + } + } + + @Override + public String qrCodePictureUrl(String ticket) throws WxErrorException { + return qrCodePictureUrl(ticket, false); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java index 420cb25249..c5d71693b0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java @@ -1,469 +1,469 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import me.chanjar.weixin.common.bean.WxJsapiSignature; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.session.StandardSessionManager; -import me.chanjar.weixin.common.session.WxSessionManager; -import me.chanjar.weixin.common.util.RandomUtils; -import me.chanjar.weixin.common.util.crypto.SHA1; -import me.chanjar.weixin.common.util.http.*; -import me.chanjar.weixin.mp.api.*; -import me.chanjar.weixin.mp.bean.*; -import me.chanjar.weixin.mp.bean.result.*; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.concurrent.locks.Lock; - -public abstract class WxMpServiceAbstractImpl implements WxMpService, RequestHttp { - - private static final JsonParser JSON_PARSER = new JsonParser(); - - protected final Logger log = LoggerFactory.getLogger(this.getClass()); - protected WxSessionManager sessionManager = new StandardSessionManager(); - protected WxMpConfigStorage wxMpConfigStorage; - private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); - private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); - private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); - private WxMpUserService userService = new WxMpUserServiceImpl(this); - private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this); - private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); - private WxMpCardService cardService = new WxMpCardServiceImpl(this); - private WxMpStoreService storeService = new WxMpStoreServiceImpl(this); - private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); - private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); - private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); - private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); - private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this); - private WxMpMemberCardService memberCardService = new WxMpMemberCardServiceImpl(this); - private WxMpMassMessageService massMessageService = new WxMpMassMessageServiceImpl(this); - - private int retrySleepMillis = 1000; - private int maxRetryTimes = 5; - - - @Override - public boolean checkSignature(String timestamp, String nonce, String signature) { - try { - return SHA1.gen(this.getWxMpConfigStorage().getToken(), timestamp, nonce) - .equals(signature); - } catch (Exception e) { - this.log.error("Checking signature failed, and the reason is :" + e.getMessage()); - return false; - } - } - - @Override - public String getJsapiTicket() throws WxErrorException { - return getJsapiTicket(false); - } - - @Override - public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { - Lock lock = this.getWxMpConfigStorage().getJsapiTicketLock(); - try { - lock.lock(); - if (forceRefresh) { - this.getWxMpConfigStorage().expireJsapiTicket(); - } - - if (this.getWxMpConfigStorage().isJsapiTicketExpired()) { - String responseContent = execute(SimpleGetRequestExecutor.create(this), WxMpService.GET_JSAPI_TICKET_URL, null); - JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); - JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); - String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); - int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); - this.getWxMpConfigStorage().updateJsapiTicket(jsapiTicket, expiresInSeconds); - } - } finally { - lock.unlock(); - } - return this.getWxMpConfigStorage().getJsapiTicket(); - } - - @Override - public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { - long timestamp = System.currentTimeMillis() / 1000; - String noncestr = RandomUtils.getRandomStr(); - String jsapiTicket = getJsapiTicket(false); - String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, - "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); - WxJsapiSignature jsapiSignature = new WxJsapiSignature(); - jsapiSignature.setAppId(this.getWxMpConfigStorage().getAppId()); - jsapiSignature.setTimestamp(timestamp); - jsapiSignature.setNonceStr(noncestr); - jsapiSignature.setUrl(url); - jsapiSignature.setSignature(signature); - return jsapiSignature; - } - - @Override - public String getAccessToken() throws WxErrorException { - return getAccessToken(false); - } - - @Override - public String shortUrl(String long_url) throws WxErrorException { - JsonObject o = new JsonObject(); - o.addProperty("action", "long2short"); - o.addProperty("long_url", long_url); - String responseContent = this.post(WxMpService.SHORTURL_API_URL, o.toString()); - JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); - return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); - } - - @Override - public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException { - String responseContent = this.post(WxMpService.SEMANTIC_SEMPROXY_SEARCH_URL, semanticQuery.toJson()); - return WxMpSemanticQueryResult.fromJson(responseContent); - } - - @Override - public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) { - return String.format(WxMpService.CONNECT_OAUTH2_AUTHORIZE_URL, - this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); - } - - @Override - public String buildQrConnectUrl(String redirectURI, String scope, String state) { - return String.format(WxMpService.QRCONNECT_URL, - this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); - } - - private WxMpOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException { - try { - RequestExecutor executor = SimpleGetRequestExecutor.create(this); - String responseText = executor.execute(url, null); - return WxMpOAuth2AccessToken.fromJson(responseText); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException { - String url = String.format(WxMpService.OAUTH2_ACCESS_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret(), code); - return this.getOAuth2AccessToken(url); - } - - @Override - public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException { - String url = String.format(WxMpService.OAUTH2_REFRESH_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), refreshToken); - return this.getOAuth2AccessToken(url); - } - - @Override - public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException { - if (lang == null) { - lang = "zh_CN"; - } - - String url = String.format(WxMpService.OAUTH2_USERINFO_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId(), lang); - - try { - RequestExecutor executor = SimpleGetRequestExecutor.create(this); - String responseText = executor.execute(url, null); - return WxMpUser.fromJson(responseText); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken) { - String url = String.format(WxMpService.OAUTH2_VALIDATE_TOKEN_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId()); - - try { - SimpleGetRequestExecutor.create(this).execute(url, null); - } catch (IOException e) { - throw new RuntimeException(e); - } catch (WxErrorException e) { - return false; - } - return true; - } - - @Override - public String[] getCallbackIP() throws WxErrorException { - String responseContent = this.get(WxMpService.GET_CALLBACK_IP_URL, null); - JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); - JsonArray ipList = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray(); - String[] ipArray = new String[ipList.size()]; - for (int i = 0; i < ipList.size(); i++) { - ipArray[i] = ipList.get(i).getAsString(); - } - return ipArray; - } - - @Override - public WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException { - return WxMpCurrentAutoReplyInfo.fromJson(this.get(GET_CURRENT_AUTOREPLY_INFO_URL, null)); - } - - @Override - public String get(String url, String queryParam) throws WxErrorException { - return execute(SimpleGetRequestExecutor.create(this), url, queryParam); - } - - @Override - public String post(String url, String postData) throws WxErrorException { - return execute(SimplePostRequestExecutor.create(this), url, postData); - } - - /** - * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 - */ - public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { - int retryTimes = 0; - do { - try { - return this.executeInternal(executor, uri, data); - } catch (WxErrorException e) { - if (retryTimes + 1 > this.maxRetryTimes) { - this.log.warn("重试达到最大次数【{}】", maxRetryTimes); - //最后一次重试失败后,直接抛出异常,不再等待 - throw new RuntimeException("微信服务端异常,超出重试次数"); - } - - WxError error = e.getError(); - // -1 系统繁忙, 1000ms后重试 - if (error.getErrorCode() == -1) { - int sleepMillis = this.retrySleepMillis * (1 << retryTimes); - try { - this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); - Thread.sleep(sleepMillis); - } catch (InterruptedException e1) { - throw new RuntimeException(e1); - } - } else { - throw e; - } - } - } while (retryTimes++ < this.maxRetryTimes); - - this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); - throw new RuntimeException("微信服务端异常,超出重试次数"); - } - - public synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { - if (uri.contains("access_token=")) { - throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); - } - String accessToken = getAccessToken(false); - - String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken; - - try { - T result = executor.execute(uriWithAccessToken, data); - this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); - return result; - } catch (WxErrorException e) { - WxError error = e.getError(); - /* - * 发生以下情况时尝试刷新access_token - * 40001 获取access_token时AppSecret错误,或者access_token无效 - * 42001 access_token超时 - * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 - */ - if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { - // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token - this.getWxMpConfigStorage().expireAccessToken(); - if (this.getWxMpConfigStorage().autoRefreshToken()) { - return this.execute(executor, uri, data); - } - } - - if (error.getErrorCode() != 0) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); - throw new WxErrorException(error, e); - } - return null; - } catch (IOException e) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); - throw new RuntimeException(e); - } - } - - @Override - public WxMpConfigStorage getWxMpConfigStorage() { - return this.wxMpConfigStorage; - } - - @Override - public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { - this.wxMpConfigStorage = wxConfigProvider; - this.initHttp(); - } - - @Override - public void setRetrySleepMillis(int retrySleepMillis) { - this.retrySleepMillis = retrySleepMillis; - } - - @Override - public void setMaxRetryTimes(int maxRetryTimes) { - this.maxRetryTimes = maxRetryTimes; - } - - @Override - public WxMpKefuService getKefuService() { - return this.kefuService; - } - - @Override - public WxMpMaterialService getMaterialService() { - return this.materialService; - } - - @Override - public WxMpMenuService getMenuService() { - return this.menuService; - } - - @Override - public WxMpUserService getUserService() { - return this.userService; - } - - @Override - public WxMpUserTagService getUserTagService() { - return this.tagService; - } - - @Override - public WxMpQrcodeService getQrcodeService() { - return this.qrCodeService; - } - - @Override - public WxMpCardService getCardService() { - return this.cardService; - } - - @Override - public WxMpDataCubeService getDataCubeService() { - return this.dataCubeService; - } - - @Override - public WxMpUserBlacklistService getBlackListService() { - return this.blackListService; - } - - @Override - public WxMpStoreService getStoreService() { - return this.storeService; - } - - @Override - public WxMpTemplateMsgService getTemplateMsgService() { - return this.templateMsgService; - } - - @Override - public WxMpDeviceService getDeviceService() { - return this.deviceService; - } - - @Override - public WxMpShakeService getShakeService() { - return this.shakeService; - } - - @Override - public WxMpMemberCardService getMemberCardService() { - return this.memberCardService; - } - - @Override - public RequestHttp getRequestHttp() { - return this; - } - - @Override - public WxMpMassMessageService getMassMessageService() { - return this.massMessageService; - } - - @Override - public void setKefuService(WxMpKefuService kefuService) { - this.kefuService = kefuService; - } - - @Override - public void setMaterialService(WxMpMaterialService materialService) { - this.materialService = materialService; - } - - @Override - public void setMenuService(WxMpMenuService menuService) { - this.menuService = menuService; - } - - @Override - public void setUserService(WxMpUserService userService) { - this.userService = userService; - } - - @Override - public void setTagService(WxMpUserTagService tagService) { - this.tagService = tagService; - } - - @Override - public void setQrCodeService(WxMpQrcodeService qrCodeService) { - this.qrCodeService = qrCodeService; - } - - @Override - public void setCardService(WxMpCardService cardService) { - this.cardService = cardService; - } - - @Override - public void setStoreService(WxMpStoreService storeService) { - this.storeService = storeService; - } - - @Override - public void setDataCubeService(WxMpDataCubeService dataCubeService) { - this.dataCubeService = dataCubeService; - } - - @Override - public void setBlackListService(WxMpUserBlacklistService blackListService) { - this.blackListService = blackListService; - } - - @Override - public void setTemplateMsgService(WxMpTemplateMsgService templateMsgService) { - this.templateMsgService = templateMsgService; - } - - @Override - public void setDeviceService(WxMpDeviceService deviceService) { - this.deviceService = deviceService; - } - - @Override - public void setShakeService(WxMpShakeService shakeService) { - this.shakeService = shakeService; - } - - @Override - public void setMemberCardService(WxMpMemberCardService memberCardService) { - this.memberCardService = memberCardService; - } - - @Override - public void setMassMessageService(WxMpMassMessageService massMessageService) { - this.massMessageService = massMessageService; - } -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.session.StandardSessionManager; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.common.util.RandomUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; +import me.chanjar.weixin.common.util.http.*; +import me.chanjar.weixin.mp.api.*; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.*; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.concurrent.locks.Lock; + +public abstract class WxMpServiceAbstractImpl implements WxMpService, RequestHttp { + + private static final JsonParser JSON_PARSER = new JsonParser(); + + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + protected WxSessionManager sessionManager = new StandardSessionManager(); + protected WxMpConfigStorage wxMpConfigStorage; + private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); + private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); + private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); + private WxMpUserService userService = new WxMpUserServiceImpl(this); + private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this); + private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); + private WxMpCardService cardService = new WxMpCardServiceImpl(this); + private WxMpStoreService storeService = new WxMpStoreServiceImpl(this); + private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); + private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); + private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); + private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); + private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this); + private WxMpMemberCardService memberCardService = new WxMpMemberCardServiceImpl(this); + private WxMpMassMessageService massMessageService = new WxMpMassMessageServiceImpl(this); + + private int retrySleepMillis = 1000; + private int maxRetryTimes = 5; + + + @Override + public boolean checkSignature(String timestamp, String nonce, String signature) { + try { + return SHA1.gen(this.getWxMpConfigStorage().getToken(), timestamp, nonce) + .equals(signature); + } catch (Exception e) { + this.log.error("Checking signature failed, and the reason is :" + e.getMessage()); + return false; + } + } + + @Override + public String getJsapiTicket() throws WxErrorException { + return getJsapiTicket(false); + } + + @Override + public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { + Lock lock = this.getWxMpConfigStorage().getJsapiTicketLock(); + try { + lock.lock(); + if (forceRefresh) { + this.getWxMpConfigStorage().expireJsapiTicket(); + } + + if (this.getWxMpConfigStorage().isJsapiTicketExpired()) { + String responseContent = execute(SimpleGetRequestExecutor.create(this), WxMpService.GET_JSAPI_TICKET_URL, null); + JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); + JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); + String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); + int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); + this.getWxMpConfigStorage().updateJsapiTicket(jsapiTicket, expiresInSeconds); + } + } finally { + lock.unlock(); + } + return this.getWxMpConfigStorage().getJsapiTicket(); + } + + @Override + public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { + long timestamp = System.currentTimeMillis() / 1000; + String noncestr = RandomUtils.getRandomStr(); + String jsapiTicket = getJsapiTicket(false); + String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, + "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); + WxJsapiSignature jsapiSignature = new WxJsapiSignature(); + jsapiSignature.setAppId(this.getWxMpConfigStorage().getAppId()); + jsapiSignature.setTimestamp(timestamp); + jsapiSignature.setNonceStr(noncestr); + jsapiSignature.setUrl(url); + jsapiSignature.setSignature(signature); + return jsapiSignature; + } + + @Override + public String getAccessToken() throws WxErrorException { + return getAccessToken(false); + } + + @Override + public String shortUrl(String long_url) throws WxErrorException { + JsonObject o = new JsonObject(); + o.addProperty("action", "long2short"); + o.addProperty("long_url", long_url); + String responseContent = this.post(WxMpService.SHORTURL_API_URL, o.toString()); + JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); + return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); + } + + @Override + public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException { + String responseContent = this.post(WxMpService.SEMANTIC_SEMPROXY_SEARCH_URL, semanticQuery.toJson()); + return WxMpSemanticQueryResult.fromJson(responseContent); + } + + @Override + public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) { + return String.format(WxMpService.CONNECT_OAUTH2_AUTHORIZE_URL, + this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); + } + + @Override + public String buildQrConnectUrl(String redirectURI, String scope, String state) { + return String.format(WxMpService.QRCONNECT_URL, + this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); + } + + private WxMpOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException { + try { + RequestExecutor executor = SimpleGetRequestExecutor.create(this); + String responseText = executor.execute(url, null); + return WxMpOAuth2AccessToken.fromJson(responseText); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException { + String url = String.format(WxMpService.OAUTH2_ACCESS_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret(), code); + return this.getOAuth2AccessToken(url); + } + + @Override + public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException { + String url = String.format(WxMpService.OAUTH2_REFRESH_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), refreshToken); + return this.getOAuth2AccessToken(url); + } + + @Override + public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException { + if (lang == null) { + lang = "zh_CN"; + } + + String url = String.format(WxMpService.OAUTH2_USERINFO_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId(), lang); + + try { + RequestExecutor executor = SimpleGetRequestExecutor.create(this); + String responseText = executor.execute(url, null); + return WxMpUser.fromJson(responseText); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken) { + String url = String.format(WxMpService.OAUTH2_VALIDATE_TOKEN_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId()); + + try { + SimpleGetRequestExecutor.create(this).execute(url, null); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (WxErrorException e) { + return false; + } + return true; + } + + @Override + public String[] getCallbackIP() throws WxErrorException { + String responseContent = this.get(WxMpService.GET_CALLBACK_IP_URL, null); + JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); + JsonArray ipList = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray(); + String[] ipArray = new String[ipList.size()]; + for (int i = 0; i < ipList.size(); i++) { + ipArray[i] = ipList.get(i).getAsString(); + } + return ipArray; + } + + @Override + public WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException { + return WxMpCurrentAutoReplyInfo.fromJson(this.get(GET_CURRENT_AUTOREPLY_INFO_URL, null)); + } + + @Override + public String get(String url, String queryParam) throws WxErrorException { + return execute(SimpleGetRequestExecutor.create(this), url, queryParam); + } + + @Override + public String post(String url, String postData) throws WxErrorException { + return execute(SimplePostRequestExecutor.create(this), url, postData); + } + + /** + * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 + */ + public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { + int retryTimes = 0; + do { + try { + return this.executeInternal(executor, uri, data); + } catch (WxErrorException e) { + if (retryTimes + 1 > this.maxRetryTimes) { + this.log.warn("重试达到最大次数【{}】", maxRetryTimes); + //最后一次重试失败后,直接抛出异常,不再等待 + throw new RuntimeException("微信服务端异常,超出重试次数"); + } + + WxError error = e.getError(); + // -1 系统繁忙, 1000ms后重试 + if (error.getErrorCode() == -1) { + int sleepMillis = this.retrySleepMillis * (1 << retryTimes); + try { + this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); + Thread.sleep(sleepMillis); + } catch (InterruptedException e1) { + throw new RuntimeException(e1); + } + } else { + throw e; + } + } + } while (retryTimes++ < this.maxRetryTimes); + + this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); + throw new RuntimeException("微信服务端异常,超出重试次数"); + } + + public synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + if (uri.contains("access_token=")) { + throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); + } + String accessToken = getAccessToken(false); + + String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken; + + try { + T result = executor.execute(uriWithAccessToken, data); + this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); + return result; + } catch (WxErrorException e) { + WxError error = e.getError(); + /* + * 发生以下情况时尝试刷新access_token + * 40001 获取access_token时AppSecret错误,或者access_token无效 + * 42001 access_token超时 + * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 + */ + if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { + // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token + this.getWxMpConfigStorage().expireAccessToken(); + if (this.getWxMpConfigStorage().autoRefreshToken()) { + return this.execute(executor, uri, data); + } + } + + if (error.getErrorCode() != 0) { + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); + throw new WxErrorException(error, e); + } + return null; + } catch (IOException e) { + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); + throw new RuntimeException(e); + } + } + + @Override + public WxMpConfigStorage getWxMpConfigStorage() { + return this.wxMpConfigStorage; + } + + @Override + public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { + this.wxMpConfigStorage = wxConfigProvider; + this.initHttp(); + } + + @Override + public void setRetrySleepMillis(int retrySleepMillis) { + this.retrySleepMillis = retrySleepMillis; + } + + @Override + public void setMaxRetryTimes(int maxRetryTimes) { + this.maxRetryTimes = maxRetryTimes; + } + + @Override + public WxMpKefuService getKefuService() { + return this.kefuService; + } + + @Override + public WxMpMaterialService getMaterialService() { + return this.materialService; + } + + @Override + public WxMpMenuService getMenuService() { + return this.menuService; + } + + @Override + public WxMpUserService getUserService() { + return this.userService; + } + + @Override + public WxMpUserTagService getUserTagService() { + return this.tagService; + } + + @Override + public WxMpQrcodeService getQrcodeService() { + return this.qrCodeService; + } + + @Override + public WxMpCardService getCardService() { + return this.cardService; + } + + @Override + public WxMpDataCubeService getDataCubeService() { + return this.dataCubeService; + } + + @Override + public WxMpUserBlacklistService getBlackListService() { + return this.blackListService; + } + + @Override + public WxMpStoreService getStoreService() { + return this.storeService; + } + + @Override + public WxMpTemplateMsgService getTemplateMsgService() { + return this.templateMsgService; + } + + @Override + public WxMpDeviceService getDeviceService() { + return this.deviceService; + } + + @Override + public WxMpShakeService getShakeService() { + return this.shakeService; + } + + @Override + public WxMpMemberCardService getMemberCardService() { + return this.memberCardService; + } + + @Override + public RequestHttp getRequestHttp() { + return this; + } + + @Override + public WxMpMassMessageService getMassMessageService() { + return this.massMessageService; + } + + @Override + public void setKefuService(WxMpKefuService kefuService) { + this.kefuService = kefuService; + } + + @Override + public void setMaterialService(WxMpMaterialService materialService) { + this.materialService = materialService; + } + + @Override + public void setMenuService(WxMpMenuService menuService) { + this.menuService = menuService; + } + + @Override + public void setUserService(WxMpUserService userService) { + this.userService = userService; + } + + @Override + public void setTagService(WxMpUserTagService tagService) { + this.tagService = tagService; + } + + @Override + public void setQrCodeService(WxMpQrcodeService qrCodeService) { + this.qrCodeService = qrCodeService; + } + + @Override + public void setCardService(WxMpCardService cardService) { + this.cardService = cardService; + } + + @Override + public void setStoreService(WxMpStoreService storeService) { + this.storeService = storeService; + } + + @Override + public void setDataCubeService(WxMpDataCubeService dataCubeService) { + this.dataCubeService = dataCubeService; + } + + @Override + public void setBlackListService(WxMpUserBlacklistService blackListService) { + this.blackListService = blackListService; + } + + @Override + public void setTemplateMsgService(WxMpTemplateMsgService templateMsgService) { + this.templateMsgService = templateMsgService; + } + + @Override + public void setDeviceService(WxMpDeviceService deviceService) { + this.deviceService = deviceService; + } + + @Override + public void setShakeService(WxMpShakeService shakeService) { + this.shakeService = shakeService; + } + + @Override + public void setMemberCardService(WxMpMemberCardService memberCardService) { + this.memberCardService = memberCardService; + } + + @Override + public void setMassMessageService(WxMpMassMessageService massMessageService) { + this.massMessageService = massMessageService; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java index b5135cebcb..0aa9e8eaae 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java @@ -1,93 +1,93 @@ -package me.chanjar.weixin.mp.api.impl; - -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.HttpType; -import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.mp.api.WxMpService; -import okhttp3.*; - -import java.io.IOException; -import java.util.concurrent.locks.Lock; - -public class WxMpServiceOkHttpImpl extends WxMpServiceAbstractImpl { - private OkHttpClient httpClient; - private OkHttpProxyInfo httpProxy; - - @Override - public OkHttpClient getRequestHttpClient() { - return httpClient; - } - - @Override - public OkHttpProxyInfo getRequestHttpProxy() { - return httpProxy; - } - - @Override - public HttpType getRequestType() { - return HttpType.OK_HTTP; - } - - @Override - public String getAccessToken(boolean forceRefresh) throws WxErrorException { - this.log.debug("WxMpServiceOkHttpImpl is running"); - Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); - try { - lock.lock(); - - if (this.getWxMpConfigStorage().isAccessTokenExpired() || forceRefresh) { - String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL, - this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret()); - - Request request = new Request.Builder().url(url).get().build(); - Response response = getRequestHttpClient().newCall(request).execute(); - String resultContent = response.body().string(); - WxError error = WxError.fromJson(resultContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); - this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), - accessToken.getExpiresIn()); - } - } catch (IOException e) { - this.log.error(e.getMessage(), e); - } finally { - lock.unlock(); - } - return this.getWxMpConfigStorage().getAccessToken(); - } - - @Override - public void initHttp() { - this.log.debug("WxMpServiceOkHttpImpl initHttp"); - - //设置代理 - if (wxMpConfigStorage.getHttpProxyHost() != null && wxMpConfigStorage.getHttpProxyPort() > 0) { - httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(), - wxMpConfigStorage.getHttpProxyPort(), - wxMpConfigStorage.getHttpProxyUsername(), - wxMpConfigStorage.getHttpProxyPassword()); - } - - OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); - if (httpProxy != null) { - clientBuilder.proxy(getRequestHttpProxy().getProxy()); - - //设置授权 - clientBuilder.authenticator(new Authenticator() { - @Override - public Request authenticate(Route route, Response response) throws IOException { - String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword()); - return response.request().newBuilder() - .header("Authorization", credential) - .build(); - } - }); - } - httpClient = clientBuilder.build(); - } - -} +package me.chanjar.weixin.mp.api.impl; + +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.HttpType; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.mp.api.WxMpService; +import okhttp3.*; + +import java.io.IOException; +import java.util.concurrent.locks.Lock; + +public class WxMpServiceOkHttpImpl extends WxMpServiceAbstractImpl { + private OkHttpClient httpClient; + private OkHttpProxyInfo httpProxy; + + @Override + public OkHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public OkHttpProxyInfo getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpType getRequestType() { + return HttpType.OK_HTTP; + } + + @Override + public String getAccessToken(boolean forceRefresh) throws WxErrorException { + this.log.debug("WxMpServiceOkHttpImpl is running"); + Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); + try { + lock.lock(); + + if (this.getWxMpConfigStorage().isAccessTokenExpired() || forceRefresh) { + String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL, + this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret()); + + Request request = new Request.Builder().url(url).get().build(); + Response response = getRequestHttpClient().newCall(request).execute(); + String resultContent = response.body().string(); + WxError error = WxError.fromJson(resultContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); + this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), + accessToken.getExpiresIn()); + } + } catch (IOException e) { + this.log.error(e.getMessage(), e); + } finally { + lock.unlock(); + } + return this.getWxMpConfigStorage().getAccessToken(); + } + + @Override + public void initHttp() { + this.log.debug("WxMpServiceOkHttpImpl initHttp"); + + //设置代理 + if (wxMpConfigStorage.getHttpProxyHost() != null && wxMpConfigStorage.getHttpProxyPort() > 0) { + httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(), + wxMpConfigStorage.getHttpProxyPort(), + wxMpConfigStorage.getHttpProxyUsername(), + wxMpConfigStorage.getHttpProxyPassword()); + } + + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + if (httpProxy != null) { + clientBuilder.proxy(getRequestHttpProxy().getProxy()); + + //设置授权 + clientBuilder.authenticator(new Authenticator() { + @Override + public Request authenticate(Route route, Response response) throws IOException { + String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword()); + return response.request().newBuilder() + .header("Authorization", credential) + .build(); + } + }); + } + httpClient = clientBuilder.build(); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java index 2c90f70e2b..f211c9f35c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java @@ -1,66 +1,66 @@ -package me.chanjar.weixin.mp.api.impl; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.WxMpShakeService; -import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; -import me.chanjar.weixin.mp.bean.WxMpShakeQuery; -import me.chanjar.weixin.mp.bean.shake.*; - -/** - * Created by rememberber on 2017/6/5. - * - * @author rememberber - */ -public class WxMpShakeServiceImpl implements WxMpShakeService { - - private WxMpService wxMpService; - - public WxMpShakeServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - /** - *
-   * 获取设备及用户信息
- * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 - * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963 - * http请求方式: POST(请使用https协议) - * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE - *
- * - * @param wxMpShakeQuery 查询参数 - */ - @Override - public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException { - String url = "https://api.weixin.qq.com/shakearound/user/getshakeinfo"; - String postData = wxMpShakeQuery.toJsonString(); - String responseContent = this.wxMpService.post(url, postData); - return WxMpShakeInfoResult.fromJson(responseContent); - } - - @Override - public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException { - String url = "https://api.weixin.qq.com/shakearound/page/add"; - String postData = shakeAroundPageAddQuery.toJsonString(); - String responseContent = this.wxMpService.post(url, postData); - return WxMpShakeAroundPageAddResult.fromJson(responseContent); - } - - @Override - public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException { - String url = "https://api.weixin.qq.com/shakearound/device/bindpage"; - String postData = shakeAroundDeviceBindPageQuery.toJsonString(); - String responseContent = this.wxMpService.post(url, postData); - return WxError.fromJson(responseContent); - } - - @Override - public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException { - String url = "https://api.weixin.qq.com/shakearound/relation/search"; - String postData = shakeAroundRelationSearchQuery.toJsonString(); - String responseContent = this.wxMpService.post(url, postData); - return WxMpShakeAroundRelationSearchResult.fromJson(responseContent); - } -} +package me.chanjar.weixin.mp.api.impl; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpShakeService; +import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; +import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; + +/** + * Created by rememberber on 2017/6/5. + * + * @author rememberber + */ +public class WxMpShakeServiceImpl implements WxMpShakeService { + + private WxMpService wxMpService; + + public WxMpShakeServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + /** + *
+   * 获取设备及用户信息
+ * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 + * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963 + * http请求方式: POST(请使用https协议) + * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE + *
+ * + * @param wxMpShakeQuery 查询参数 + */ + @Override + public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/user/getshakeinfo"; + String postData = wxMpShakeQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeInfoResult.fromJson(responseContent); + } + + @Override + public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/page/add"; + String postData = shakeAroundPageAddQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundPageAddResult.fromJson(responseContent); + } + + @Override + public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/device/bindpage"; + String postData = shakeAroundDeviceBindPageQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxError.fromJson(responseContent); + } + + @Override + public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/relation/search"; + String postData = shakeAroundRelationSearchQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundRelationSearchResult.fromJson(responseContent); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java index 3901c61fbc..7c724537fb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java @@ -1,123 +1,123 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * 图文分析数据接口返回结果对象 - *

- * Created by Binary Wang on 2016/8/24. - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class WxDataCubeArticleResult extends WxDataCubeBaseResult { - private static final long serialVersionUID = -9222452497954511765L; - - /** - * ref_hour - * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 - */ - @SerializedName("ref_hour") - private Integer refHour; - - /** - * msgid - * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id) - * 和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index, - * 假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 - */ - @SerializedName("msgid") - private String msgId; - - /** - * title - * 图文消息的标题 - */ - @SerializedName("title") - private String title; - - /** - * int_page_read_user - * 图文页(点击群发图文卡片进入的页面)的阅读人数 - */ - @SerializedName("int_page_read_user") - private Integer intPageReadUser; - - /** - * int_page_read_count - * 图文页的阅读次数 - */ - @SerializedName("int_page_read_count") - private Integer intPageReadCount; - - /** - * ori_page_read_user - * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 - */ - @SerializedName("ori_page_read_user") - private Integer oriPageReadUser; - - /** - * ori_page_read_count - * 原文页的阅读次数 - */ - @SerializedName("ori_page_read_count") - private Integer oriPageReadCount; - - /** - * share_scene - * 分享的场景 1代表好友转发 2代表朋友圈 3代表腾讯微博 255代表其他 - */ - @SerializedName("share_scene") - private Integer shareScene; - - /** - * share_user - * 分享的人数 - */ - @SerializedName("share_user") - private Integer shareUser; - - /** - * share_count - * 分享的次数 - */ - @SerializedName("share_count") - private Integer shareCount; - - /** - * add_to_fav_user - * 收藏的人数 - */ - @SerializedName("add_to_fav_user") - private Integer addToFavUser; - - /** - * add_to_fav_count - * 收藏的次数 - */ - @SerializedName("add_to_fav_count") - private Integer addToFavCount; - - /** - * user_source - * 在获取图文阅读分时数据时才有该字段,代表用户从哪里进入来阅读该图文。0:会话;1.好友;2.朋友圈;3.腾讯微博;4.历史消息页;5.其他 - */ - @SerializedName("user_source") - private Integer userSource; - - public static List fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson( - JSON_PARSER.parse(json).getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * 图文分析数据接口返回结果对象 + *

+ * Created by Binary Wang on 2016/8/24. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxDataCubeArticleResult extends WxDataCubeBaseResult { + private static final long serialVersionUID = -9222452497954511765L; + + /** + * ref_hour + * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 + */ + @SerializedName("ref_hour") + private Integer refHour; + + /** + * msgid + * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id) + * 和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index, + * 假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 + */ + @SerializedName("msgid") + private String msgId; + + /** + * title + * 图文消息的标题 + */ + @SerializedName("title") + private String title; + + /** + * int_page_read_user + * 图文页(点击群发图文卡片进入的页面)的阅读人数 + */ + @SerializedName("int_page_read_user") + private Integer intPageReadUser; + + /** + * int_page_read_count + * 图文页的阅读次数 + */ + @SerializedName("int_page_read_count") + private Integer intPageReadCount; + + /** + * ori_page_read_user + * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 + */ + @SerializedName("ori_page_read_user") + private Integer oriPageReadUser; + + /** + * ori_page_read_count + * 原文页的阅读次数 + */ + @SerializedName("ori_page_read_count") + private Integer oriPageReadCount; + + /** + * share_scene + * 分享的场景 1代表好友转发 2代表朋友圈 3代表腾讯微博 255代表其他 + */ + @SerializedName("share_scene") + private Integer shareScene; + + /** + * share_user + * 分享的人数 + */ + @SerializedName("share_user") + private Integer shareUser; + + /** + * share_count + * 分享的次数 + */ + @SerializedName("share_count") + private Integer shareCount; + + /** + * add_to_fav_user + * 收藏的人数 + */ + @SerializedName("add_to_fav_user") + private Integer addToFavUser; + + /** + * add_to_fav_count + * 收藏的次数 + */ + @SerializedName("add_to_fav_count") + private Integer addToFavCount; + + /** + * user_source + * 在获取图文阅读分时数据时才有该字段,代表用户从哪里进入来阅读该图文。0:会话;1.好友;2.朋友圈;3.腾讯微博;4.历史消息页;5.其他 + */ + @SerializedName("user_source") + private Integer userSource; + + public static List fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java index bef0e66d15..6c63e83231 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java @@ -1,50 +1,50 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * 图文分析数据接口返回结果对象. - * Created by Binary Wang on 2016/8/24. - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class WxDataCubeArticleTotal extends WxDataCubeBaseResult { - private static final long serialVersionUID = -7634365687303052699L; - - /** - * msgid. - * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id)和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index,假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 - */ - @SerializedName("msgid") - private String msgId; - - /** - * title. - * 图文消息的标题 - */ - @SerializedName("title") - private String title; - - /** - * details. - * 详细信息 - */ - @SerializedName("details") - private List details; - - public static List fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson( - JSON_PARSER.parse(json).getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * 图文分析数据接口返回结果对象. + * Created by Binary Wang on 2016/8/24. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxDataCubeArticleTotal extends WxDataCubeBaseResult { + private static final long serialVersionUID = -7634365687303052699L; + + /** + * msgid. + * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id)和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index,假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 + */ + @SerializedName("msgid") + private String msgId; + + /** + * title. + * 图文消息的标题 + */ + @SerializedName("title") + private String title; + + /** + * details. + * 详细信息 + */ + @SerializedName("details") + private List details; + + public static List fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java index df86ab4e15..8af64015b7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java @@ -1,35 +1,35 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.JsonParser; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; - -/** - *

- *  统计接口的共用属性类.
- *  Created by Binary Wang on 2016/8/25.
- * 
- * - * @author Binary Wang - */ -@Data -public abstract class WxDataCubeBaseResult implements Serializable { - private static final long serialVersionUID = 8780389911053297600L; - protected static final JsonParser JSON_PARSER = new JsonParser(); - - /** - * ref_date. - * 数据的日期,需在begin_date和end_date之间 - */ - @SerializedName("ref_date") - private String refDate; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; + +import java.io.Serializable; + +/** + *
+ *  统计接口的共用属性类.
+ *  Created by Binary Wang on 2016/8/25.
+ * 
+ * + * @author Binary Wang + */ +@Data +public abstract class WxDataCubeBaseResult implements Serializable { + private static final long serialVersionUID = 8780389911053297600L; + protected static final JsonParser JSON_PARSER = new JsonParser(); + + /** + * ref_date. + * 数据的日期,需在begin_date和end_date之间 + */ + @SerializedName("ref_date") + private String refDate; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java index b151c0089f..cf77b28575 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java @@ -1,65 +1,65 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * 接口分析数据接口返回结果对象 - *

- * Created by Binary Wang on 2016/8/30. - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult { - private static final long serialVersionUID = 597734329161281398L; - - /** - * ref_hour - * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 - */ - @SerializedName("ref_hour") - private Integer refHour; - - /** - * callback_count - * 通过服务器配置地址获得消息后,被动回复用户消息的次数 - */ - @SerializedName("callback_count") - private Integer callbackCount; - - /** - * fail_count - * 上述动作的失败次数 - */ - @SerializedName("fail_count") - private Integer failCount; - - /** - * total_time_cost - * 总耗时,除以callback_count即为平均耗时 - */ - @SerializedName("total_time_cost") - private Integer totalTimeCost; - - /** - * max_time_cost - * 最大耗时 - */ - @SerializedName("max_time_cost") - private Integer maxTimeCost; - - public static List fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson( - JSON_PARSER.parse(json).getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * 接口分析数据接口返回结果对象 + *

+ * Created by Binary Wang on 2016/8/30. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult { + private static final long serialVersionUID = 597734329161281398L; + + /** + * ref_hour + * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 + */ + @SerializedName("ref_hour") + private Integer refHour; + + /** + * callback_count + * 通过服务器配置地址获得消息后,被动回复用户消息的次数 + */ + @SerializedName("callback_count") + private Integer callbackCount; + + /** + * fail_count + * 上述动作的失败次数 + */ + @SerializedName("fail_count") + private Integer failCount; + + /** + * total_time_cost + * 总耗时,除以callback_count即为平均耗时 + */ + @SerializedName("total_time_cost") + private Integer totalTimeCost; + + /** + * max_time_cost + * 最大耗时 + */ + @SerializedName("max_time_cost") + private Integer maxTimeCost; + + public static List fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java index 1e7e1f58c2..a786605c9e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java @@ -1,78 +1,78 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * 消息分析数据接口返回结果对象. - * Created by Binary Wang on 2016/8/29. - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class WxDataCubeMsgResult extends WxDataCubeBaseResult { - private static final long serialVersionUID = 6932121822150573659L; - - /** - * ref_hour. - * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 - */ - @SerializedName("ref_hour") - private Integer refHour; - - /** - * msg_type. - * 消息类型,代表含义如下:1代表文字 2代表图片 3代表语音 4代表视频 6代表第三方应用消息(链接消息) - */ - @SerializedName("msg_type") - private Integer msgType; - - /** - * msg_user. - * 上行发送了(向公众号发送了)消息的用户数 - */ - @SerializedName("msg_user") - private Integer msgUser; - - /** - * msg_count. - * 上行发送了消息的消息总数 - */ - @SerializedName("msg_count") - private Integer msgCount; - - /** - * count_interval. - * 当日发送消息量分布的区间,0代表 “0”,1代表“1-5”,2代表“6-10”,3代表“10次以上” - */ - @SerializedName("count_interval") - private Integer countInterval; - - /** - * int_page_read_count - * 图文页的阅读次数 - */ - @SerializedName("int_page_read_count") - private Integer intPageReadCount; - - /** - * ori_page_read_user. - * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 - */ - @SerializedName("ori_page_read_user") - private Integer oriPageReadUser; - - public static List fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson( - JSON_PARSER.parse(json).getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * 消息分析数据接口返回结果对象. + * Created by Binary Wang on 2016/8/29. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxDataCubeMsgResult extends WxDataCubeBaseResult { + private static final long serialVersionUID = 6932121822150573659L; + + /** + * ref_hour. + * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 + */ + @SerializedName("ref_hour") + private Integer refHour; + + /** + * msg_type. + * 消息类型,代表含义如下:1代表文字 2代表图片 3代表语音 4代表视频 6代表第三方应用消息(链接消息) + */ + @SerializedName("msg_type") + private Integer msgType; + + /** + * msg_user. + * 上行发送了(向公众号发送了)消息的用户数 + */ + @SerializedName("msg_user") + private Integer msgUser; + + /** + * msg_count. + * 上行发送了消息的消息总数 + */ + @SerializedName("msg_count") + private Integer msgCount; + + /** + * count_interval. + * 当日发送消息量分布的区间,0代表 “0”,1代表“1-5”,2代表“6-10”,3代表“10次以上” + */ + @SerializedName("count_interval") + private Integer countInterval; + + /** + * int_page_read_count + * 图文页的阅读次数 + */ + @SerializedName("int_page_read_count") + private Integer intPageReadCount; + + /** + * ori_page_read_user. + * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 + */ + @SerializedName("ori_page_read_user") + private Integer oriPageReadUser; + + public static List fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java index 5c66b0cd60..207c1921b8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java @@ -1,31 +1,31 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class BaseResp extends AbstractDeviceBean { - private static final long serialVersionUID = 4252655933699659073L; - - @SerializedName("base_info") - private BaseInfo baseInfo; - @SerializedName("errcode") - private Integer errCode; - @SerializedName("errmsg") - private String errMsg; - - @Data - private class BaseInfo { - @SerializedName("device_type") - private String deviceType; - - @SerializedName("device_id") - private String deviceId; - } -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class BaseResp extends AbstractDeviceBean { + private static final long serialVersionUID = 4252655933699659073L; + + @SerializedName("base_info") + private BaseInfo baseInfo; + @SerializedName("errcode") + private Integer errCode; + @SerializedName("errmsg") + private String errMsg; + + @Data + private class BaseInfo { + @SerializedName("device_type") + private String deviceType; + + @SerializedName("device_id") + private String deviceId; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java index 601f848223..de9dccd429 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java @@ -1,21 +1,21 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class RespMsg extends AbstractDeviceBean { - private static final long serialVersionUID = -4241272701707684136L; - - @SerializedName("ret_code") - private Integer retCode; - @SerializedName("error_info") - private String errorInfo; -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class RespMsg extends AbstractDeviceBean { + private static final long serialVersionUID = -4241272701707684136L; + + @SerializedName("ret_code") + private Integer retCode; + @SerializedName("error_info") + private String errorInfo; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java index f2b35da5ea..289816a782 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java @@ -1,29 +1,29 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -/** - * - * @author keungtung. - * @date 14/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class TransMsgResp extends AbstractDeviceBean { - private static final long serialVersionUID = 5386954916622816491L; - - private Integer ret; - @SerializedName("ret_info") - private String retInfo; - @SerializedName("errcode") - private Integer errCode; - @SerializedName("errmsg") - private String errMsg; - - public static TransMsgResp fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, TransMsgResp.class); - } -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * + * @author keungtung. + * @date 14/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class TransMsgResp extends AbstractDeviceBean { + private static final long serialVersionUID = 5386954916622816491L; + + private Integer ret; + @SerializedName("ret_info") + private String retInfo; + @SerializedName("errcode") + private Integer errCode; + @SerializedName("errmsg") + private String errMsg; + + public static TransMsgResp fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, TransMsgResp.class); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java index 5e00c4faea..ed02aedc70 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java @@ -1,32 +1,32 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -/** - * @author keungtung - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceAuthorize extends AbstractDeviceBean { - private static final long serialVersionUID = 8786321356569903887L; - - @SerializedName("device_num") - private String deviceNum; - @SerializedName("op_type") - private String opType; - @SerializedName("product_id") - private String productId; - @SerializedName("device_list") - private List deviceList = new LinkedList<>(); - - public void addDevice(WxDevice... devices) { - this.deviceList.addAll(Arrays.asList(devices)); - } -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * @author keungtung + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceAuthorize extends AbstractDeviceBean { + private static final long serialVersionUID = 8786321356569903887L; + + @SerializedName("device_num") + private String deviceNum; + @SerializedName("op_type") + private String opType; + @SerializedName("product_id") + private String productId; + @SerializedName("device_list") + private List deviceList = new LinkedList<>(); + + public void addDevice(WxDevice... devices) { + this.deviceList.addAll(Arrays.asList(devices)); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java index 9608452ce1..d0fe937ee7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.device; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.util.List; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceAuthorizeResult extends AbstractDeviceBean { - private static final long serialVersionUID = 9105294570912249811L; - - private List resp; - - public static WxDeviceAuthorizeResult fromJson(String response) { - return WxGsonBuilder.create().fromJson(response, WxDeviceAuthorizeResult.class); - } - -} +package me.chanjar.weixin.mp.bean.device; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.util.List; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceAuthorizeResult extends AbstractDeviceBean { + private static final long serialVersionUID = 9105294570912249811L; + + private List resp; + + public static WxDeviceAuthorizeResult fromJson(String response) { + return WxGsonBuilder.create().fromJson(response, WxDeviceAuthorizeResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java index aeb7f819ce..94d3e938c0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceBind extends AbstractDeviceBean { - private static final long serialVersionUID = 467559769037590880L; - - private String ticket; - @SerializedName("device_id") - private String deviceId; - @SerializedName("openid") - private String openId; - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceBind extends AbstractDeviceBean { + private static final long serialVersionUID = 467559769037590880L; + + private String ticket; + @SerializedName("device_id") + private String deviceId; + @SerializedName("openid") + private String openId; + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java index ec032e8617..5653863a45 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java @@ -1,39 +1,39 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * @author keungtung. - * @date 16/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceBindDeviceResult extends AbstractDeviceBean { - private static final long serialVersionUID = 725870295905935355L; - - @SerializedName("resp_msg") - private RespMsg respMsg; - @SerializedName("openid") - private String openId; - @SerializedName("device_list") - private List devices; - - public static WxDeviceBindDeviceResult fromJson(String json) { - return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindDeviceResult.class); - } - - @Data - private class Device { - @SerializedName("device_type") - private String deviceType; - @SerializedName("device_id") - private String deviceId; - - } - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * @author keungtung. + * @date 16/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceBindDeviceResult extends AbstractDeviceBean { + private static final long serialVersionUID = 725870295905935355L; + + @SerializedName("resp_msg") + private RespMsg respMsg; + @SerializedName("openid") + private String openId; + @SerializedName("device_list") + private List devices; + + public static WxDeviceBindDeviceResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindDeviceResult.class); + } + + @Data + private class Device { + @SerializedName("device_type") + private String deviceType; + @SerializedName("device_id") + private String deviceId; + + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java index f6c702aa29..67a0edf654 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceBindResult extends AbstractDeviceBean { - private static final long serialVersionUID = 4687725146279339359L; - - @SerializedName("base_resp") - private BaseResp baseResp; - - public static WxDeviceBindResult fromJson(String json) { - return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindResult.class); - } - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceBindResult extends AbstractDeviceBean { + private static final long serialVersionUID = 4687725146279339359L; + + @SerializedName("base_resp") + private BaseResp baseResp; + + public static WxDeviceBindResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java index 4128a9f82b..6cab2305d9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java @@ -1,29 +1,29 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.util.ToStringUtils; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceMsg extends AbstractDeviceBean { - private static final long serialVersionUID = -5567110858455277963L; - - @SerializedName("device_type") - private String deviceType; - @SerializedName("device_id") - private String deviceId; - @SerializedName("open_id") - private String openId; - private String content; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.util.ToStringUtils; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceMsg extends AbstractDeviceBean { + private static final long serialVersionUID = -5567110858455277963L; + + @SerializedName("device_type") + private String deviceType; + @SerializedName("device_id") + private String deviceId; + @SerializedName("open_id") + private String openId; + private String content; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java index 95cf2a94ff..5ab726c1a3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java @@ -1,32 +1,32 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * @author keungtung. - * @date 16/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceOpenIdResult extends AbstractDeviceBean { - private static final long serialVersionUID = 4980885167833836220L; - - @SerializedName("errcode") - private Integer errCode; - @SerializedName("errmsg") - private String errMsg; - @SerializedName("open_id") - private List openIds; - @SerializedName("resp_msg") - private RespMsg respMsg; - - public static WxDeviceOpenIdResult fromJson(String json) { - return WxMpGsonBuilder.create().fromJson(json, WxDeviceOpenIdResult.class); - } - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * @author keungtung. + * @date 16/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceOpenIdResult extends AbstractDeviceBean { + private static final long serialVersionUID = 4980885167833836220L; + + @SerializedName("errcode") + private Integer errCode; + @SerializedName("errmsg") + private String errMsg; + @SerializedName("open_id") + private List openIds; + @SerializedName("resp_msg") + private RespMsg respMsg; + + public static WxDeviceOpenIdResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxDeviceOpenIdResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java index 0e0d96f419..c2ffb094b0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java @@ -1,30 +1,30 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceQrCodeResult extends AbstractDeviceBean { - private static final long serialVersionUID = -4312858303060918266L; - - @SerializedName("deviceid") - private String deviceId; - @SerializedName("qrticket") - private String qrTicket; - @SerializedName("devicelicence") - private String deviceLicence; - @SerializedName("base_resp") - private BaseResp baseResp; - - public static WxDeviceQrCodeResult fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxDeviceQrCodeResult.class); - } - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceQrCodeResult extends AbstractDeviceBean { + private static final long serialVersionUID = -4312858303060918266L; + + @SerializedName("deviceid") + private String deviceId; + @SerializedName("qrticket") + private String qrTicket; + @SerializedName("devicelicence") + private String deviceLicence; + @SerializedName("base_resp") + private BaseResp baseResp; + + public static WxDeviceQrCodeResult fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxDeviceQrCodeResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java index dbb0ab90f9..a913b6918c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutImageMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = -2684778597067990723L; - - @XStreamAlias("Image") - @XStreamConverter(value = XStreamMediaIdConverter.class) - private String mediaId; - - public WxMpXmlOutImageMessage() { - this.msgType = WxConsts.XmlMsgType.IMAGE; - } - -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutImageMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = -2684778597067990723L; + + @XStreamAlias("Image") + @XStreamConverter(value = XStreamMediaIdConverter.class) + private String mediaId; + + public WxMpXmlOutImageMessage() { + this.msgType = WxConsts.XmlMsgType.IMAGE; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java index f7405600ef..2b55cc241e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java @@ -1,58 +1,58 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = -4604402850905714772L; - - @XStreamAlias("Articles") - protected final List articles = new ArrayList<>(); - @XStreamAlias("ArticleCount") - protected int articleCount; - - public WxMpXmlOutNewsMessage() { - this.msgType = WxConsts.XmlMsgType.NEWS; - } - - public void addArticle(Item item) { - this.articles.add(item); - this.articleCount = this.articles.size(); - } - - @XStreamAlias("item") - @Data - public static class Item implements Serializable { - private static final long serialVersionUID = -4971456355028904754L; - - @XStreamAlias("Title") - @XStreamConverter(value = XStreamCDataConverter.class) - private String title; - - @XStreamAlias("Description") - @XStreamConverter(value = XStreamCDataConverter.class) - private String description; - - @XStreamAlias("PicUrl") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picUrl; - - @XStreamAlias("Url") - @XStreamConverter(value = XStreamCDataConverter.class) - private String url; - - } - - -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = -4604402850905714772L; + + @XStreamAlias("Articles") + protected final List articles = new ArrayList<>(); + @XStreamAlias("ArticleCount") + protected int articleCount; + + public WxMpXmlOutNewsMessage() { + this.msgType = WxConsts.XmlMsgType.NEWS; + } + + public void addArticle(Item item) { + this.articles.add(item); + this.articleCount = this.articles.size(); + } + + @XStreamAlias("item") + @Data + public static class Item implements Serializable { + private static final long serialVersionUID = -4971456355028904754L; + + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @XStreamAlias("Description") + @XStreamConverter(value = XStreamCDataConverter.class) + private String description; + + @XStreamAlias("PicUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picUrl; + + @XStreamAlias("Url") + @XStreamConverter(value = XStreamCDataConverter.class) + private String url; + + } + + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java index cbaa05abc3..6a3fd1f97c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutTextMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = -3972786455288763361L; - - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - public WxMpXmlOutTextMessage() { - this.msgType = WxConsts.XmlMsgType.TEXT; - } - -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutTextMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = -3972786455288763361L; + + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + public WxMpXmlOutTextMessage() { + this.msgType = WxConsts.XmlMsgType.TEXT; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java index 5b0857830e..7e047bb2a3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java @@ -1,35 +1,35 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -import java.io.Serializable; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutTransferKefuMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = 1850903037285841322L; - - @XStreamAlias("TransInfo") - protected TransInfo transInfo; - - public WxMpXmlOutTransferKefuMessage() { - this.msgType = WxConsts.KefuMsgType.TRANSFER_CUSTOMER_SERVICE; - } - - @XStreamAlias("TransInfo") - @Data - public static class TransInfo implements Serializable { - private static final long serialVersionUID = -6317885617135706056L; - - @XStreamAlias("KfAccount") - @XStreamConverter(value = XStreamCDataConverter.class) - private String kfAccount; - - } -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +import java.io.Serializable; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutTransferKefuMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = 1850903037285841322L; + + @XStreamAlias("TransInfo") + protected TransInfo transInfo; + + public WxMpXmlOutTransferKefuMessage() { + this.msgType = WxConsts.KefuMsgType.TRANSFER_CUSTOMER_SERVICE; + } + + @XStreamAlias("TransInfo") + @Data + public static class TransInfo implements Serializable { + private static final long serialVersionUID = -6317885617135706056L; + + @XStreamAlias("KfAccount") + @XStreamConverter(value = XStreamCDataConverter.class) + private String kfAccount; + + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java index bd91b861ee..690208fcea 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = 240367390249860551L; - - @XStreamAlias("Voice") - @XStreamConverter(value = XStreamMediaIdConverter.class) - private String mediaId; - - public WxMpXmlOutVoiceMessage() { - this.msgType = WxConsts.XmlMsgType.VOICE; - } - -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = 240367390249860551L; + + @XStreamAlias("Voice") + @XStreamConverter(value = XStreamMediaIdConverter.class) + private String mediaId; + + public WxMpXmlOutVoiceMessage() { + this.msgType = WxConsts.XmlMsgType.VOICE; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java index e93bf75cf9..ec5734e1e6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java @@ -1,23 +1,23 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonObject; -import lombok.Data; - -import java.io.Serializable; - -@Data -public class WxMpDeviceIdentifier implements Serializable { - private Integer device_id; - private String uuid; - private Integer page_id; - private Integer major; - private Integer minor; - public JsonObject toJsonObject(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("device_id", device_id); - jsonObject.addProperty("uuid", uuid); - jsonObject.addProperty("major", major); - jsonObject.addProperty("minor", minor); - return jsonObject; - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpDeviceIdentifier implements Serializable { + private Integer device_id; + private String uuid; + private Integer page_id; + private Integer major; + private Integer minor; + public JsonObject toJsonObject(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("device_id", device_id); + jsonObject.addProperty("uuid", uuid); + jsonObject.addProperty("major", major); + jsonObject.addProperty("minor", minor); + return jsonObject; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java index 71da0b1c65..d5e99c6c1a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java @@ -1,23 +1,23 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import lombok.Data; - -import java.util.Collection; - -@Data -public class WxMpShakeAroundDeviceBindPageQuery { - private WxMpDeviceIdentifier deviceIdentifier; - private Collection pageIds; - public String toJsonString(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); - JsonArray jsonArray = new JsonArray(); - for(Integer pageid: pageIds){ - jsonArray.add(pageid); - } - jsonObject.add("page_ids", jsonArray); - return jsonObject.toString(); - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.Data; + +import java.util.Collection; + +@Data +public class WxMpShakeAroundDeviceBindPageQuery { + private WxMpDeviceIdentifier deviceIdentifier; + private Collection pageIds; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + JsonArray jsonArray = new JsonArray(); + for(Integer pageid: pageIds){ + jsonArray.add(pageid); + } + jsonObject.add("page_ids", jsonArray); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java index b04ced93bd..f72f4a1e0d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java @@ -1,23 +1,23 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonObject; -import lombok.Data; - -import java.io.Serializable; -@Data -public class WxMpShakeAroundPageAddQuery implements Serializable { - private String title; - private String description; - private String pageUrl; - private String comment; - private String iconUrl; - public String toJsonString(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("title", title); - jsonObject.addProperty("description", description); - jsonObject.addProperty("page_url", pageUrl); - jsonObject.addProperty("comment", comment); - jsonObject.addProperty("icon_url", iconUrl); - return jsonObject.toString(); - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; +@Data +public class WxMpShakeAroundPageAddQuery implements Serializable { + private String title; + private String description; + private String pageUrl; + private String comment; + private String iconUrl; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("title", title); + jsonObject.addProperty("description", description); + jsonObject.addProperty("page_url", pageUrl); + jsonObject.addProperty("comment", comment); + jsonObject.addProperty("icon_url", iconUrl); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java index 632fe4f351..8d9c8c2a37 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java @@ -1,26 +1,26 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonObject; -import lombok.Data; -import me.chanjar.weixin.common.util.json.GsonHelper; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.io.Serializable; - -@Data -public class WxMpShakeAroundPageAddResult implements Serializable { - private Integer errorCode; - private String errorMsg; - private Integer pageId; - public static WxMpShakeAroundPageAddResult fromJson(String json) { - JsonObject jsonObject = WxMpGsonBuilder.INSTANCE.create().fromJson(json, JsonObject.class); - WxMpShakeAroundPageAddResult result = new WxMpShakeAroundPageAddResult(); - result.setErrorCode(GsonHelper.getInteger(jsonObject, "errcode")); - result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); - jsonObject = jsonObject.getAsJsonObject("data"); - if(jsonObject != null){ - result.setPageId(GsonHelper.getInteger(jsonObject, "page_id")); - } - return result; - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundPageAddResult implements Serializable { + private Integer errorCode; + private String errorMsg; + private Integer pageId; + public static WxMpShakeAroundPageAddResult fromJson(String json) { + JsonObject jsonObject = WxMpGsonBuilder.INSTANCE.create().fromJson(json, JsonObject.class); + WxMpShakeAroundPageAddResult result = new WxMpShakeAroundPageAddResult(); + result.setErrorCode(GsonHelper.getInteger(jsonObject, "errcode")); + result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); + jsonObject = jsonObject.getAsJsonObject("data"); + if(jsonObject != null){ + result.setPageId(GsonHelper.getInteger(jsonObject, "page_id")); + } + return result; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java index 390fe50964..0c4d7fdb80 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java @@ -1,32 +1,32 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonObject; -import lombok.Data; - -import java.io.Serializable; - -@Data -public class WxMpShakeAroundRelationSearchQuery implements Serializable { - private int type; - private Integer pageId; - private Integer begin; - private Integer count; - private WxMpDeviceIdentifier deviceIdentifier; - public String toJsonString(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("type", type); - switch (type){ - case 1: - jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); - break; - case 2: - jsonObject.addProperty("page_id", pageId); - jsonObject.addProperty("begin", begin); - jsonObject.addProperty("count", count); - break; - default: - throw new IllegalArgumentException("type error"); - } - return jsonObject.toString(); - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundRelationSearchQuery implements Serializable { + private int type; + private Integer pageId; + private Integer begin; + private Integer count; + private WxMpDeviceIdentifier deviceIdentifier; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("type", type); + switch (type){ + case 1: + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + break; + case 2: + jsonObject.addProperty("page_id", pageId); + jsonObject.addProperty("begin", begin); + jsonObject.addProperty("count", count); + break; + default: + throw new IllegalArgumentException("type error"); + } + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java index 2b7269e572..e4cff86973 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.mp.bean.shake; - -import lombok.Data; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.io.Serializable; -import java.util.List; - -@Data -public class WxMpShakeAroundRelationSearchResult implements Serializable { - private Integer errcode; - private String errmsg; - private WxMpShakeAcoundRelationSearch data; - public static WxMpShakeAroundRelationSearchResult fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); - } - @Data - public static class WxMpShakeAcoundRelationSearch implements Serializable{ - private List relations; - private Integer total_count; - } -} +package me.chanjar.weixin.mp.bean.shake; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +@Data +public class WxMpShakeAroundRelationSearchResult implements Serializable { + private Integer errcode; + private String errmsg; + private WxMpShakeAcoundRelationSearch data; + public static WxMpShakeAroundRelationSearchResult fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); + } + @Data + public static class WxMpShakeAcoundRelationSearch implements Serializable{ + private List relations; + private Integer total_count; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java index 8a4f7462f7..90b0b2fe80 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java @@ -1,36 +1,36 @@ -package me.chanjar.weixin.mp.util.http; - -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialVoiceAndImageDownloadRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialVoiceAndImageDownloadRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialVoiceAndImageDownloadRequestExecutor; - -import java.io.File; -import java.io.InputStream; - -public abstract class MaterialVoiceAndImageDownloadRequestExecutor - implements RequestExecutor { - protected RequestHttp requestHttp; - protected File tmpDirFile; - - public MaterialVoiceAndImageDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { - this.requestHttp = requestHttp; - this.tmpDirFile = tmpDirFile; - } - - public static RequestExecutor create(RequestHttp requestHttp, File tmpDirFile) { - switch (requestHttp.getRequestType()) { - case APACHE_HTTP: - return new ApacheMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); - case JODD_HTTP: - return new JoddMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); - case OK_HTTP: - return new OkhttpMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); - default: - return null; - } - } - - -} +package me.chanjar.weixin.mp.util.http; + +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialVoiceAndImageDownloadRequestExecutor; +import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialVoiceAndImageDownloadRequestExecutor; +import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialVoiceAndImageDownloadRequestExecutor; + +import java.io.File; +import java.io.InputStream; + +public abstract class MaterialVoiceAndImageDownloadRequestExecutor + implements RequestExecutor { + protected RequestHttp requestHttp; + protected File tmpDirFile; + + public MaterialVoiceAndImageDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { + this.requestHttp = requestHttp; + this.tmpDirFile = tmpDirFile; + } + + public static RequestExecutor create(RequestHttp requestHttp, File tmpDirFile) { + switch (requestHttp.getRequestType()) { + case APACHE_HTTP: + return new ApacheMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + case JODD_HTTP: + return new JoddMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + case OK_HTTP: + return new OkhttpMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + default: + return null; + } + } + + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java index af2e025796..f3fa5eeb3c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java @@ -1,39 +1,39 @@ -package me.chanjar.weixin.mp.util.http; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.apache.ApacheQrCodeRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddQrCodeRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpQrCodeRequestExecutor; - -import java.io.File; - -/** - * 获得QrCode图片 请求执行器 - * - * @author chanjarster - */ -public abstract class QrCodeRequestExecutor implements RequestExecutor { - protected RequestHttp requestHttp; - - public QrCodeRequestExecutor(RequestHttp requestHttp) { - this.requestHttp = requestHttp; - } - - public static RequestExecutor create(RequestHttp requestHttp) throws WxErrorException { - switch (requestHttp.getRequestType()) { - case APACHE_HTTP: - return new ApacheQrCodeRequestExecutor(requestHttp); - case JODD_HTTP: - return new JoddQrCodeRequestExecutor(requestHttp); - case OK_HTTP: - return new OkhttpQrCodeRequestExecutor(requestHttp); - default: - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("不支持的http框架").build()); - } - } - -} +package me.chanjar.weixin.mp.util.http; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import me.chanjar.weixin.mp.util.http.apache.ApacheQrCodeRequestExecutor; +import me.chanjar.weixin.mp.util.http.jodd.JoddQrCodeRequestExecutor; +import me.chanjar.weixin.mp.util.http.okhttp.OkhttpQrCodeRequestExecutor; + +import java.io.File; + +/** + * 获得QrCode图片 请求执行器 + * + * @author chanjarster + */ +public abstract class QrCodeRequestExecutor implements RequestExecutor { + protected RequestHttp requestHttp; + + public QrCodeRequestExecutor(RequestHttp requestHttp) { + this.requestHttp = requestHttp; + } + + public static RequestExecutor create(RequestHttp requestHttp) throws WxErrorException { + switch (requestHttp.getRequestType()) { + case APACHE_HTTP: + return new ApacheQrCodeRequestExecutor(requestHttp); + case JODD_HTTP: + return new JoddQrCodeRequestExecutor(requestHttp); + case OK_HTTP: + return new OkhttpQrCodeRequestExecutor(requestHttp); + default: + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("不支持的http框架").build()); + } + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java index 9ddd61f9a9..534b5aa5c1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java @@ -1,77 +1,77 @@ -package me.chanjar.weixin.mp.util.http.apache; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.bean.material.WxMpMaterial; -import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; -import org.apache.http.Consts; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.HttpMultipartMode; -import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.entity.mime.content.StringBody; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Map; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class ApacheMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { - public ApacheMaterialUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { - HttpPost httpPost = new HttpPost(uri); - if (requestHttp.getRequestHttpProxy() != null) { - RequestConfig response = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); - httpPost.setConfig(response); - } - - if (material == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); - } - - File file = material.getFile(); - if (file == null || !file.exists()) { - throw new FileNotFoundException(); - } - - MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); - multipartEntityBuilder - .addBinaryBody("media", file) - .setMode(HttpMultipartMode.RFC6532); - Map form = material.getForm(); - if (material.getForm() != null) { - multipartEntityBuilder.addPart("description", - new StringBody(WxGsonBuilder.create().toJson(form), ContentType.create("text/plain", Consts.UTF_8))); - } - - httpPost.setEntity(multipartEntityBuilder.build()); - httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); - - try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return WxMpMaterialUploadResult.fromJson(responseContent); - } - } finally { - httpPost.releaseConnection(); - } - } -} +package me.chanjar.weixin.mp.util.http.apache; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.bean.material.WxMpMaterial; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; +import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; +import org.apache.http.Consts; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class ApacheMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { + public ApacheMaterialUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { + HttpPost httpPost = new HttpPost(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig response = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(response); + } + + if (material == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); + } + + File file = material.getFile(); + if (file == null || !file.exists()) { + throw new FileNotFoundException(); + } + + MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); + multipartEntityBuilder + .addBinaryBody("media", file) + .setMode(HttpMultipartMode.RFC6532); + Map form = material.getForm(); + if (material.getForm() != null) { + multipartEntityBuilder.addPart("description", + new StringBody(WxGsonBuilder.create().toJson(form), ContentType.create("text/plain", Consts.UTF_8))); + } + + httpPost.setEntity(multipartEntityBuilder.build()); + httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return WxMpMaterialUploadResult.fromJson(responseContent); + } + } finally { + httpPost.releaseConnection(); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java index d001876d6d..ddd5a56879 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java @@ -1,60 +1,60 @@ -package me.chanjar.weixin.mp.util.http.apache; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; -import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; -import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.HttpMultipartMode; -import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.File; -import java.io.IOException; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class ApacheMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { - public ApacheMediaImgUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { - if (data == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); - } - - HttpPost httpPost = new HttpPost(uri); - if (requestHttp.getRequestHttpProxy() != null) { - RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); - httpPost.setConfig(config); - } - - HttpEntity entity = MultipartEntityBuilder - .create() - .addBinaryBody("media", data) - .setMode(HttpMultipartMode.RFC6532) - .build(); - httpPost.setEntity(entity); - httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); - - try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - - return WxMediaImgUploadResult.fromJson(responseContent); - } - } -} +package me.chanjar.weixin.mp.util.http.apache; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; +import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.File; +import java.io.IOException; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class ApacheMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { + public ApacheMediaImgUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { + if (data == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); + } + + HttpPost httpPost = new HttpPost(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(config); + } + + HttpEntity entity = MultipartEntityBuilder + .create() + .addBinaryBody("media", data) + .setMode(HttpMultipartMode.RFC6532) + .build(); + httpPost.setEntity(entity); + httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + + return WxMediaImgUploadResult.fromJson(responseContent); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java index a7a5509c08..c5d77c4ab8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java @@ -1,62 +1,62 @@ -package me.chanjar.weixin.mp.util.http.jodd; - -import jodd.http.HttpConnectionProvider; -import jodd.http.HttpRequest; -import jodd.http.HttpResponse; -import jodd.http.ProxyInfo; -import jodd.util.StringPool; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.bean.material.WxMpMaterial; -import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Map; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class JoddMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { - public JoddMaterialUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { - HttpRequest request = HttpRequest.post(uri); - if (requestHttp.getRequestHttpProxy() != null) { - requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); - } - request.withConnectionProvider(requestHttp.getRequestHttpClient()); - - if (material == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); - } - - File file = material.getFile(); - if (file == null || !file.exists()) { - throw new FileNotFoundException(); - } - request.form("media", file); - Map form = material.getForm(); - if (material.getForm() != null) { - request.form("description", WxGsonBuilder.create().toJson(form)); - } - - HttpResponse response = request.send(); - response.charset(StringPool.UTF_8); - String responseContent = response.bodyText(); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return WxMpMaterialUploadResult.fromJson(responseContent); - } - } -} +package me.chanjar.weixin.mp.util.http.jodd; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import jodd.util.StringPool; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.bean.material.WxMpMaterial; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; +import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class JoddMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { + public JoddMaterialUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { + HttpRequest request = HttpRequest.post(uri); + if (requestHttp.getRequestHttpProxy() != null) { + requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); + } + request.withConnectionProvider(requestHttp.getRequestHttpClient()); + + if (material == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); + } + + File file = material.getFile(); + if (file == null || !file.exists()) { + throw new FileNotFoundException(); + } + request.form("media", file); + Map form = material.getForm(); + if (material.getForm() != null) { + request.form("description", WxGsonBuilder.create().toJson(form)); + } + + HttpResponse response = request.send(); + response.charset(StringPool.UTF_8); + String responseContent = response.bodyText(); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return WxMpMaterialUploadResult.fromJson(responseContent); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java index b66a793365..8379674b32 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java @@ -1,49 +1,49 @@ -package me.chanjar.weixin.mp.util.http.jodd; - -import jodd.http.HttpConnectionProvider; -import jodd.http.HttpRequest; -import jodd.http.HttpResponse; -import jodd.http.ProxyInfo; -import jodd.util.StringPool; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; -import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; - -import java.io.File; -import java.io.IOException; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class JoddMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { - public JoddMediaImgUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { - if (data == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); - } - - HttpRequest request = HttpRequest.post(uri); - if (requestHttp.getRequestHttpProxy() != null) { - requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); - } - request.withConnectionProvider(requestHttp.getRequestHttpClient()); - - request.form("media", data); - HttpResponse response = request.send(); - response.charset(StringPool.UTF_8); - String responseContent = response.bodyText(); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - - return WxMediaImgUploadResult.fromJson(responseContent); - } -} +package me.chanjar.weixin.mp.util.http.jodd; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import jodd.util.StringPool; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; +import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; + +import java.io.File; +import java.io.IOException; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class JoddMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { + public JoddMediaImgUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { + if (data == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); + } + + HttpRequest request = HttpRequest.post(uri); + if (requestHttp.getRequestHttpProxy() != null) { + requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); + } + request.withConnectionProvider(requestHttp.getRequestHttpClient()); + + request.form("media", data); + HttpResponse response = request.send(); + response.charset(StringPool.UTF_8); + String responseContent = response.bodyText(); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + + return WxMediaImgUploadResult.fromJson(responseContent); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java index 766d239565..4375606a38 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java @@ -1,66 +1,66 @@ -package me.chanjar.weixin.mp.util.http.okhttp; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.bean.material.WxMpMaterial; -import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; -import okhttp3.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Map; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class OkhttpMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public OkhttpMaterialUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { - logger.debug("OkhttpMaterialUploadRequestExecutor is running"); - if (material == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); - } - File file = material.getFile(); - if (file == null || !file.exists()) { - throw new FileNotFoundException(); - } - - //得到httpClient - - OkHttpClient client = requestHttp.getRequestHttpClient(); - - MultipartBody.Builder bodyBuilder = new MultipartBody.Builder() - .setType(MediaType.parse("multipart/form-data")) - .addFormDataPart("media", - file.getName(), - RequestBody.create(MediaType.parse("application/octet-stream"), file)); - Map form = material.getForm(); - if (form != null) { - bodyBuilder.addFormDataPart("description", WxGsonBuilder.create().toJson(form)); - } - - Request request = new Request.Builder().url(uri).post(bodyBuilder.build()).build(); - Response response = client.newCall(request).execute(); - String responseContent = response.body().string(); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return WxMpMaterialUploadResult.fromJson(responseContent); - } - } - -} +package me.chanjar.weixin.mp.util.http.okhttp; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.bean.material.WxMpMaterial; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; +import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; +import okhttp3.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class OkhttpMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public OkhttpMaterialUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { + logger.debug("OkhttpMaterialUploadRequestExecutor is running"); + if (material == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); + } + File file = material.getFile(); + if (file == null || !file.exists()) { + throw new FileNotFoundException(); + } + + //得到httpClient + + OkHttpClient client = requestHttp.getRequestHttpClient(); + + MultipartBody.Builder bodyBuilder = new MultipartBody.Builder() + .setType(MediaType.parse("multipart/form-data")) + .addFormDataPart("media", + file.getName(), + RequestBody.create(MediaType.parse("application/octet-stream"), file)); + Map form = material.getForm(); + if (form != null) { + bodyBuilder.addFormDataPart("description", WxGsonBuilder.create().toJson(form)); + } + + Request request = new Request.Builder().url(uri).post(bodyBuilder.build()).build(); + Response response = client.newCall(request).execute(); + String responseContent = response.body().string(); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return WxMpMaterialUploadResult.fromJson(responseContent); + } + } + +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java index e8630dbc5a..7ed544d46d 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java @@ -1,65 +1,65 @@ -package me.chanjar.weixin.mp.api; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.mp.api.impl.WxMpServiceApacheHttpClientImpl; -import org.testng.annotations.*; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -@Test -public class WxMpBusyRetryTest { - - @DataProvider(name = "getService") - public Object[][] getService() { - WxMpService service = new WxMpServiceApacheHttpClientImpl() { - - @Override - public synchronized T executeInternal( - RequestExecutor executor, String uri, E data) - throws WxErrorException { - this.log.info("Executed"); - throw new WxErrorException(WxError.builder().errorCode(-1).build()); - } - }; - - service.setMaxRetryTimes(3); - service.setRetrySleepMillis(500); - return new Object[][]{{service}}; - } - - @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) - public void testRetry(WxMpService service) throws WxErrorException { - service.execute(null, null, null); - } - - @Test(dataProvider = "getService") - public void testRetryInThreadPool(final WxMpService service) throws InterruptedException, ExecutionException { - // 当线程池中的线程复用的时候,还是能保证相同的重试次数 - ExecutorService executorService = Executors.newFixedThreadPool(1); - Runnable runnable = new Runnable() { - @Override - public void run() { - try { - System.out.println("====================="); - System.out.println(Thread.currentThread().getName() + ": testRetry"); - service.execute(null, null, null); - } catch (WxErrorException e) { - throw new RuntimeException(e); - } catch (RuntimeException e) { - // OK - } - } - }; - Future submit1 = executorService.submit(runnable); - Future submit2 = executorService.submit(runnable); - - submit1.get(); - submit2.get(); - } - -} +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.mp.api.impl.WxMpServiceApacheHttpClientImpl; +import org.testng.annotations.*; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +@Test +public class WxMpBusyRetryTest { + + @DataProvider(name = "getService") + public Object[][] getService() { + WxMpService service = new WxMpServiceApacheHttpClientImpl() { + + @Override + public synchronized T executeInternal( + RequestExecutor executor, String uri, E data) + throws WxErrorException { + this.log.info("Executed"); + throw new WxErrorException(WxError.builder().errorCode(-1).build()); + } + }; + + service.setMaxRetryTimes(3); + service.setRetrySleepMillis(500); + return new Object[][]{{service}}; + } + + @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) + public void testRetry(WxMpService service) throws WxErrorException { + service.execute(null, null, null); + } + + @Test(dataProvider = "getService") + public void testRetryInThreadPool(final WxMpService service) throws InterruptedException, ExecutionException { + // 当线程池中的线程复用的时候,还是能保证相同的重试次数 + ExecutorService executorService = Executors.newFixedThreadPool(1); + Runnable runnable = new Runnable() { + @Override + public void run() { + try { + System.out.println("====================="); + System.out.println(Thread.currentThread().getName() + ": testRetry"); + service.execute(null, null, null); + } catch (WxErrorException e) { + throw new RuntimeException(e); + } catch (RuntimeException e) { + // OK + } + } + }; + Future submit1 = executorService.submit(runnable); + Future submit2 = executorService.submit(runnable); + + submit1.get(); + submit2.get(); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index c3c402c5af..40e698a514 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -1,83 +1,83 @@ -package me.chanjar.weixin.open.api; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; -import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; -import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; -import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; - -/** - * @author 007 - */ -public interface WxOpenComponentService { - - String API_COMPONENT_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; - String API_CREATE_PREAUTHCODE_URL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode"; - String API_QUERY_AUTH_URL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth"; - String API_AUTHORIZER_TOKEN_URL = "https://api.weixin.qq.com /cgi-bin/component/api_authorizer_token"; - String API_GET_AUTHORIZER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info"; - String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option"; - String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/ api_set_authorizer_option"; - - - String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; - String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; - - /** - * 用code换取oauth2的access token - */ - String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s"; - /** - * 刷新oauth2的access token - */ - String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid==%s"; - - WxMpService getWxMpServiceByAppid(String appid); - - WxOpenConfigStorage getWxOpenConfigStorage(); - - boolean checkSignature(String timestamp, String nonce, String signature); - - String getComponentAccessToken(boolean forceRefresh) throws WxErrorException; - - /** - * 获取用户授权页URL(来路URL和成功跳转URL 的域名都需要为三方平台设置的 登录授权的发起页域名) - */ - String getPreAuthUrl(String redirectURI) throws WxErrorException; - - String route(WxOpenXmlMessage wxMessage) throws WxErrorException; - - /** - * 使用授权码换取公众号或小程序的接口调用凭据和授权信息 - */ - WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException; - - /** - * 获取授权方的帐号基本信息 - */ - WxOpenAuthorizerInfoResult getAuthorizerInfo(String authorizerAppid) throws WxErrorException; - - /** - * 获取授权方的选项设置信息 - */ - WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException; - - /** - * 设置授权方的选项信息 - */ - WxError setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException; - - String getAuthorizerAccessToken(String appid, boolean forceRefresh) throws WxErrorException; - - WxMpOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException; - - boolean checkSignature(String appId, String timestamp, String nonce, String signature); - - WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; - - String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state); - -} +package me.chanjar.weixin.open.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; + +/** + * @author 007 + */ +public interface WxOpenComponentService { + + String API_COMPONENT_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; + String API_CREATE_PREAUTHCODE_URL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode"; + String API_QUERY_AUTH_URL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth"; + String API_AUTHORIZER_TOKEN_URL = "https://api.weixin.qq.com /cgi-bin/component/api_authorizer_token"; + String API_GET_AUTHORIZER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info"; + String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option"; + String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/ api_set_authorizer_option"; + + + String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; + String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; + + /** + * 用code换取oauth2的access token + */ + String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s"; + /** + * 刷新oauth2的access token + */ + String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid==%s"; + + WxMpService getWxMpServiceByAppid(String appid); + + WxOpenConfigStorage getWxOpenConfigStorage(); + + boolean checkSignature(String timestamp, String nonce, String signature); + + String getComponentAccessToken(boolean forceRefresh) throws WxErrorException; + + /** + * 获取用户授权页URL(来路URL和成功跳转URL 的域名都需要为三方平台设置的 登录授权的发起页域名) + */ + String getPreAuthUrl(String redirectURI) throws WxErrorException; + + String route(WxOpenXmlMessage wxMessage) throws WxErrorException; + + /** + * 使用授权码换取公众号或小程序的接口调用凭据和授权信息 + */ + WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException; + + /** + * 获取授权方的帐号基本信息 + */ + WxOpenAuthorizerInfoResult getAuthorizerInfo(String authorizerAppid) throws WxErrorException; + + /** + * 获取授权方的选项设置信息 + */ + WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException; + + /** + * 设置授权方的选项信息 + */ + WxError setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException; + + String getAuthorizerAccessToken(String appid, boolean forceRefresh) throws WxErrorException; + + WxMpOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException; + + boolean checkSignature(String appId, String timestamp, String nonce, String signature); + + WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; + + String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state); + +} diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 47b3f4da16..075633f716 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -1,55 +1,55 @@ - - - - weixin-java-parent - com.github.binarywang - 2.8.8.BETA - - 4.0.0 - - weixin-java-pay - WeiXin Java Tools - PAY - 微信支付 Java SDK - - - - com.github.binarywang - weixin-java-common - ${project.version} - - - com.github.binarywang - qrcode-utils - - - - org.jodd - jodd-http - provided - - - - org.apache.commons - commons-lang3 - - - - ch.qos.logback - logback-classic - test - - - org.testng - testng - test - - - com.google.inject - guice - test - - - - + + + + weixin-java-parent + com.github.binarywang + 2.8.8.BETA + + 4.0.0 + + weixin-java-pay + WeiXin Java Tools - PAY + 微信支付 Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + com.github.binarywang + qrcode-utils + + + + org.jodd + jodd-http + provided + + + + org.apache.commons + commons-lang3 + + + + ch.qos.logback + logback-classic + test + + + org.testng + testng + test + + + com.google.inject + guice + test + + + + From 42a9213e425bde9a7c88e3ca2dfa5ba8c1ccb0b9 Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Tue, 14 Nov 2017 16:49:54 +0800 Subject: [PATCH 10/13] =?UTF-8?q?unix=20=E6=8D=A2=E8=A1=8C=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 774 +++++++-------- weixin-java-common/pom.xml | 256 ++--- .../weixin/common/bean/WxAccessToken.java | 40 +- .../common/bean/WxCardApiSignature.java | 82 +- .../weixin/common/bean/WxJsapiSignature.java | 48 +- .../weixin/common/bean/menu/WxMenu.java | 106 +- .../weixin/common/bean/menu/WxMenuButton.java | 164 +-- .../weixin/common/bean/menu/WxMenuRule.java | 58 +- .../weixin/common/bean/result/WxError.java | 76 +- .../bean/result/WxMediaUploadResult.java | 54 +- .../chanjar/weixin/common/util/BeanUtils.java | 212 ++-- .../weixin/common/util/crypto/ByteGroup.java | 52 +- .../common/util/crypto/PKCS7Encoder.java | 136 +-- .../common/util/http/HttpResponseProxy.java | 180 ++-- .../ApacheSimplePostRequestExecutor.java | 118 +-- .../JoddHttpSimplePostRequestExecutor.java | 116 +-- .../common/util/json/WxErrorAdapter.java | 78 +- .../weixin/common/bean/WxErrorTest.java | 72 +- weixin-java-cp/pom.xml | 176 ++-- .../cp/api/impl/WxCpServiceOkHttpImpl.java | 200 ++-- .../me/chanjar/weixin/cp/bean/WxCpDepart.java | 60 +- .../chanjar/weixin/cp/bean/WxCpMessage.java | 238 ++--- .../weixin/cp/bean/WxCpMessageSendResult.java | 136 +-- .../me/chanjar/weixin/cp/bean/WxCpTag.java | 64 +- .../bean/WxCpTagAddOrRemoveUsersResult.java | 114 +-- .../me/chanjar/weixin/cp/bean/WxCpUser.java | 172 ++-- .../weixin/cp/bean/WxCpXmlMessage.java | 604 +++++------ .../cp/bean/WxCpXmlOutImageMessage.java | 44 +- .../weixin/cp/bean/WxCpXmlOutMessage.java | 162 +-- .../weixin/cp/bean/WxCpXmlOutNewsMessage.java | 110 +- .../weixin/cp/bean/WxCpXmlOutTextMessage.java | 44 +- .../cp/bean/WxCpXmlOutVideoMessage.java | 126 +-- .../cp/bean/WxCpXmlOutVoiceMessage.java | 44 +- .../weixin/cp/bean/article/MpnewsArticle.java | 56 +- .../weixin/cp/bean/article/NewArticle.java | 46 +- .../weixin/cp/api/WxCpBusyRetryTest.java | 136 +-- .../weixin/cp/bean/WxCpXmlMessageTest.java | 240 ++--- weixin-java-miniapp/pom.xml | 168 ++-- .../api/impl/WxMaMediaServiceImpl.java | 110 +- .../wx/miniapp/bean/WxMaCodeLineColor.java | 36 +- .../bean/WxMaJscode2SessionResult.java | 72 +- .../wx/miniapp/bean/WxMaKefuMessage.java | 90 +- .../wx/miniapp/bean/WxMaMessage.java | 302 +++--- .../wx/miniapp/bean/WxMaQrcode.java | 64 +- .../wx/miniapp/bean/WxMaTemplateMessage.java | 216 ++-- .../wx/miniapp/bean/WxMaUserInfo.java | 70 +- .../wx/miniapp/bean/WxMaWxcode.java | 66 +- .../wx/miniapp/bean/WxMaWxcodeLimit.java | 68 +- .../api/impl/WxMaMsgServiceImplTest.java | 146 +-- .../miniapp/bean/WxMaTemplateMessageTest.java | 62 +- .../wx/miniapp/demo/WxMaDemoServer.java | 296 +++--- weixin-java-mp/pom.xml | 168 ++-- .../weixin/mp/api/WxMpMassMessageService.java | 238 ++--- .../weixin/mp/api/WxMpShakeService.java | 122 +-- .../mp/api/impl/WxMpCardServiceImpl.java | 478 ++++----- .../mp/api/impl/WxMpKefuServiceImpl.java | 304 +++--- .../api/impl/WxMpMassMessageServiceImpl.java | 134 +-- .../mp/api/impl/WxMpMaterialServiceImpl.java | 302 +++--- .../mp/api/impl/WxMpQrcodeServiceImpl.java | 302 +++--- .../mp/api/impl/WxMpServiceAbstractImpl.java | 938 +++++++++--------- .../mp/api/impl/WxMpServiceOkHttpImpl.java | 186 ++-- .../mp/api/impl/WxMpShakeServiceImpl.java | 132 +-- .../datacube/WxDataCubeArticleResult.java | 246 ++--- .../bean/datacube/WxDataCubeArticleTotal.java | 100 +- .../bean/datacube/WxDataCubeBaseResult.java | 70 +- .../datacube/WxDataCubeInterfaceResult.java | 130 +-- .../mp/bean/datacube/WxDataCubeMsgResult.java | 156 +-- .../weixin/mp/bean/device/BaseResp.java | 62 +- .../weixin/mp/bean/device/RespMsg.java | 42 +- .../weixin/mp/bean/device/TransMsgResp.java | 58 +- .../mp/bean/device/WxDeviceAuthorize.java | 64 +- .../bean/device/WxDeviceAuthorizeResult.java | 48 +- .../weixin/mp/bean/device/WxDeviceBind.java | 44 +- .../bean/device/WxDeviceBindDeviceResult.java | 78 +- .../mp/bean/device/WxDeviceBindResult.java | 48 +- .../weixin/mp/bean/device/WxDeviceMsg.java | 58 +- .../mp/bean/device/WxDeviceOpenIdResult.java | 64 +- .../mp/bean/device/WxDeviceQrCodeResult.java | 60 +- .../bean/message/WxMpXmlOutImageMessage.java | 48 +- .../bean/message/WxMpXmlOutNewsMessage.java | 116 +-- .../bean/message/WxMpXmlOutTextMessage.java | 48 +- .../WxMpXmlOutTransferKefuMessage.java | 70 +- .../bean/message/WxMpXmlOutVoiceMessage.java | 48 +- .../mp/bean/shake/WxMpDeviceIdentifier.java | 46 +- .../WxMpShakeAroundDeviceBindPageQuery.java | 46 +- .../shake/WxMpShakeAroundPageAddQuery.java | 46 +- .../shake/WxMpShakeAroundPageAddResult.java | 52 +- .../WxMpShakeAroundRelationSearchQuery.java | 64 +- .../WxMpShakeAroundRelationSearchResult.java | 44 +- ...lVoiceAndImageDownloadRequestExecutor.java | 72 +- .../mp/util/http/QrCodeRequestExecutor.java | 78 +- .../ApacheMaterialUploadRequestExecutor.java | 154 +-- .../ApacheMediaImgUploadRequestExecutor.java | 120 +-- .../JoddMaterialUploadRequestExecutor.java | 124 +-- .../JoddMediaImgUploadRequestExecutor.java | 98 +- .../OkhttpMaterialUploadRequestExecutor.java | 132 +-- .../weixin/mp/api/WxMpBusyRetryTest.java | 130 +-- .../open/api/WxOpenComponentService.java | 166 ++-- weixin-java-pay/pom.xml | 110 +- 99 files changed, 6802 insertions(+), 6802 deletions(-) diff --git a/pom.xml b/pom.xml index 2beb44880d..54f52b021e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,387 +1,387 @@ - - - 4.0.0 - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - pom - WeiXin Java Tools - Parent - 微信公众号、企业号上级POM - https://github.com/wechat-group/weixin-java-tools - - - - The Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - - Daniel Qian - chanjarster@gmail.com - https://github.com/chanjarster - - - Binary Wang - binarywang@gmail.com - https://github.com/binarywang - - - gaigeshen - gaigeshen@qq.com - https://github.com/gaigeshen - - - Liu Mingbo - liumingbo2008@gmail.com - https://github.com/FirenzesEagle - - - kakotor - kakotor@gmail.com - https://github.com/kakotor - - - xiong - zhaoxiong.tan@gmail.com - https://github.com/ZhaoxiongTan - - - LiuJunGuang - aimilin@yeah.net - https://github.com/aimilin6688 - - - Eric.Tsai - xiaodong.cai.ks@gmail.com - https://github.com/iwareserictsai - - - withinthefog - withinthefog@gmail.com - https://github.com/withinthefog - - - Keung - dongfuqiang1988@163.com - https://github.com/johnnytung - - - Jonk - aimilin@yeah.net - https://github.com/aimilin6688 - - - ecoolper - crskyp@gmail.com - https://github.com/crskyp - - - 007 - 007gzs@gmail.com - https://github.com/007gzs - - - - - scm:git:https://github.com/wechat-group/weixin-java-tools.git - scm:git:git@github.com:wechat-group/weixin-java-tools.git - https://github.com/wechat-group/weixin-java-tools - - - - weixin-java-common - weixin-java-cp - weixin-java-mp - weixin-java-pay - weixin-java-miniapp - weixin-java-open - - - - - 1.7 - 1.7 - - UTF-8 - true - true - 4.5 - 9.3.0.RC0 - - - - - - com.github.binarywang - qrcode-utils - 1.1 - - - - org.jodd - jodd-http - 3.7.1 - provided - - - com.squareup.okhttp3 - okhttp - 3.7.0 - provided - - - - org.apache.httpcomponents - httpclient - ${httpclient.version} - - - org.apache.httpcomponents - httpmime - ${httpclient.version} - - - commons-codec - commons-codec - 1.10 - - - commons-io - commons-io - 2.5 - - - org.apache.commons - commons-lang3 - 3.5 - - - org.slf4j - slf4j-api - 1.7.24 - - - com.thoughtworks.xstream - xstream - 1.4.9 - - - - com.google.guava - guava - 20.0 - - - com.google.code.gson - gson - 2.8.0 - - - - - joda-time - joda-time - 2.9.7 - test - - - ch.qos.logback - logback-classic - 1.1.11 - test - - - com.google.inject - guice - 3.0 - test - - - org.testng - testng - 6.10 - test - - - org.mockito - mockito-all - 1.9.5 - test - - - org.eclipse.jetty - jetty-server - ${jetty.version} - test - - - org.eclipse.jetty - jetty-servlet - ${jetty.version} - test - - - redis.clients - jedis - 2.9.0 - provided - - - org.projectlombok - lombok - 1.16.18 - compile - - - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - - doclint-java8-disable - - [1.8,) - - - -Xdoclint:none - - - - - release - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - - ${javadoc.opts} - UTF-8 - zh_CN - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.17 - - true - - - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.3 - true - - ossrh - https://oss.sonatype.org/ - true - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.1 - - true - false - release - deploy - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.6.0 - - UTF-8 - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 2.17 - - quality-checks/google_checks.xml - true - true - true - - - - verify - - check - - - - - - - - + + + 4.0.0 + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + pom + WeiXin Java Tools - Parent + 微信公众号、企业号上级POM + https://github.com/wechat-group/weixin-java-tools + + + + The Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + Daniel Qian + chanjarster@gmail.com + https://github.com/chanjarster + + + Binary Wang + binarywang@gmail.com + https://github.com/binarywang + + + gaigeshen + gaigeshen@qq.com + https://github.com/gaigeshen + + + Liu Mingbo + liumingbo2008@gmail.com + https://github.com/FirenzesEagle + + + kakotor + kakotor@gmail.com + https://github.com/kakotor + + + xiong + zhaoxiong.tan@gmail.com + https://github.com/ZhaoxiongTan + + + LiuJunGuang + aimilin@yeah.net + https://github.com/aimilin6688 + + + Eric.Tsai + xiaodong.cai.ks@gmail.com + https://github.com/iwareserictsai + + + withinthefog + withinthefog@gmail.com + https://github.com/withinthefog + + + Keung + dongfuqiang1988@163.com + https://github.com/johnnytung + + + Jonk + aimilin@yeah.net + https://github.com/aimilin6688 + + + ecoolper + crskyp@gmail.com + https://github.com/crskyp + + + 007 + 007gzs@gmail.com + https://github.com/007gzs + + + + + scm:git:https://github.com/wechat-group/weixin-java-tools.git + scm:git:git@github.com:wechat-group/weixin-java-tools.git + https://github.com/wechat-group/weixin-java-tools + + + + weixin-java-common + weixin-java-cp + weixin-java-mp + weixin-java-pay + weixin-java-miniapp + weixin-java-open + + + + + 1.7 + 1.7 + + UTF-8 + true + true + 4.5 + 9.3.0.RC0 + + + + + + com.github.binarywang + qrcode-utils + 1.1 + + + + org.jodd + jodd-http + 3.7.1 + provided + + + com.squareup.okhttp3 + okhttp + 3.7.0 + provided + + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + org.apache.httpcomponents + httpmime + ${httpclient.version} + + + commons-codec + commons-codec + 1.10 + + + commons-io + commons-io + 2.5 + + + org.apache.commons + commons-lang3 + 3.5 + + + org.slf4j + slf4j-api + 1.7.24 + + + com.thoughtworks.xstream + xstream + 1.4.9 + + + + com.google.guava + guava + 20.0 + + + com.google.code.gson + gson + 2.8.0 + + + + + joda-time + joda-time + 2.9.7 + test + + + ch.qos.logback + logback-classic + 1.1.11 + test + + + com.google.inject + guice + 3.0 + test + + + org.testng + testng + 6.10 + test + + + org.mockito + mockito-all + 1.9.5 + test + + + org.eclipse.jetty + jetty-server + ${jetty.version} + test + + + org.eclipse.jetty + jetty-servlet + ${jetty.version} + test + + + redis.clients + jedis + 2.9.0 + provided + + + org.projectlombok + lombok + 1.16.18 + compile + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + doclint-java8-disable + + [1.8,) + + + -Xdoclint:none + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + ${javadoc.opts} + UTF-8 + zh_CN + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.17 + + true + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + true + + ossrh + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.1 + + true + false + release + deploy + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.0 + + UTF-8 + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.17 + + quality-checks/google_checks.xml + true + true + true + + + + verify + + check + + + + + + + + diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 769c0bea6c..25dc5bd1fa 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -1,128 +1,128 @@ - - - 4.0.0 - - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - - - weixin-java-common - WeiXin Java Tools - Common - 微信公众号、企业号Java SDK Common - - - - org.jodd - jodd-http - provided - - - com.squareup.okhttp3 - okhttp - provided - - - - org.slf4j - slf4j-api - - - com.thoughtworks.xstream - xstream - - - org.apache.httpcomponents - httpclient - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - httpmime - - - org.slf4j - jcl-over-slf4j - 1.7.24 - - - - com.google.code.gson - gson - - - commons-codec - commons-codec - - - commons-io - commons-io - - - org.apache.commons - commons-lang3 - - - com.google.guava - guava - - - org.projectlombok - lombok - - - - ch.qos.logback - logback-classic - test - - - org.testng - testng - test - - - org.mockito - mockito-all - test - - - com.google.inject - guice - test - - - org.eclipse.jetty - jetty-server - test - - - org.eclipse.jetty - jetty-servlet - test - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - src/test/resources/testng.xml - - - - - - - + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + + + weixin-java-common + WeiXin Java Tools - Common + 微信公众号、企业号Java SDK Common + + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + + org.slf4j + slf4j-api + + + com.thoughtworks.xstream + xstream + + + org.apache.httpcomponents + httpclient + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpmime + + + org.slf4j + jcl-over-slf4j + 1.7.24 + + + + com.google.code.gson + gson + + + commons-codec + commons-codec + + + commons-io + commons-io + + + org.apache.commons + commons-lang3 + + + com.google.guava + guava + + + org.projectlombok + lombok + + + + ch.qos.logback + logback-classic + test + + + org.testng + testng + test + + + org.mockito + mockito-all + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java index 3e6d6da197..6327965152 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java @@ -1,20 +1,20 @@ -package me.chanjar.weixin.common.bean; - -import lombok.Data; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.Serializable; - -@Data -public class WxAccessToken implements Serializable { - private static final long serialVersionUID = 8709719312922168909L; - - private String accessToken; - - private int expiresIn = -1; - - public static WxAccessToken fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxAccessToken.class); - } - -} +package me.chanjar.weixin.common.bean; + +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxAccessToken implements Serializable { + private static final long serialVersionUID = 8709719312922168909L; + + private String accessToken; + + private int expiresIn = -1; + + public static WxAccessToken fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxAccessToken.class); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java index 19fb06a74c..9d5d7a06dd 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java @@ -1,41 +1,41 @@ -package me.chanjar.weixin.common.bean; - -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; - -/** - * 卡券Api签名. - * - * @author YuJian - * @version 15/11/8 - */ -@Data -public class WxCardApiSignature implements Serializable { - private static final long serialVersionUID = 158176707226975979L; - - private String appId; - - private String cardId; - - private String cardType; - - private String locationId; - - private String code; - - private String openId; - - private Long timestamp; - - private String nonceStr; - - private String signature; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.common.bean; + +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; + +import java.io.Serializable; + +/** + * 卡券Api签名. + * + * @author YuJian + * @version 15/11/8 + */ +@Data +public class WxCardApiSignature implements Serializable { + private static final long serialVersionUID = 158176707226975979L; + + private String appId; + + private String cardId; + + private String cardType; + + private String locationId; + + private String code; + + private String openId; + + private Long timestamp; + + private String nonceStr; + + private String signature; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java index 899a32cf51..619f0a7504 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.common.bean; - -import lombok.Data; - -import java.io.Serializable; - -/** - * jspai signature. - */ -@Data -public class WxJsapiSignature implements Serializable { - private static final long serialVersionUID = -1116808193154384804L; - - private String appId; - - private String nonceStr; - - private long timestamp; - - private String url; - - private String signature; - -} +package me.chanjar.weixin.common.bean; + +import lombok.Data; + +import java.io.Serializable; + +/** + * jspai signature. + */ +@Data +public class WxJsapiSignature implements Serializable { + private static final long serialVersionUID = -1116808193154384804L; + + private String appId; + + private String nonceStr; + + private long timestamp; + + private String url; + + private String signature; + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java index 327c613178..4d349acb25 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java @@ -1,53 +1,53 @@ -package me.chanjar.weixin.common.bean.menu; - -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; - -/** - * 菜单(公众号和企业号共用的). - * - * @author Daniel Qian - */ -@Data -public class WxMenu implements Serializable { - private static final long serialVersionUID = -7083914585539687746L; - - private List buttons = new ArrayList<>(); - - private WxMenuRule matchRule; - - /** - * 要用 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html 格式来反序列化 - * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu - */ - public static WxMenu fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxMenu.class); - } - - /** - * 要用 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html 格式来反序列化 - * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu - */ - public static WxMenu fromJson(InputStream is) { - return WxGsonBuilder.create() - .fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class); - } - - public String toJson() { - return WxGsonBuilder.create().toJson(this); - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.common.bean.menu; + +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * 菜单(公众号和企业号共用的). + * + * @author Daniel Qian + */ +@Data +public class WxMenu implements Serializable { + private static final long serialVersionUID = -7083914585539687746L; + + private List buttons = new ArrayList<>(); + + private WxMenuRule matchRule; + + /** + * 要用 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html 格式来反序列化 + * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu + */ + public static WxMenu fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxMenu.class); + } + + /** + * 要用 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html 格式来反序列化 + * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu + */ + public static WxMenu fromJson(InputStream is) { + return WxGsonBuilder.create() + .fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class); + } + + public String toJson() { + return WxGsonBuilder.create().toJson(this); + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java index abe3e04a05..2f9276b025 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java @@ -1,82 +1,82 @@ -package me.chanjar.weixin.common.bean.menu; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -@Data -public class WxMenuButton implements Serializable { - private static final long serialVersionUID = -1070939403109776555L; - - /** - *

-   * 菜单的响应动作类型.
-   * view表示网页类型,
-   * click表示点击类型,
-   * miniprogram表示小程序类型
-   * 
- */ - private String type; - - /** - * 菜单标题,不超过16个字节,子菜单不超过60个字节. - */ - private String name; - - /** - *
-   * 菜单KEY值,用于消息接口推送,不超过128字节.
-   * click等点击类型必须
-   * 
- */ - private String key; - - /** - *
-   * 网页链接.
-   * 用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
-   * view、miniprogram类型必须
-   * 
- */ - private String url; - - /** - *
-   * 调用新增永久素材接口返回的合法media_id.
-   * media_id类型和view_limited类型必须
-   * 
- */ - @SerializedName("media_id") - private String mediaId; - - /** - *
-   * 小程序的appid.
-   * miniprogram类型必须
-   * 
- */ - @SerializedName("appid") - private String appId; - - /** - *
-   * 小程序的页面路径.
-   * miniprogram类型必须
-   * 
- */ - @SerializedName("pagepath") - private String pagePath; - - @SerializedName("sub_button") - private List subButtons = new ArrayList<>(); - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.common.bean.menu; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@Data +public class WxMenuButton implements Serializable { + private static final long serialVersionUID = -1070939403109776555L; + + /** + *
+   * 菜单的响应动作类型.
+   * view表示网页类型,
+   * click表示点击类型,
+   * miniprogram表示小程序类型
+   * 
+ */ + private String type; + + /** + * 菜单标题,不超过16个字节,子菜单不超过60个字节. + */ + private String name; + + /** + *
+   * 菜单KEY值,用于消息接口推送,不超过128字节.
+   * click等点击类型必须
+   * 
+ */ + private String key; + + /** + *
+   * 网页链接.
+   * 用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
+   * view、miniprogram类型必须
+   * 
+ */ + private String url; + + /** + *
+   * 调用新增永久素材接口返回的合法media_id.
+   * media_id类型和view_limited类型必须
+   * 
+ */ + @SerializedName("media_id") + private String mediaId; + + /** + *
+   * 小程序的appid.
+   * miniprogram类型必须
+   * 
+ */ + @SerializedName("appid") + private String appId; + + /** + *
+   * 小程序的页面路径.
+   * miniprogram类型必须
+   * 
+ */ + @SerializedName("pagepath") + private String pagePath; + + @SerializedName("sub_button") + private List subButtons = new ArrayList<>(); + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java index 6e8ea66b01..16542dec69 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java @@ -1,29 +1,29 @@ -package me.chanjar.weixin.common.bean.menu; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; - -@Data -public class WxMenuRule implements Serializable { - private static final long serialVersionUID = -4587181819499286670L; - - /** - * 变态的微信接口,反序列化时这里反人类的使用和序列化时不一样的名字. - */ - @SerializedName(value = "tag_id", alternate = "group_id") - private String tagId; - private String sex; - private String country; - private String province; - private String city; - private String clientPlatformType; - private String language; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } -} +package me.chanjar.weixin.common.bean.menu; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; + +import java.io.Serializable; + +@Data +public class WxMenuRule implements Serializable { + private static final long serialVersionUID = -4587181819499286670L; + + /** + * 变态的微信接口,反序列化时这里反人类的使用和序列化时不一样的名字. + */ + @SerializedName(value = "tag_id", alternate = "group_id") + private String tagId; + private String sex; + private String country; + private String province; + private String city; + private String clientPlatformType; + private String language; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java index 5cee70306b..25a06f4785 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java @@ -1,38 +1,38 @@ -package me.chanjar.weixin.common.bean.result; - -import lombok.Builder; -import lombok.Data; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.Serializable; - -/** - * 微信错误码说明,请阅读: 全局返回码说明. - * - * @author Daniel Qian - */ -@Data -@Builder -public class WxError implements Serializable { - - private static final long serialVersionUID = 7869786563361406291L; - - private int errorCode; - - private String errorMsg; - - private String json; - - public static WxError fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxError.class); - } - - @Override - public String toString() { - if (this.json != null) { - return this.json; - } - return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; - } - -} +package me.chanjar.weixin.common.bean.result; + +import lombok.Builder; +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +/** + * 微信错误码说明,请阅读: 全局返回码说明. + * + * @author Daniel Qian + */ +@Data +@Builder +public class WxError implements Serializable { + + private static final long serialVersionUID = 7869786563361406291L; + + private int errorCode; + + private String errorMsg; + + private String json; + + public static WxError fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxError.class); + } + + @Override + public String toString() { + if (this.json != null) { + return this.json; + } + return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java index 7359b80763..a50018aaef 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java @@ -1,27 +1,27 @@ -package me.chanjar.weixin.common.bean.result; - -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.Serializable; - -@Data -public class WxMediaUploadResult implements Serializable { - private static final long serialVersionUID = 330834334738622341L; - - private String type; - private String mediaId; - private String thumbMediaId; - private long createdAt; - - public static WxMediaUploadResult fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class); - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.common.bean.result; + +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxMediaUploadResult implements Serializable { + private static final long serialVersionUID = 330834334738622341L; + + private String type; + private String mediaId; + private String thumbMediaId; + private long createdAt; + + public static WxMediaUploadResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class); + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java index 222809f34e..12ce3a4e13 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java @@ -1,106 +1,106 @@ -package me.chanjar.weixin.common.util; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import me.chanjar.weixin.common.annotation.Required; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -/** - *
- * bean操作的一些工具类
- * Created by Binary Wang on 2016-10-21.
- * 
- * - * @author binarywang(Binary Wang) - */ -public class BeanUtils { - private static Logger log = LoggerFactory.getLogger(BeanUtils.class); - - /** - * 检查bean里标记为@Required的field是否为空,为空则抛异常 - * - * @param bean 要检查的bean对象 - * @throws WxErrorException - */ - public static void checkRequiredFields(Object bean) throws WxErrorException { - List requiredFields = Lists.newArrayList(); - - List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); - fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); - for (Field field : fields) { - try { - boolean isAccessible = field.isAccessible(); - field.setAccessible(true); - if (field.isAnnotationPresent(Required.class)) { - // 两种情况,一种是值为null, - // 另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值 - boolean isRequiredMissing = field.get(bean) == null - || (field.get(bean) instanceof String - && StringUtils.isBlank(field.get(bean).toString()) - ); - if (isRequiredMissing) { - requiredFields.add(field.getName()); - } - } - field.setAccessible(isAccessible); - } catch (SecurityException | IllegalArgumentException - | IllegalAccessException e) { - log.error(e.getMessage(), e); - } - } - - if (!requiredFields.isEmpty()) { - String msg = "必填字段 " + requiredFields + " 必须提供值"; - log.debug(msg); - throw new WxErrorException(WxError.builder().errorMsg(msg).build()); - } - } - - /** - * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 - * - * @param bean 包含@XStreamAlias的xml bean对象 - * @return map对象 - */ - public static Map xmlBean2Map(Object bean) { - Map result = Maps.newHashMap(); - List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); - fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); - for (Field field : fields) { - try { - boolean isAccessible = field.isAccessible(); - field.setAccessible(true); - if (field.get(bean) == null) { - field.setAccessible(isAccessible); - continue; - } - - if (field.isAnnotationPresent(XStreamAlias.class)) { - result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); - } else if (!Modifier.isStatic(field.getModifiers())) { - //忽略掉静态成员变量 - result.put(field.getName(), field.get(bean).toString()); - } - - field.setAccessible(isAccessible); - } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { - log.error(e.getMessage(), e); - } - - } - - return result; - } -} +package me.chanjar.weixin.common.util; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import me.chanjar.weixin.common.annotation.Required; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + *
+ * bean操作的一些工具类
+ * Created by Binary Wang on 2016-10-21.
+ * 
+ * + * @author binarywang(Binary Wang) + */ +public class BeanUtils { + private static Logger log = LoggerFactory.getLogger(BeanUtils.class); + + /** + * 检查bean里标记为@Required的field是否为空,为空则抛异常 + * + * @param bean 要检查的bean对象 + * @throws WxErrorException + */ + public static void checkRequiredFields(Object bean) throws WxErrorException { + List requiredFields = Lists.newArrayList(); + + List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); + for (Field field : fields) { + try { + boolean isAccessible = field.isAccessible(); + field.setAccessible(true); + if (field.isAnnotationPresent(Required.class)) { + // 两种情况,一种是值为null, + // 另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值 + boolean isRequiredMissing = field.get(bean) == null + || (field.get(bean) instanceof String + && StringUtils.isBlank(field.get(bean).toString()) + ); + if (isRequiredMissing) { + requiredFields.add(field.getName()); + } + } + field.setAccessible(isAccessible); + } catch (SecurityException | IllegalArgumentException + | IllegalAccessException e) { + log.error(e.getMessage(), e); + } + } + + if (!requiredFields.isEmpty()) { + String msg = "必填字段 " + requiredFields + " 必须提供值"; + log.debug(msg); + throw new WxErrorException(WxError.builder().errorMsg(msg).build()); + } + } + + /** + * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 + * + * @param bean 包含@XStreamAlias的xml bean对象 + * @return map对象 + */ + public static Map xmlBean2Map(Object bean) { + Map result = Maps.newHashMap(); + List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); + for (Field field : fields) { + try { + boolean isAccessible = field.isAccessible(); + field.setAccessible(true); + if (field.get(bean) == null) { + field.setAccessible(isAccessible); + continue; + } + + if (field.isAnnotationPresent(XStreamAlias.class)) { + result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); + } else if (!Modifier.isStatic(field.getModifiers())) { + //忽略掉静态成员变量 + result.put(field.getName(), field.get(bean).toString()); + } + + field.setAccessible(isAccessible); + } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { + log.error(e.getMessage(), e); + } + + } + + return result; + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java index b12ec65555..bff08d680d 100755 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java @@ -1,26 +1,26 @@ -package me.chanjar.weixin.common.util.crypto; - -import java.util.ArrayList; - -public class ByteGroup { - ArrayList byteContainer = new ArrayList<>(); - - public byte[] toBytes() { - byte[] bytes = new byte[this.byteContainer.size()]; - for (int i = 0; i < this.byteContainer.size(); i++) { - bytes[i] = this.byteContainer.get(i); - } - return bytes; - } - - public ByteGroup addBytes(byte[] bytes) { - for (byte b : bytes) { - this.byteContainer.add(b); - } - return this; - } - - public int size() { - return this.byteContainer.size(); - } -} +package me.chanjar.weixin.common.util.crypto; + +import java.util.ArrayList; + +public class ByteGroup { + ArrayList byteContainer = new ArrayList<>(); + + public byte[] toBytes() { + byte[] bytes = new byte[this.byteContainer.size()]; + for (int i = 0; i < this.byteContainer.size(); i++) { + bytes[i] = this.byteContainer.get(i); + } + return bytes; + } + + public ByteGroup addBytes(byte[] bytes) { + for (byte b : bytes) { + this.byteContainer.add(b); + } + return this; + } + + public int size() { + return this.byteContainer.size(); + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java index 145896a577..8ce94cbac0 100755 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java @@ -1,68 +1,68 @@ -/** - * 对公众平台发送给公众账号的消息加解密示例代码. - * - * @copyright Copyright (c) 1998-2014 Tencent Inc. - */ - -// ------------------------------------------------------------------------ - -package me.chanjar.weixin.common.util.crypto; - -import java.nio.charset.Charset; -import java.util.Arrays; - -/** - * 提供基于PKCS7算法的加解 - */ -public class PKCS7Encoder { - - private static final Charset CHARSET = Charset.forName("utf-8"); - private static final int BLOCK_SIZE = 32; - - /** - * 获得对明文进行补位填充的字节. - * - * @param count 需要进行填充补位操作的明文字节个数 - * @return 补齐用的字节数组 - */ - public static byte[] encode(int count) { - // 计算需要填充的位数 - int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); - if (amountToPad == 0) { - amountToPad = BLOCK_SIZE; - } - // 获得补位所用的字符 - char padChr = chr(amountToPad); - String tmp = new String(); - for (int index = 0; index < amountToPad; index++) { - tmp += padChr; - } - return tmp.getBytes(CHARSET); - } - - /** - * 删除解密后明文的补位字符 - * - * @param decrypted 解密后的明文 - * @return 删除补位字符后的明文 - */ - public static byte[] decode(byte[] decrypted) { - int pad = decrypted[decrypted.length - 1]; - if (pad < 1 || pad > 32) { - pad = 0; - } - return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); - } - - /** - * 将数字转化成ASCII码对应的字符,用于对明文进行补码 - * - * @param a 需要转化的数字 - * @return 转化得到的字符 - */ - public static char chr(int a) { - byte target = (byte) (a & 0xFF); - return (char) target; - } - -} +/** + * 对公众平台发送给公众账号的消息加解密示例代码. + * + * @copyright Copyright (c) 1998-2014 Tencent Inc. + */ + +// ------------------------------------------------------------------------ + +package me.chanjar.weixin.common.util.crypto; + +import java.nio.charset.Charset; +import java.util.Arrays; + +/** + * 提供基于PKCS7算法的加解 + */ +public class PKCS7Encoder { + + private static final Charset CHARSET = Charset.forName("utf-8"); + private static final int BLOCK_SIZE = 32; + + /** + * 获得对明文进行补位填充的字节. + * + * @param count 需要进行填充补位操作的明文字节个数 + * @return 补齐用的字节数组 + */ + public static byte[] encode(int count) { + // 计算需要填充的位数 + int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); + if (amountToPad == 0) { + amountToPad = BLOCK_SIZE; + } + // 获得补位所用的字符 + char padChr = chr(amountToPad); + String tmp = new String(); + for (int index = 0; index < amountToPad; index++) { + tmp += padChr; + } + return tmp.getBytes(CHARSET); + } + + /** + * 删除解密后明文的补位字符 + * + * @param decrypted 解密后的明文 + * @return 删除补位字符后的明文 + */ + public static byte[] decode(byte[] decrypted) { + int pad = decrypted[decrypted.length - 1]; + if (pad < 1 || pad > 32) { + pad = 0; + } + return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); + } + + /** + * 将数字转化成ASCII码对应的字符,用于对明文进行补码 + * + * @param a 需要转化的数字 + * @return 转化得到的字符 + */ + public static char chr(int a) { + byte target = (byte) (a & 0xFF); + return (char) target; + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java index 08a59b7140..37efdaaf38 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java @@ -1,90 +1,90 @@ -package me.chanjar.weixin.common.util.http; - -import jodd.http.HttpResponse; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import okhttp3.Response; -import org.apache.http.Header; -import org.apache.http.client.methods.CloseableHttpResponse; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - *
- * 三种http框架的response代理类,方便提取公共方法
- * Created by Binary Wang on 2017-8-3.
- * 
- * - * @author Binary Wang - */ -public class HttpResponseProxy { - private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\""); - - private CloseableHttpResponse apacheHttpResponse; - private HttpResponse joddHttpResponse; - private Response okHttpResponse; - - public HttpResponseProxy(CloseableHttpResponse apacheHttpResponse) { - this.apacheHttpResponse = apacheHttpResponse; - } - - public HttpResponseProxy(HttpResponse joddHttpResponse) { - this.joddHttpResponse = joddHttpResponse; - } - - public HttpResponseProxy(Response okHttpResponse) { - this.okHttpResponse = okHttpResponse; - } - - public String getFileName() throws WxErrorException { - //由于对象只能由一个构造方法实现,因此三个response对象必定且只有一个不为空 - if (this.apacheHttpResponse != null) { - return this.getFileName(this.apacheHttpResponse); - } - - if (this.joddHttpResponse != null) { - return this.getFileName(this.joddHttpResponse); - } - - if (this.okHttpResponse != null) { - return this.getFileName(this.okHttpResponse); - } - - //cannot happen - return null; - } - - private String getFileName(CloseableHttpResponse response) throws WxErrorException { - Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); - if (contentDispositionHeader == null || contentDispositionHeader.length == 0) { - throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); - } - - return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue()); - } - - private String getFileName(HttpResponse response) throws WxErrorException { - String content = response.header("Content-disposition"); - return this.extractFileNameFromContentString(content); - } - - private String getFileName(Response response) throws WxErrorException { - String content = response.header("Content-disposition"); - return this.extractFileNameFromContentString(content); - } - - private String extractFileNameFromContentString(String content) throws WxErrorException { - if (content == null || content.length() == 0) { - throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); - } - - Matcher m = PATTERN.matcher(content); - if (m.matches()) { - return m.group(1); - } - - throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); - } - -} +package me.chanjar.weixin.common.util.http; + +import jodd.http.HttpResponse; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import okhttp3.Response; +import org.apache.http.Header; +import org.apache.http.client.methods.CloseableHttpResponse; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *
+ * 三种http框架的response代理类,方便提取公共方法
+ * Created by Binary Wang on 2017-8-3.
+ * 
+ * + * @author Binary Wang + */ +public class HttpResponseProxy { + private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\""); + + private CloseableHttpResponse apacheHttpResponse; + private HttpResponse joddHttpResponse; + private Response okHttpResponse; + + public HttpResponseProxy(CloseableHttpResponse apacheHttpResponse) { + this.apacheHttpResponse = apacheHttpResponse; + } + + public HttpResponseProxy(HttpResponse joddHttpResponse) { + this.joddHttpResponse = joddHttpResponse; + } + + public HttpResponseProxy(Response okHttpResponse) { + this.okHttpResponse = okHttpResponse; + } + + public String getFileName() throws WxErrorException { + //由于对象只能由一个构造方法实现,因此三个response对象必定且只有一个不为空 + if (this.apacheHttpResponse != null) { + return this.getFileName(this.apacheHttpResponse); + } + + if (this.joddHttpResponse != null) { + return this.getFileName(this.joddHttpResponse); + } + + if (this.okHttpResponse != null) { + return this.getFileName(this.okHttpResponse); + } + + //cannot happen + return null; + } + + private String getFileName(CloseableHttpResponse response) throws WxErrorException { + Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); + if (contentDispositionHeader == null || contentDispositionHeader.length == 0) { + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); + } + + return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue()); + } + + private String getFileName(HttpResponse response) throws WxErrorException { + String content = response.header("Content-disposition"); + return this.extractFileNameFromContentString(content); + } + + private String getFileName(Response response) throws WxErrorException { + String content = response.header("Content-disposition"); + return this.extractFileNameFromContentString(content); + } + + private String extractFileNameFromContentString(String content) throws WxErrorException { + if (content == null || content.length() == 0) { + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); + } + + Matcher m = PATTERN.matcher(content); + if (m.matches()) { + return m.group(1); + } + + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java index 811a631401..1a8a292b9f 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java @@ -1,59 +1,59 @@ -package me.chanjar.weixin.common.util.http.apache; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; -import org.apache.http.Consts; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.IOException; - -/** - * Created by ecoolper on 2017/5/4. - */ -public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor { - - public ApacheSimplePostRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public String execute(String uri, String postEntity) throws WxErrorException, IOException { - HttpPost httpPost = new HttpPost(uri); - if (requestHttp.getRequestHttpProxy() != null) { - RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); - httpPost.setConfig(config); - } - - if (postEntity != null) { - StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); - httpPost.setEntity(entity); - } - - try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - if (responseContent.isEmpty()) { - throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); - } - - if (responseContent.startsWith("")) { - //xml格式输出直接返回 - return responseContent; - } - - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - return responseContent; - } finally { - httpPost.releaseConnection(); - } - } -} +package me.chanjar.weixin.common.util.http.apache; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import org.apache.http.Consts; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.IOException; + +/** + * Created by ecoolper on 2017/5/4. + */ +public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor { + + public ApacheSimplePostRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public String execute(String uri, String postEntity) throws WxErrorException, IOException { + HttpPost httpPost = new HttpPost(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(config); + } + + if (postEntity != null) { + StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); + httpPost.setEntity(entity); + } + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + if (responseContent.isEmpty()) { + throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); + } + + if (responseContent.startsWith("")) { + //xml格式输出直接返回 + return responseContent; + } + + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + return responseContent; + } finally { + httpPost.releaseConnection(); + } + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java index d3456a55f1..57207f1b3e 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java @@ -1,58 +1,58 @@ -package me.chanjar.weixin.common.util.http.jodd; - -import jodd.http.HttpConnectionProvider; -import jodd.http.HttpRequest; -import jodd.http.HttpResponse; -import jodd.http.ProxyInfo; -import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; - -import java.io.IOException; - -/** - * Created by ecoolper on 2017/5/4. - */ -public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor { - - public JoddHttpSimplePostRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public String execute(String uri, String postEntity) throws WxErrorException, IOException { - HttpConnectionProvider provider = requestHttp.getRequestHttpClient(); - ProxyInfo proxyInfo = requestHttp.getRequestHttpProxy(); - - HttpRequest request = HttpRequest.post(uri); - if (proxyInfo != null) { - provider.useProxy(proxyInfo); - } - request.withConnectionProvider(provider); - if (postEntity != null) { - request.bodyText(postEntity); - } - HttpResponse response = request.send(); - response.charset(StringPool.UTF_8); - - String responseContent = response.bodyText(); - if (responseContent.isEmpty()) { - throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容") - .build()); - } - - if (responseContent.startsWith("")) { - //xml格式输出直接返回 - return responseContent; - } - - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - return responseContent; - } - -} +package me.chanjar.weixin.common.util.http.jodd; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import jodd.util.StringPool; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; + +import java.io.IOException; + +/** + * Created by ecoolper on 2017/5/4. + */ +public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor { + + public JoddHttpSimplePostRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public String execute(String uri, String postEntity) throws WxErrorException, IOException { + HttpConnectionProvider provider = requestHttp.getRequestHttpClient(); + ProxyInfo proxyInfo = requestHttp.getRequestHttpProxy(); + + HttpRequest request = HttpRequest.post(uri); + if (proxyInfo != null) { + provider.useProxy(proxyInfo); + } + request.withConnectionProvider(provider); + if (postEntity != null) { + request.bodyText(postEntity); + } + HttpResponse response = request.send(); + response.charset(StringPool.UTF_8); + + String responseContent = response.bodyText(); + if (responseContent.isEmpty()) { + throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容") + .build()); + } + + if (responseContent.startsWith("")) { + //xml格式输出直接返回 + return responseContent; + } + + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + return responseContent; + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java index a6363be7e3..abd0da6052 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java @@ -1,39 +1,39 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ -package me.chanjar.weixin.common.util.json; - -import com.google.gson.*; -import me.chanjar.weixin.common.bean.result.WxError; - -import java.lang.reflect.Type; - -/** - * @author Daniel Qian. - */ -public class WxErrorAdapter implements JsonDeserializer { - - @Override - public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - WxError.WxErrorBuilder errorBuilder = WxError.builder(); - JsonObject wxErrorJsonObject = json.getAsJsonObject(); - - if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) { - errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode"))); - } - if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) { - errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg"))); - } - - errorBuilder.json(json.toString()); - - return errorBuilder.build(); - } - -} +/* + * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. + * + * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended + * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction + * arose from modification of the original source, or other redistribution of this source + * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. + */ +package me.chanjar.weixin.common.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.bean.result.WxError; + +import java.lang.reflect.Type; + +/** + * @author Daniel Qian. + */ +public class WxErrorAdapter implements JsonDeserializer { + + @Override + public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + WxError.WxErrorBuilder errorBuilder = WxError.builder(); + JsonObject wxErrorJsonObject = json.getAsJsonObject(); + + if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) { + errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode"))); + } + if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) { + errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg"))); + } + + errorBuilder.json(json.toString()); + + return errorBuilder.build(); + } + +} diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java index f9d57d3f28..1c05ea731e 100644 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java @@ -1,36 +1,36 @@ -package me.chanjar.weixin.common.bean; - -import me.chanjar.weixin.common.bean.result.WxError; -import org.testng.*; -import org.testng.annotations.*; - -@Test -public class WxErrorTest { - - public void testFromJson() { - String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; - WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 40003); - Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); - - } - - public void testFromBadJson1() { - - String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; - WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 40003); - Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); - - } - - public void testFromBadJson2() { - - String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; - WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 0); - Assert.assertEquals(wxError.getErrorMsg(), null); - - } - -} +package me.chanjar.weixin.common.bean; + +import me.chanjar.weixin.common.bean.result.WxError; +import org.testng.*; +import org.testng.annotations.*; + +@Test +public class WxErrorTest { + + public void testFromJson() { + String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; + WxError wxError = WxError.fromJson(json); + Assert.assertTrue(wxError.getErrorCode() == 40003); + Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); + + } + + public void testFromBadJson1() { + + String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; + WxError wxError = WxError.fromJson(json); + Assert.assertTrue(wxError.getErrorCode() == 40003); + Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); + + } + + public void testFromBadJson2() { + + String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; + WxError wxError = WxError.fromJson(json); + Assert.assertTrue(wxError.getErrorCode() == 0); + Assert.assertEquals(wxError.getErrorMsg(), null); + + } + +} diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 776356b94c..96dba9c9d6 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -1,88 +1,88 @@ - - - 4.0.0 - - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - - - weixin-java-cp - WeiXin Java Tools - CP - 微信企业号Java SDK - - - - com.github.binarywang - weixin-java-common - ${project.version} - - - org.jodd - jodd-http - provided - - - com.squareup.okhttp3 - okhttp - provided - - - redis.clients - jedis - - - org.slf4j - slf4j-api - - - - org.testng - testng - test - - - org.mockito - mockito-all - test - - - com.google.inject - guice - test - - - org.eclipse.jetty - jetty-server - test - - - org.eclipse.jetty - jetty-servlet - test - - - ch.qos.logback - logback-classic - test - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - src/test/resources/testng.xml - - - - - - - + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + + + weixin-java-cp + WeiXin Java Tools - CP + 微信企业号Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + redis.clients + jedis + + + org.slf4j + slf4j-api + + + + org.testng + testng + test + + + org.mockito + mockito-all + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + ch.qos.logback + logback-classic + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java index b5e2f6e533..af9219cfe8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java @@ -1,100 +1,100 @@ -package me.chanjar.weixin.cp.api.impl; - -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.HttpType; -import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import okhttp3.*; - -import java.io.IOException; - -public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl { - protected OkHttpClient httpClient; - protected OkHttpProxyInfo httpProxy; - - - @Override - public OkHttpClient getRequestHttpClient() { - return httpClient; - } - - @Override - public OkHttpProxyInfo getRequestHttpProxy() { - return httpProxy; - } - - @Override - public HttpType getRequestType() { - return HttpType.OK_HTTP; - } - - @Override - public String getAccessToken(boolean forceRefresh) throws WxErrorException { - this.log.debug("WxCpServiceOkHttpImpl is running"); - if (this.configStorage.isAccessTokenExpired() || forceRefresh) { - synchronized (this.globalAccessTokenRefreshLock) { - if (this.configStorage.isAccessTokenExpired()) { - String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" - + "&corpid=" + this.configStorage.getCorpId() - + "&corpsecret=" + this.configStorage.getCorpSecret(); - //得到httpClient - OkHttpClient client = getRequestHttpClient(); - //请求的request - Request request = new Request.Builder().url(url).get().build(); - String resultContent = null; - try { - Response response = client.newCall(request).execute(); - resultContent = response.body().string(); - } catch (IOException e) { - this.log.error(e.getMessage(), e); - } - - WxError error = WxError.fromJson(resultContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); - this.configStorage.updateAccessToken(accessToken.getAccessToken(), - accessToken.getExpiresIn()); - } - } - } - return this.configStorage.getAccessToken(); - } - - @Override - public void initHttp() { - this.log.debug("WxCpServiceOkHttpImpl initHttp"); - //设置代理 - if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { - httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(), - configStorage.getHttpProxyPort(), - configStorage.getHttpProxyUsername(), - configStorage.getHttpProxyPassword()); - } - - OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); - if (httpProxy != null) { - clientBuilder.proxy(getRequestHttpProxy().getProxy()); - - //设置授权 - clientBuilder.authenticator(new Authenticator() { - @Override - public Request authenticate(Route route, Response response) throws IOException { - String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword()); - return response.request().newBuilder() - .header("Authorization", credential) - .build(); - } - }); - } - httpClient = clientBuilder.build(); - } - - @Override - public WxCpConfigStorage getWxCpConfigStorage() { - return this.configStorage; - } -} +package me.chanjar.weixin.cp.api.impl; + +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.HttpType; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.cp.config.WxCpConfigStorage; +import okhttp3.*; + +import java.io.IOException; + +public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl { + protected OkHttpClient httpClient; + protected OkHttpProxyInfo httpProxy; + + + @Override + public OkHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public OkHttpProxyInfo getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpType getRequestType() { + return HttpType.OK_HTTP; + } + + @Override + public String getAccessToken(boolean forceRefresh) throws WxErrorException { + this.log.debug("WxCpServiceOkHttpImpl is running"); + if (this.configStorage.isAccessTokenExpired() || forceRefresh) { + synchronized (this.globalAccessTokenRefreshLock) { + if (this.configStorage.isAccessTokenExpired()) { + String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" + + "&corpid=" + this.configStorage.getCorpId() + + "&corpsecret=" + this.configStorage.getCorpSecret(); + //得到httpClient + OkHttpClient client = getRequestHttpClient(); + //请求的request + Request request = new Request.Builder().url(url).get().build(); + String resultContent = null; + try { + Response response = client.newCall(request).execute(); + resultContent = response.body().string(); + } catch (IOException e) { + this.log.error(e.getMessage(), e); + } + + WxError error = WxError.fromJson(resultContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); + this.configStorage.updateAccessToken(accessToken.getAccessToken(), + accessToken.getExpiresIn()); + } + } + } + return this.configStorage.getAccessToken(); + } + + @Override + public void initHttp() { + this.log.debug("WxCpServiceOkHttpImpl initHttp"); + //设置代理 + if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { + httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(), + configStorage.getHttpProxyPort(), + configStorage.getHttpProxyUsername(), + configStorage.getHttpProxyPassword()); + } + + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + if (httpProxy != null) { + clientBuilder.proxy(getRequestHttpProxy().getProxy()); + + //设置授权 + clientBuilder.authenticator(new Authenticator() { + @Override + public Request authenticate(Route route, Response response) throws IOException { + String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword()); + return response.request().newBuilder() + .header("Authorization", credential) + .build(); + } + }); + } + httpClient = clientBuilder.build(); + } + + @Override + public WxCpConfigStorage getWxCpConfigStorage() { + return this.configStorage; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java index 5ff90f7d1c..2890ce61eb 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java @@ -1,30 +1,30 @@ -package me.chanjar.weixin.cp.bean; - -import lombok.Data; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - -import java.io.Serializable; - -/** - * 微信部门. - * - * @author Daniel Qian - */ -@Data -public class WxCpDepart implements Serializable { - - private static final long serialVersionUID = -5028321625140879571L; - private Integer id; - private String name; - private Integer parentId; - private Long order; - - public static WxCpDepart fromJson(String json) { - return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); - } - - public String toJson() { - return WxCpGsonBuilder.create().toJson(this); - } - -} +package me.chanjar.weixin.cp.bean; + +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 微信部门. + * + * @author Daniel Qian + */ +@Data +public class WxCpDepart implements Serializable { + + private static final long serialVersionUID = -5028321625140879571L; + private Integer id; + private String name; + private Integer parentId; + private Long order; + + public static WxCpDepart fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java index 8ea4fbf8a7..403e9dc365 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java @@ -1,119 +1,119 @@ -package me.chanjar.weixin.cp.bean; - -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.bean.article.MpnewsArticle; -import me.chanjar.weixin.cp.bean.article.NewArticle; -import me.chanjar.weixin.cp.bean.messagebuilder.*; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * 消息. - * - * @author Daniel Qian - */ -@Data -public class WxCpMessage implements Serializable { - private static final long serialVersionUID = -2082278303476631708L; - - private String toUser; - private String toParty; - private String toTag; - private Integer agentId; - private String msgType; - private String content; - private String mediaId; - private String thumbMediaId; - private String title; - private String description; - private String musicUrl; - private String hqMusicUrl; - private String safe; - private String url; - private List articles = new ArrayList<>(); - private List mpnewsArticles = new ArrayList<>(); - - /** - * 获得文本消息builder. - */ - public static TextBuilder TEXT() { - return new TextBuilder(); - } - - /** - * 获得文本卡片消息builder. - */ - public static TextCardBuilder TEXTCARD() { - return new TextCardBuilder(); - } - - /** - * 获得图片消息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(); - } - - /** - * 获得mpnews图文消息builder. - */ - public static MpnewsBuilder MPNEWS() { - return new MpnewsBuilder(); - } - - /** - * 获得文件消息builder. - */ - public static FileBuilder FILE() { - return new FileBuilder(); - } - - - /** - *
-   * 请使用
-   * {@link WxConsts.KefuMsgType#TEXT}
-   * {@link WxConsts.KefuMsgType#IMAGE}
-   * {@link WxConsts.KefuMsgType#VOICE}
-   * {@link WxConsts.KefuMsgType#MUSIC}
-   * {@link WxConsts.KefuMsgType#VIDEO}
-   * {@link WxConsts.KefuMsgType#NEWS}
-   * {@link WxConsts.KefuMsgType#MPNEWS}
-   * 
- * - * @param msgType 消息类型 - */ - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - public String toJson() { - return WxCpGsonBuilder.INSTANCE.create().toJson(this); - } - -} +package me.chanjar.weixin.cp.bean; + +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.cp.bean.article.MpnewsArticle; +import me.chanjar.weixin.cp.bean.article.NewArticle; +import me.chanjar.weixin.cp.bean.messagebuilder.*; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 消息. + * + * @author Daniel Qian + */ +@Data +public class WxCpMessage implements Serializable { + private static final long serialVersionUID = -2082278303476631708L; + + private String toUser; + private String toParty; + private String toTag; + private Integer agentId; + private String msgType; + private String content; + private String mediaId; + private String thumbMediaId; + private String title; + private String description; + private String musicUrl; + private String hqMusicUrl; + private String safe; + private String url; + private List articles = new ArrayList<>(); + private List mpnewsArticles = new ArrayList<>(); + + /** + * 获得文本消息builder. + */ + public static TextBuilder TEXT() { + return new TextBuilder(); + } + + /** + * 获得文本卡片消息builder. + */ + public static TextCardBuilder TEXTCARD() { + return new TextCardBuilder(); + } + + /** + * 获得图片消息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(); + } + + /** + * 获得mpnews图文消息builder. + */ + public static MpnewsBuilder MPNEWS() { + return new MpnewsBuilder(); + } + + /** + * 获得文件消息builder. + */ + public static FileBuilder FILE() { + return new FileBuilder(); + } + + + /** + *
+   * 请使用
+   * {@link WxConsts.KefuMsgType#TEXT}
+   * {@link WxConsts.KefuMsgType#IMAGE}
+   * {@link WxConsts.KefuMsgType#VOICE}
+   * {@link WxConsts.KefuMsgType#MUSIC}
+   * {@link WxConsts.KefuMsgType#VIDEO}
+   * {@link WxConsts.KefuMsgType#NEWS}
+   * {@link WxConsts.KefuMsgType#MPNEWS}
+   * 
+ * + * @param msgType 消息类型 + */ + public void setMsgType(String msgType) { + this.msgType = msgType; + } + + public String toJson() { + return WxCpGsonBuilder.INSTANCE.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java index d8159c0fd8..e54a01eccd 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java @@ -1,68 +1,68 @@ -package me.chanjar.weixin.cp.bean; - -import com.google.common.base.Splitter; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import org.apache.commons.lang3.StringUtils; - -import java.io.Serializable; -import java.util.Collections; -import java.util.List; - -/** - * 消息发送结果对象类. - * Created by Binary Wang on 2017-6-22. - * - * @author Binary Wang - */ -@Data -public class WxCpMessageSendResult implements Serializable { - private static final long serialVersionUID = 916455987193190004L; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public static WxCpMessageSendResult fromJson(String json) { - return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpMessageSendResult.class); - } - - @SerializedName("errcode") - private Integer errCode; - - @SerializedName("errmsg") - private String errMsg; - - @SerializedName("invaliduser") - private String invalidUser; - - @SerializedName("invalidparty") - private String invalidParty; - - @SerializedName("invalidtag") - private String invalidTag; - - - public List getInvalidUserList() { - return this.content2List(this.invalidUser); - } - - private List content2List(String content) { - if (StringUtils.isBlank(content)) { - return Collections.emptyList(); - } - - return Splitter.on("|").splitToList(content); - } - - public List getInvalidPartyList() { - return this.content2List(this.invalidParty); - } - - public List getInvalidTagList() { - return this.content2List(this.invalidTag); - } -} +package me.chanjar.weixin.cp.bean; + +import com.google.common.base.Splitter; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +/** + * 消息发送结果对象类. + * Created by Binary Wang on 2017-6-22. + * + * @author Binary Wang + */ +@Data +public class WxCpMessageSendResult implements Serializable { + private static final long serialVersionUID = 916455987193190004L; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + public static WxCpMessageSendResult fromJson(String json) { + return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpMessageSendResult.class); + } + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("invaliduser") + private String invalidUser; + + @SerializedName("invalidparty") + private String invalidParty; + + @SerializedName("invalidtag") + private String invalidTag; + + + public List getInvalidUserList() { + return this.content2List(this.invalidUser); + } + + private List content2List(String content) { + if (StringUtils.isBlank(content)) { + return Collections.emptyList(); + } + + return Splitter.on("|").splitToList(content); + } + + public List getInvalidPartyList() { + return this.content2List(this.invalidParty); + } + + public List getInvalidTagList() { + return this.content2List(this.invalidTag); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java index 7724948160..360ddd28be 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java @@ -1,32 +1,32 @@ -package me.chanjar.weixin.cp.bean; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - -import java.io.Serializable; - -/** - * Created by Daniel Qian. - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class WxCpTag implements Serializable { - private static final long serialVersionUID = -7243320279646928402L; - - private String id; - - private String name; - - - public static WxCpTag fromJson(String json) { - return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); - } - - public String toJson() { - return WxCpGsonBuilder.create().toJson(this); - } - -} +package me.chanjar.weixin.cp.bean; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * Created by Daniel Qian. + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class WxCpTag implements Serializable { + private static final long serialVersionUID = -7243320279646928402L; + + private String id; + + private String name; + + + public static WxCpTag fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java index 5179fc7f0c..3d89c073fc 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java @@ -1,57 +1,57 @@ -package me.chanjar.weixin.cp.bean; - -import com.google.common.base.Splitter; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import org.apache.commons.lang3.StringUtils; - -import java.io.Serializable; -import java.util.Collections; -import java.util.List; - -/** - * 为标签添加或移除用户结果对象类. - * Created by Binary Wang on 2017-6-22. - * - * @author Binary Wang - */ -@Data -public class WxCpTagAddOrRemoveUsersResult implements Serializable { - private static final long serialVersionUID = 1420065684270213578L; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public static WxCpTagAddOrRemoveUsersResult fromJson(String json) { - return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpTagAddOrRemoveUsersResult.class); - } - - @SerializedName("errcode") - private Integer errCode; - - @SerializedName("errmsg") - private String errMsg; - - @SerializedName("invalidlist") - private String invalidUsers; - - @SerializedName("invalidparty") - private String[] invalidParty; - - public List getInvalidUserList() { - return this.content2List(this.invalidUsers); - } - - private List content2List(String content) { - if (StringUtils.isBlank(content)) { - return Collections.emptyList(); - } - - return Splitter.on("|").splitToList(content); - } - -} +package me.chanjar.weixin.cp.bean; + +import com.google.common.base.Splitter; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +/** + * 为标签添加或移除用户结果对象类. + * Created by Binary Wang on 2017-6-22. + * + * @author Binary Wang + */ +@Data +public class WxCpTagAddOrRemoveUsersResult implements Serializable { + private static final long serialVersionUID = 1420065684270213578L; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + public static WxCpTagAddOrRemoveUsersResult fromJson(String json) { + return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpTagAddOrRemoveUsersResult.class); + } + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("invalidlist") + private String invalidUsers; + + @SerializedName("invalidparty") + private String[] invalidParty; + + public List getInvalidUserList() { + return this.content2List(this.invalidUsers); + } + + private List content2List(String content) { + if (StringUtils.isBlank(content)) { + return Collections.emptyList(); + } + + return Splitter.on("|").splitToList(content); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java index b904b5e12b..0a3aaeb7a7 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java @@ -1,86 +1,86 @@ -package me.chanjar.weixin.cp.bean; - -import lombok.AllArgsConstructor; -import lombok.Data; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * 微信用户信息. - * - * @author Daniel Qian - */ -@Data -public class WxCpUser implements Serializable { - public enum Gender { - MALE("男", "1"), - FEMAIL("女", "2"); - - private String genderName; - private String code; - - Gender(String genderName, String code) { - this.genderName = genderName; - this.code = code; - } - - public String getGenderName() { - return this.genderName; - } - - public String getCode() { - return this.code; - } - - public static Gender fromCode(String code) { - if ("1".equals(code)) { - return Gender.MALE; - } - if ("2".equals(code)) { - return Gender.FEMAIL; - } - - return null; - } - } - - private static final long serialVersionUID = -5696099236344075582L; - private String userId; - private String name; - private Integer[] departIds; - private String position; - private String mobile; - private Gender gender; - private String email; - private String avatar; - private Integer status; - private Integer enable; - private Integer isLeader; - private final List extAttrs = new ArrayList<>(); - private Integer hideMobile; - private String englishName; - private String telephone; - - public void addExtAttr(String name, String value) { - this.extAttrs.add(new Attr(name, value)); - } - - public static WxCpUser fromJson(String json) { - return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); - } - - public String toJson() { - return WxCpGsonBuilder.INSTANCE.create().toJson(this); - } - - @Data - @AllArgsConstructor - public static class Attr { - private String name; - private String value; - } - -} +package me.chanjar.weixin.cp.bean; + +import lombok.AllArgsConstructor; +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 微信用户信息. + * + * @author Daniel Qian + */ +@Data +public class WxCpUser implements Serializable { + public enum Gender { + MALE("男", "1"), + FEMAIL("女", "2"); + + private String genderName; + private String code; + + Gender(String genderName, String code) { + this.genderName = genderName; + this.code = code; + } + + public String getGenderName() { + return this.genderName; + } + + public String getCode() { + return this.code; + } + + public static Gender fromCode(String code) { + if ("1".equals(code)) { + return Gender.MALE; + } + if ("2".equals(code)) { + return Gender.FEMAIL; + } + + return null; + } + } + + private static final long serialVersionUID = -5696099236344075582L; + private String userId; + private String name; + private Integer[] departIds; + private String position; + private String mobile; + private Gender gender; + private String email; + private String avatar; + private Integer status; + private Integer enable; + private Integer isLeader; + private final List extAttrs = new ArrayList<>(); + private Integer hideMobile; + private String englishName; + private String telephone; + + public void addExtAttr(String name, String value) { + this.extAttrs.add(new Attr(name, value)); + } + + public static WxCpUser fromJson(String json) { + return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); + } + + public String toJson() { + return WxCpGsonBuilder.INSTANCE.create().toJson(this); + } + + @Data + @AllArgsConstructor + public static class Attr { + private String name; + private String value; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java index a66b80af5c..785884a174 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java @@ -1,302 +1,302 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; -import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; -import me.chanjar.weixin.cp.util.xml.XStreamTransformer; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - *
- * 微信推送过来的消息,也是同步回复给用户的消息,xml格式
- * 相关字段的解释看微信开发者文档:
- * http://mp.weixin.qq.com/wiki/index.php?title=接收普通消息
- * http://mp.weixin.qq.com/wiki/index.php?title=接收事件推送
- * http://mp.weixin.qq.com/wiki/index.php?title=接收语音识别结果
- * 
- * - * @author Daniel Qian - */ -@XStreamAlias("xml") -@Data -public class WxCpXmlMessage implements Serializable { - private static final long serialVersionUID = -1042994982179476410L; - - /////////////////////// - // 以下都是微信推送过来的消息的xml的element所对应的属性 - /////////////////////// - - @XStreamAlias("AgentID") - private Integer agentId; - - @XStreamAlias("ToUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - private String toUserName; - - @XStreamAlias("FromUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - private String fromUserName; - - @XStreamAlias("CreateTime") - private Long createTime; - - @XStreamAlias("MsgType") - @XStreamConverter(value = XStreamCDataConverter.class) - private String msgType; - - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - @XStreamAlias("MsgId") - private Long msgId; - - @XStreamAlias("PicUrl") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picUrl; - - @XStreamAlias("MediaId") - @XStreamConverter(value = XStreamCDataConverter.class) - private String mediaId; - - @XStreamAlias("Format") - @XStreamConverter(value = XStreamCDataConverter.class) - private String format; - - @XStreamAlias("ThumbMediaId") - @XStreamConverter(value = XStreamCDataConverter.class) - private String thumbMediaId; - - @XStreamAlias("Location_X") - private Double locationX; - - @XStreamAlias("Location_Y") - private Double locationY; - - @XStreamAlias("Scale") - private Double scale; - - @XStreamAlias("Label") - @XStreamConverter(value = XStreamCDataConverter.class) - private String label; - - @XStreamAlias("Title") - @XStreamConverter(value = XStreamCDataConverter.class) - private String title; - - @XStreamAlias("Description") - @XStreamConverter(value = XStreamCDataConverter.class) - private String description; - - @XStreamAlias("Url") - @XStreamConverter(value = XStreamCDataConverter.class) - private String url; - - @XStreamAlias("Event") - @XStreamConverter(value = XStreamCDataConverter.class) - private String event; - - @XStreamAlias("EventKey") - @XStreamConverter(value = XStreamCDataConverter.class) - private String eventKey; - - @XStreamAlias("Ticket") - @XStreamConverter(value = XStreamCDataConverter.class) - private String ticket; - - @XStreamAlias("Latitude") - private Double latitude; - - @XStreamAlias("Longitude") - private Double longitude; - - @XStreamAlias("Precision") - private Double precision; - - @XStreamAlias("Recognition") - @XStreamConverter(value = XStreamCDataConverter.class) - private String recognition; - - /////////////////////////////////////// - // 群发消息返回的结果 - /////////////////////////////////////// - /** - * 群发的结果. - */ - @XStreamAlias("Status") - @XStreamConverter(value = XStreamCDataConverter.class) - private String status; - /** - * group_id下粉丝数;或者openid_list中的粉丝数. - */ - @XStreamAlias("TotalCount") - private Integer totalCount; - /** - * 过滤. - * (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount - */ - @XStreamAlias("FilterCount") - private Integer filterCount; - /** - * 发送成功的粉丝数. - */ - @XStreamAlias("SentCount") - private Integer sentCount; - /** - * 发送失败的粉丝数. - */ - @XStreamAlias("ErrorCount") - private Integer errorCount; - - @XStreamAlias("ScanCodeInfo") - private ScanCodeInfo scanCodeInfo = new ScanCodeInfo(); - - @XStreamAlias("SendPicsInfo") - private SendPicsInfo sendPicsInfo = new SendPicsInfo(); - - @XStreamAlias("SendLocationInfo") - private SendLocationInfo sendLocationInfo = new SendLocationInfo(); - - protected static WxCpXmlMessage fromXml(String xml) { - //修改微信变态的消息内容格式,方便解析 - xml = xml.replace("
", ""); - return XStreamTransformer.fromXml(WxCpXmlMessage.class, xml); - } - - protected static WxCpXmlMessage fromXml(InputStream is) { - return XStreamTransformer.fromXml(WxCpXmlMessage.class, is); - } - - /** - * 从加密字符串转换. - */ - 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); - } - } - - /** - *
-   * 当接受用户消息时,可能会获得以下值:
-   * {@link WxConsts.XmlMsgType#TEXT}
-   * {@link WxConsts.XmlMsgType#IMAGE}
-   * {@link WxConsts.XmlMsgType#VOICE}
-   * {@link WxConsts.XmlMsgType#VIDEO}
-   * {@link WxConsts.XmlMsgType#LOCATION}
-   * {@link WxConsts.XmlMsgType#LINK}
-   * {@link WxConsts.XmlMsgType#EVENT}
-   * 
- */ - public String getMsgType() { - return this.msgType; - } - - /** - *
-   * 当发送消息的时候使用:
-   * {@link WxConsts.XmlMsgType#TEXT}
-   * {@link WxConsts.XmlMsgType#IMAGE}
-   * {@link WxConsts.XmlMsgType#VOICE}
-   * {@link WxConsts.XmlMsgType#VIDEO}
-   * {@link WxConsts.XmlMsgType#NEWS}
-   * 
- */ - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - @Data - @XStreamAlias("ScanCodeInfo") - public static class ScanCodeInfo { - - /** - * 扫描类型,一般是qrcode. - */ - @XStreamAlias("ScanType") - @XStreamConverter(value = XStreamCDataConverter.class) - private String scanType; - - /** - * 扫描结果,即二维码对应的字符串信息. - */ - @XStreamAlias("ScanResult") - @XStreamConverter(value = XStreamCDataConverter.class) - private String scanResult; - } - - @Data - @XStreamAlias("SendPicsInfo") - public static class SendPicsInfo { - @XStreamAlias("PicList") - protected final List picList = new ArrayList<>(); - - @XStreamAlias("Count") - private Long count; - - @XStreamAlias("item") - @Data - public static class Item { - @XStreamAlias("PicMd5Sum") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picMd5Sum; - } - } - - @Data - @XStreamAlias("SendLocationInfo") - public static class SendLocationInfo { - - @XStreamAlias("Location_X") - @XStreamConverter(value = XStreamCDataConverter.class) - private String locationX; - - @XStreamAlias("Location_Y") - @XStreamConverter(value = XStreamCDataConverter.class) - private String locationY; - - @XStreamAlias("Scale") - @XStreamConverter(value = XStreamCDataConverter.class) - private String scale; - - @XStreamAlias("Label") - @XStreamConverter(value = XStreamCDataConverter.class) - private String label; - - @XStreamAlias("Poiname") - @XStreamConverter(value = XStreamCDataConverter.class) - private String poiName; - - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import me.chanjar.weixin.cp.config.WxCpConfigStorage; +import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; +import me.chanjar.weixin.cp.util.xml.XStreamTransformer; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + *
+ * 微信推送过来的消息,也是同步回复给用户的消息,xml格式
+ * 相关字段的解释看微信开发者文档:
+ * http://mp.weixin.qq.com/wiki/index.php?title=接收普通消息
+ * http://mp.weixin.qq.com/wiki/index.php?title=接收事件推送
+ * http://mp.weixin.qq.com/wiki/index.php?title=接收语音识别结果
+ * 
+ * + * @author Daniel Qian + */ +@XStreamAlias("xml") +@Data +public class WxCpXmlMessage implements Serializable { + private static final long serialVersionUID = -1042994982179476410L; + + /////////////////////// + // 以下都是微信推送过来的消息的xml的element所对应的属性 + /////////////////////// + + @XStreamAlias("AgentID") + private Integer agentId; + + @XStreamAlias("ToUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String toUserName; + + @XStreamAlias("FromUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String fromUserName; + + @XStreamAlias("CreateTime") + private Long createTime; + + @XStreamAlias("MsgType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String msgType; + + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + @XStreamAlias("MsgId") + private Long msgId; + + @XStreamAlias("PicUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picUrl; + + @XStreamAlias("MediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mediaId; + + @XStreamAlias("Format") + @XStreamConverter(value = XStreamCDataConverter.class) + private String format; + + @XStreamAlias("ThumbMediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String thumbMediaId; + + @XStreamAlias("Location_X") + private Double locationX; + + @XStreamAlias("Location_Y") + private Double locationY; + + @XStreamAlias("Scale") + private Double scale; + + @XStreamAlias("Label") + @XStreamConverter(value = XStreamCDataConverter.class) + private String label; + + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @XStreamAlias("Description") + @XStreamConverter(value = XStreamCDataConverter.class) + private String description; + + @XStreamAlias("Url") + @XStreamConverter(value = XStreamCDataConverter.class) + private String url; + + @XStreamAlias("Event") + @XStreamConverter(value = XStreamCDataConverter.class) + private String event; + + @XStreamAlias("EventKey") + @XStreamConverter(value = XStreamCDataConverter.class) + private String eventKey; + + @XStreamAlias("Ticket") + @XStreamConverter(value = XStreamCDataConverter.class) + private String ticket; + + @XStreamAlias("Latitude") + private Double latitude; + + @XStreamAlias("Longitude") + private Double longitude; + + @XStreamAlias("Precision") + private Double precision; + + @XStreamAlias("Recognition") + @XStreamConverter(value = XStreamCDataConverter.class) + private String recognition; + + /////////////////////////////////////// + // 群发消息返回的结果 + /////////////////////////////////////// + /** + * 群发的结果. + */ + @XStreamAlias("Status") + @XStreamConverter(value = XStreamCDataConverter.class) + private String status; + /** + * group_id下粉丝数;或者openid_list中的粉丝数. + */ + @XStreamAlias("TotalCount") + private Integer totalCount; + /** + * 过滤. + * (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount + */ + @XStreamAlias("FilterCount") + private Integer filterCount; + /** + * 发送成功的粉丝数. + */ + @XStreamAlias("SentCount") + private Integer sentCount; + /** + * 发送失败的粉丝数. + */ + @XStreamAlias("ErrorCount") + private Integer errorCount; + + @XStreamAlias("ScanCodeInfo") + private ScanCodeInfo scanCodeInfo = new ScanCodeInfo(); + + @XStreamAlias("SendPicsInfo") + private SendPicsInfo sendPicsInfo = new SendPicsInfo(); + + @XStreamAlias("SendLocationInfo") + private SendLocationInfo sendLocationInfo = new SendLocationInfo(); + + protected static WxCpXmlMessage fromXml(String xml) { + //修改微信变态的消息内容格式,方便解析 + xml = xml.replace("
", ""); + return XStreamTransformer.fromXml(WxCpXmlMessage.class, xml); + } + + protected static WxCpXmlMessage fromXml(InputStream is) { + return XStreamTransformer.fromXml(WxCpXmlMessage.class, is); + } + + /** + * 从加密字符串转换. + */ + 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); + } + } + + /** + *
+   * 当接受用户消息时,可能会获得以下值:
+   * {@link WxConsts.XmlMsgType#TEXT}
+   * {@link WxConsts.XmlMsgType#IMAGE}
+   * {@link WxConsts.XmlMsgType#VOICE}
+   * {@link WxConsts.XmlMsgType#VIDEO}
+   * {@link WxConsts.XmlMsgType#LOCATION}
+   * {@link WxConsts.XmlMsgType#LINK}
+   * {@link WxConsts.XmlMsgType#EVENT}
+   * 
+ */ + public String getMsgType() { + return this.msgType; + } + + /** + *
+   * 当发送消息的时候使用:
+   * {@link WxConsts.XmlMsgType#TEXT}
+   * {@link WxConsts.XmlMsgType#IMAGE}
+   * {@link WxConsts.XmlMsgType#VOICE}
+   * {@link WxConsts.XmlMsgType#VIDEO}
+   * {@link WxConsts.XmlMsgType#NEWS}
+   * 
+ */ + public void setMsgType(String msgType) { + this.msgType = msgType; + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + @Data + @XStreamAlias("ScanCodeInfo") + public static class ScanCodeInfo { + + /** + * 扫描类型,一般是qrcode. + */ + @XStreamAlias("ScanType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String scanType; + + /** + * 扫描结果,即二维码对应的字符串信息. + */ + @XStreamAlias("ScanResult") + @XStreamConverter(value = XStreamCDataConverter.class) + private String scanResult; + } + + @Data + @XStreamAlias("SendPicsInfo") + public static class SendPicsInfo { + @XStreamAlias("PicList") + protected final List picList = new ArrayList<>(); + + @XStreamAlias("Count") + private Long count; + + @XStreamAlias("item") + @Data + public static class Item { + @XStreamAlias("PicMd5Sum") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picMd5Sum; + } + } + + @Data + @XStreamAlias("SendLocationInfo") + public static class SendLocationInfo { + + @XStreamAlias("Location_X") + @XStreamConverter(value = XStreamCDataConverter.class) + private String locationX; + + @XStreamAlias("Location_Y") + @XStreamConverter(value = XStreamCDataConverter.class) + private String locationY; + + @XStreamAlias("Scale") + @XStreamConverter(value = XStreamCDataConverter.class) + private String scale; + + @XStreamAlias("Label") + @XStreamConverter(value = XStreamCDataConverter.class) + private String label; + + @XStreamAlias("Poiname") + @XStreamConverter(value = XStreamCDataConverter.class) + private String poiName; + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java index 5c8300b29d..dc77875e7e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = -1099446240667237313L; - - @XStreamAlias("Image") - @XStreamConverter(value = XStreamMediaIdConverter.class) - private String mediaId; - - public WxCpXmlOutImageMessage() { - this.msgType = WxConsts.XmlMsgType.IMAGE; - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = -1099446240667237313L; + + @XStreamAlias("Image") + @XStreamConverter(value = XStreamMediaIdConverter.class) + private String mediaId; + + public WxCpXmlOutImageMessage() { + this.msgType = WxConsts.XmlMsgType.IMAGE; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java index 3725989238..34c5499f06 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java @@ -1,81 +1,81 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; -import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import me.chanjar.weixin.cp.bean.outxmlbuilder.*; -import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; -import me.chanjar.weixin.cp.util.xml.XStreamTransformer; - -import java.io.Serializable; - -@XStreamAlias("xml") -@Data -public abstract class WxCpXmlOutMessage implements Serializable { - private static final long serialVersionUID = 1418629839964153110L; - - @XStreamAlias("ToUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - protected String toUserName; - - @XStreamAlias("FromUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - protected String fromUserName; - - @XStreamAlias("CreateTime") - protected Long createTime; - - @XStreamAlias("MsgType") - @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(); - } - - protected String toXml() { - return XStreamTransformer.toXml((Class) this.getClass(), this); - } - - /** - * 转换成加密的xml格式. - */ - public String toEncryptedXml(WxCpConfigStorage wxCpConfigStorage) { - String plainXml = toXml(); - WxCpCryptUtil pc = new WxCpCryptUtil(wxCpConfigStorage); - return pc.encrypt(plainXml); - } -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import me.chanjar.weixin.cp.config.WxCpConfigStorage; +import me.chanjar.weixin.cp.bean.outxmlbuilder.*; +import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; +import me.chanjar.weixin.cp.util.xml.XStreamTransformer; + +import java.io.Serializable; + +@XStreamAlias("xml") +@Data +public abstract class WxCpXmlOutMessage implements Serializable { + private static final long serialVersionUID = 1418629839964153110L; + + @XStreamAlias("ToUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + protected String toUserName; + + @XStreamAlias("FromUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + protected String fromUserName; + + @XStreamAlias("CreateTime") + protected Long createTime; + + @XStreamAlias("MsgType") + @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(); + } + + protected String toXml() { + return XStreamTransformer.toXml((Class) this.getClass(), this); + } + + /** + * 转换成加密的xml格式. + */ + public String toEncryptedXml(WxCpConfigStorage wxCpConfigStorage) { + String plainXml = toXml(); + WxCpCryptUtil pc = new WxCpCryptUtil(wxCpConfigStorage); + return pc.encrypt(plainXml); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java index e7e17b31d4..992397981f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java @@ -1,55 +1,55 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -import java.util.ArrayList; -import java.util.List; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = -5796178637883178826L; - - @XStreamAlias("Articles") - protected final List articles = new ArrayList<>(); - - @XStreamAlias("ArticleCount") - protected int articleCount; - - public WxCpXmlOutNewsMessage() { - this.msgType = WxConsts.XmlMsgType.NEWS; - } - - - public void addArticle(Item item) { - this.articles.add(item); - this.articleCount = this.articles.size(); - } - - @XStreamAlias("item") - @Data - public static class Item { - - @XStreamAlias("Title") - @XStreamConverter(value = XStreamCDataConverter.class) - private String title; - - @XStreamAlias("Description") - @XStreamConverter(value = XStreamCDataConverter.class) - private String description; - - @XStreamAlias("PicUrl") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picUrl; - - @XStreamAlias("Url") - @XStreamConverter(value = XStreamCDataConverter.class) - private String url; - - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +import java.util.ArrayList; +import java.util.List; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = -5796178637883178826L; + + @XStreamAlias("Articles") + protected final List articles = new ArrayList<>(); + + @XStreamAlias("ArticleCount") + protected int articleCount; + + public WxCpXmlOutNewsMessage() { + this.msgType = WxConsts.XmlMsgType.NEWS; + } + + + public void addArticle(Item item) { + this.articles.add(item); + this.articleCount = this.articles.size(); + } + + @XStreamAlias("item") + @Data + public static class Item { + + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @XStreamAlias("Description") + @XStreamConverter(value = XStreamCDataConverter.class) + private String description; + + @XStreamAlias("PicUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picUrl; + + @XStreamAlias("Url") + @XStreamConverter(value = XStreamCDataConverter.class) + private String url; + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java index 023d11a21a..1c354a12d4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = 2569239617185930232L; - - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - public WxCpXmlOutTextMessage() { - this.msgType = WxConsts.XmlMsgType.TEXT; - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = 2569239617185930232L; + + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + public WxCpXmlOutTextMessage() { + this.msgType = WxConsts.XmlMsgType.TEXT; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java index 839327a306..6d3bd0b4d1 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java @@ -1,63 +1,63 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = -8672761162722733622L; - - @XStreamAlias("Video") - protected final Video video = new Video(); - - public WxCpXmlOutVideoMessage() { - this.msgType = WxConsts.XmlMsgType.VIDEO; - } - - public String getMediaId() { - return this.video.getMediaId(); - } - - public void setMediaId(String mediaId) { - this.video.setMediaId(mediaId); - } - - public String getTitle() { - return this.video.getTitle(); - } - - public void setTitle(String title) { - this.video.setTitle(title); - } - - public String getDescription() { - return this.video.getDescription(); - } - - public void setDescription(String description) { - this.video.setDescription(description); - } - - @Data - @XStreamAlias("Video") - public static class Video { - - @XStreamAlias("MediaId") - @XStreamConverter(value = XStreamCDataConverter.class) - private String mediaId; - - @XStreamAlias("Title") - @XStreamConverter(value = XStreamCDataConverter.class) - private String title; - - @XStreamAlias("Description") - @XStreamConverter(value = XStreamCDataConverter.class) - private String description; - - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = -8672761162722733622L; + + @XStreamAlias("Video") + protected final Video video = new Video(); + + public WxCpXmlOutVideoMessage() { + this.msgType = WxConsts.XmlMsgType.VIDEO; + } + + public String getMediaId() { + return this.video.getMediaId(); + } + + public void setMediaId(String mediaId) { + this.video.setMediaId(mediaId); + } + + public String getTitle() { + return this.video.getTitle(); + } + + public void setTitle(String title) { + this.video.setTitle(title); + } + + public String getDescription() { + return this.video.getDescription(); + } + + public void setDescription(String description) { + this.video.setDescription(description); + } + + @Data + @XStreamAlias("Video") + public static class Video { + + @XStreamAlias("MediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mediaId; + + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @XStreamAlias("Description") + @XStreamConverter(value = XStreamCDataConverter.class) + private String description; + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java index 63cbde3781..c880bccfff 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.cp.bean; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; - -@XStreamAlias("xml") -@Data -public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { - private static final long serialVersionUID = -7947384031546099340L; - - @XStreamAlias("Voice") - @XStreamConverter(value = XStreamMediaIdConverter.class) - private String mediaId; - - public WxCpXmlOutVoiceMessage() { - this.msgType = WxConsts.XmlMsgType.VOICE; - } - -} +package me.chanjar.weixin.cp.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; + +@XStreamAlias("xml") +@Data +public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { + private static final long serialVersionUID = -7947384031546099340L; + + @XStreamAlias("Voice") + @XStreamConverter(value = XStreamMediaIdConverter.class) + private String mediaId; + + public WxCpXmlOutVoiceMessage() { + this.msgType = WxConsts.XmlMsgType.VOICE; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java index 38950dcc39..af622fefd8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java @@ -1,28 +1,28 @@ -package me.chanjar.weixin.cp.bean.article; - -import lombok.Builder; -import lombok.Data; - -import java.io.Serializable; - -/** - *
- *  Created by BinaryWang on 2017/3/27.
- * 
- * - * @author Binary Wang - */ -@Data -@Builder(builderMethodName = "newBuilder") -public class MpnewsArticle implements Serializable { - private static final long serialVersionUID = 6985871812170756481L; - - private String title; - private String thumbMediaId; - private String author; - private String contentSourceUrl; - private String content; - private String digest; - private String showCoverPic; - -} +package me.chanjar.weixin.cp.bean.article; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ *  Created by BinaryWang on 2017/3/27.
+ * 
+ * + * @author Binary Wang + */ +@Data +@Builder(builderMethodName = "newBuilder") +public class MpnewsArticle implements Serializable { + private static final long serialVersionUID = 6985871812170756481L; + + private String title; + private String thumbMediaId; + private String author; + private String contentSourceUrl; + private String content; + private String digest; + private String showCoverPic; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java index 5accf3b42d..7f10d363b4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java @@ -1,23 +1,23 @@ -package me.chanjar.weixin.cp.bean.article; - -import lombok.Data; - -import java.io.Serializable; - -/** - *
- *  Created by BinaryWang on 2017/3/27.
- * 
- * - * @author Binary Wang - */ -@Data -public class NewArticle implements Serializable { - private static final long serialVersionUID = 4087852055781140659L; - - private String title; - private String description; - private String url; - private String picUrl; - -} +package me.chanjar.weixin.cp.bean.article; + +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ *  Created by BinaryWang on 2017/3/27.
+ * 
+ * + * @author Binary Wang + */ +@Data +public class NewArticle implements Serializable { + private static final long serialVersionUID = 4087852055781140659L; + + private String title; + private String description; + private String url; + private String picUrl; + +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java index 1e307f0146..6d4e8ce893 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java @@ -1,68 +1,68 @@ -package me.chanjar.weixin.cp.api; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -@Test -public class WxCpBusyRetryTest { - - @DataProvider(name = "getService") - public Object[][] getService() { - WxCpService service = new WxCpServiceImpl() { - - @Override - public synchronized T executeInternal( - RequestExecutor executor, String uri, E data) - throws WxErrorException { - this.log.info("Executed"); - throw new WxErrorException(WxError.builder().errorCode(-1).build()); - } - }; - - service.setMaxRetryTimes(3); - service.setRetrySleepMillis(500); - return new Object[][]{ - new Object[]{service} - }; - } - - @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) - public void testRetry(WxCpService service) throws WxErrorException { - service.execute(null, null, null); - } - - @Test(dataProvider = "getService") - public void testRetryInThreadPool(final WxCpService service) throws InterruptedException, ExecutionException { - // 当线程池中的线程复用的时候,还是能保证相同的重试次数 - ExecutorService executorService = Executors.newFixedThreadPool(1); - Runnable runnable = new Runnable() { - @Override - public void run() { - try { - System.out.println("====================="); - System.out.println(Thread.currentThread().getName() + ": testRetry"); - service.execute(null, null, null); - } catch (WxErrorException e) { - throw new RuntimeException(e); - } catch (RuntimeException e) { - // OK - } - } - }; - Future submit1 = executorService.submit(runnable); - Future submit2 = executorService.submit(runnable); - - submit1.get(); - submit2.get(); - } - -} +package me.chanjar.weixin.cp.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +@Test +public class WxCpBusyRetryTest { + + @DataProvider(name = "getService") + public Object[][] getService() { + WxCpService service = new WxCpServiceImpl() { + + @Override + public synchronized T executeInternal( + RequestExecutor executor, String uri, E data) + throws WxErrorException { + this.log.info("Executed"); + throw new WxErrorException(WxError.builder().errorCode(-1).build()); + } + }; + + service.setMaxRetryTimes(3); + service.setRetrySleepMillis(500); + return new Object[][]{ + new Object[]{service} + }; + } + + @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) + public void testRetry(WxCpService service) throws WxErrorException { + service.execute(null, null, null); + } + + @Test(dataProvider = "getService") + public void testRetryInThreadPool(final WxCpService service) throws InterruptedException, ExecutionException { + // 当线程池中的线程复用的时候,还是能保证相同的重试次数 + ExecutorService executorService = Executors.newFixedThreadPool(1); + Runnable runnable = new Runnable() { + @Override + public void run() { + try { + System.out.println("====================="); + System.out.println(Thread.currentThread().getName() + ": testRetry"); + service.execute(null, null, null); + } catch (WxErrorException e) { + throw new RuntimeException(e); + } catch (RuntimeException e) { + // OK + } + } + }; + Future submit1 = executorService.submit(runnable); + Future submit2 = executorService.submit(runnable); + + submit1.get(); + submit2.get(); + } + +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java index 62f8cae583..e320d8cb2e 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java @@ -1,120 +1,120 @@ -package me.chanjar.weixin.cp.bean; - -import me.chanjar.weixin.common.api.WxConsts; -import org.testng.annotations.*; - -import static org.testng.Assert.*; - -@Test -public class WxCpXmlMessageTest { - - public void testFromXml() { - - String xml = "" - + "" - + " " - + "1348831860" - + "" - + "" - + "1234567890123456" - + "" - + "" - + "" - + "" - + "23.134521" - + "113.358803" - + "20" - + "" - + "" - + "" - + "<![CDATA[公众平台官网链接]]>" - + "" - + "" - + "" - + "23.137466" - + "113.352425" - + "119.385040" - + "" - + " " - + " " - + "" - + "" - + " 1\n" - + " " - + " " - + " " - + " " - + " " - + "" - + "" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + "" - + ""; - WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); - assertEquals(wxMessage.getToUserName(), "toUser"); - assertEquals(wxMessage.getFromUserName(), "fromUser"); - assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); - assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); - assertEquals(wxMessage.getContent(), "this is a test"); - assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); - assertEquals(wxMessage.getPicUrl(), "this is a url"); - assertEquals(wxMessage.getMediaId(), "media_id"); - assertEquals(wxMessage.getFormat(), "Format"); - assertEquals(wxMessage.getThumbMediaId(), "thumb_media_id"); - assertEquals(wxMessage.getLocationX(), 23.134521d); - assertEquals(wxMessage.getLocationY(), 113.358803d); - assertEquals(wxMessage.getScale(), 20d); - assertEquals(wxMessage.getLabel(), "位置信息"); - assertEquals(wxMessage.getDescription(), "公众平台官网链接"); - assertEquals(wxMessage.getUrl(), "url"); - assertEquals(wxMessage.getTitle(), "公众平台官网链接"); - assertEquals(wxMessage.getEvent(), "subscribe"); - assertEquals(wxMessage.getEventKey(), "qrscene_123123"); - assertEquals(wxMessage.getTicket(), "TICKET"); - assertEquals(wxMessage.getLatitude(), 23.137466); - assertEquals(wxMessage.getLongitude(), 113.352425); - assertEquals(wxMessage.getPrecision(), 119.385040); - assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); - assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); - assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1l)); - assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); - assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); - assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); - assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); - assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); - assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi"); - } - - public void testSendPicsInfo() { - String xml = "" + - "" + - "" + - "1502012364" + - "" + - "1000004" + - "" + - "" + - "" + - "" + - "" + - "2" + - "" + - ""; - WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml.replace("
","")); - assertEquals(wxMessage.getToUserName(), "wx45a0972125658be9"); - assertEquals(wxMessage.getFromUserName(), "xiaohe"); - assertEquals(wxMessage.getCreateTime(), new Long(1502012364L)); - assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); - assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004)); - assertEquals(wxMessage.getEvent(), "pic_weixin"); - assertEquals(wxMessage.getEventKey(), "faceSimilarity"); - assertNotNull(wxMessage.getSendPicsInfo()); - assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(2L)); - assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "aef52ae501537e552725c5d7f99c1741"); - assertEquals(wxMessage.getSendPicsInfo().getPicList().get(1).getPicMd5Sum(), "c4564632a4fab91378c39bea6aad6f9e"); - } -} +package me.chanjar.weixin.cp.bean; + +import me.chanjar.weixin.common.api.WxConsts; +import org.testng.annotations.*; + +import static org.testng.Assert.*; + +@Test +public class WxCpXmlMessageTest { + + public void testFromXml() { + + String xml = "" + + "" + + " " + + "1348831860" + + "" + + "" + + "1234567890123456" + + "" + + "" + + "" + + "" + + "23.134521" + + "113.358803" + + "20" + + "" + + "" + + "" + + "<![CDATA[公众平台官网链接]]>" + + "" + + "" + + "" + + "23.137466" + + "113.352425" + + "119.385040" + + "" + + " " + + " " + + "" + + "" + + " 1\n" + + " " + + " " + + " " + + " " + + " " + + "" + + "" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "" + + ""; + WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); + assertEquals(wxMessage.getToUserName(), "toUser"); + assertEquals(wxMessage.getFromUserName(), "fromUser"); + assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); + assertEquals(wxMessage.getContent(), "this is a test"); + assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); + assertEquals(wxMessage.getPicUrl(), "this is a url"); + assertEquals(wxMessage.getMediaId(), "media_id"); + assertEquals(wxMessage.getFormat(), "Format"); + assertEquals(wxMessage.getThumbMediaId(), "thumb_media_id"); + assertEquals(wxMessage.getLocationX(), 23.134521d); + assertEquals(wxMessage.getLocationY(), 113.358803d); + assertEquals(wxMessage.getScale(), 20d); + assertEquals(wxMessage.getLabel(), "位置信息"); + assertEquals(wxMessage.getDescription(), "公众平台官网链接"); + assertEquals(wxMessage.getUrl(), "url"); + assertEquals(wxMessage.getTitle(), "公众平台官网链接"); + assertEquals(wxMessage.getEvent(), "subscribe"); + assertEquals(wxMessage.getEventKey(), "qrscene_123123"); + assertEquals(wxMessage.getTicket(), "TICKET"); + assertEquals(wxMessage.getLatitude(), 23.137466); + assertEquals(wxMessage.getLongitude(), 113.352425); + assertEquals(wxMessage.getPrecision(), 119.385040); + assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); + assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); + assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1l)); + assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); + assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); + assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); + assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); + assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); + assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi"); + } + + public void testSendPicsInfo() { + String xml = "" + + "" + + "" + + "1502012364" + + "" + + "1000004" + + "" + + "" + + "" + + "" + + "" + + "2" + + "" + + ""; + WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml.replace("","")); + assertEquals(wxMessage.getToUserName(), "wx45a0972125658be9"); + assertEquals(wxMessage.getFromUserName(), "xiaohe"); + assertEquals(wxMessage.getCreateTime(), new Long(1502012364L)); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); + assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004)); + assertEquals(wxMessage.getEvent(), "pic_weixin"); + assertEquals(wxMessage.getEventKey(), "faceSimilarity"); + assertNotNull(wxMessage.getSendPicsInfo()); + assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(2L)); + assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "aef52ae501537e552725c5d7f99c1741"); + assertEquals(wxMessage.getSendPicsInfo().getPicList().get(1).getPicMd5Sum(), "c4564632a4fab91378c39bea6aad6f9e"); + } +} diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index b2ac1061c0..b7e2f1cb9c 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -1,84 +1,84 @@ - - - 4.0.0 - - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - - weixin-java-miniapp - WeiXin Java Tools - MiniApp - 微信小程序Java SDK - - - - com.github.binarywang - weixin-java-common - ${project.version} - - - - org.jodd - jodd-http - provided - - - com.squareup.okhttp3 - okhttp - provided - - - - org.testng - testng - test - - - ch.qos.logback - logback-classic - test - - - com.google.inject - guice - test - - - org.eclipse.jetty - jetty-server - test - - - org.eclipse.jetty - jetty-servlet - test - - - joda-time - joda-time - test - - - redis.clients - jedis - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - src/test/resources/testng.xml - - - - - - - + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + + weixin-java-miniapp + WeiXin Java Tools - MiniApp + 微信小程序Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + + org.testng + testng + test + + + ch.qos.logback + logback-classic + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + joda-time + joda-time + test + + + redis.clients + jedis + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java index 95d95a0c42..b198fc7a07 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java @@ -1,55 +1,55 @@ -package cn.binarywang.wx.miniapp.api.impl; - -import cn.binarywang.wx.miniapp.api.WxMaMediaService; -import cn.binarywang.wx.miniapp.api.WxMaService; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.fs.FileUtils; -import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; -import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; -import me.chanjar.weixin.common.util.http.RequestExecutor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.util.UUID; - -/** - * @author Binary Wang - */ -public class WxMaMediaServiceImpl implements WxMaMediaService { - private WxMaService wxMaService; - - public WxMaMediaServiceImpl(WxMaService wxMaService) { - this.wxMaService = wxMaService; - } - - @Override - public WxMediaUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { - try { - return this.uploadMedia(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); - } catch (IOException e) { - throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); - } - } - - @Override - public WxMediaUploadResult uploadMedia(String mediaType, File file) throws WxErrorException { - String url = String.format(MEDIA_UPLOAD_URL, mediaType); - return this.wxMaService.execute(MediaUploadRequestExecutor.create(this.wxMaService.getRequestHttp()), url, file); - } - - @Override - public File getMedia(String mediaId) throws WxErrorException { - try { - RequestExecutor executor = BaseMediaDownloadRequestExecutor - .create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxma").toFile()); - return this.wxMaService.execute(executor, MEDIA_GET_URL, "media_id=" + mediaId); - } catch (IOException e) { - throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); - } - } - -} +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaMediaService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; +import me.chanjar.weixin.common.util.http.RequestExecutor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.UUID; + +/** + * @author Binary Wang + */ +public class WxMaMediaServiceImpl implements WxMaMediaService { + private WxMaService wxMaService; + + public WxMaMediaServiceImpl(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + @Override + public WxMediaUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { + try { + return this.uploadMedia(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); + } catch (IOException e) { + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); + } + } + + @Override + public WxMediaUploadResult uploadMedia(String mediaType, File file) throws WxErrorException { + String url = String.format(MEDIA_UPLOAD_URL, mediaType); + return this.wxMaService.execute(MediaUploadRequestExecutor.create(this.wxMaService.getRequestHttp()), url, file); + } + + @Override + public File getMedia(String mediaId) throws WxErrorException { + try { + RequestExecutor executor = BaseMediaDownloadRequestExecutor + .create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxma").toFile()); + return this.wxMaService.execute(executor, MEDIA_GET_URL, "media_id=" + mediaId); + } catch (IOException e) { + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); + } + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java index 922bbb4b2d..2afb4c073e 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java @@ -1,18 +1,18 @@ -package cn.binarywang.wx.miniapp.bean; - -import lombok.AllArgsConstructor; -import lombok.Data; - -/** - *
- * lineColor 包装类
- * 用于描述二维码(小程序码)颜色(RGB参数值),
- * 详情请查看文档 https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html
- * 
- * @author Element - */ -@Data -@AllArgsConstructor -public class WxMaCodeLineColor { - private String r = "0", g = "0", b = "0"; -} +package cn.binarywang.wx.miniapp.bean; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + *
+ * lineColor 包装类
+ * 用于描述二维码(小程序码)颜色(RGB参数值),
+ * 详情请查看文档 https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html
+ * 
+ * @author Element + */ +@Data +@AllArgsConstructor +public class WxMaCodeLineColor { + private String r = "0", g = "0", b = "0"; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java index 50f6f4bba4..7d3e2d8de6 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java @@ -1,36 +1,36 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - * {"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","expires_in":2592000,"openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"} - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxMaJscode2SessionResult implements Serializable { - private static final long serialVersionUID = -1060216618475607933L; - - @SerializedName("session_key") - private String sessionKey; - - @SerializedName("expires_in") - private Integer expiresin; - - @SerializedName("openid") - private String openid; - - @SerializedName("unionid") - private String unionid; - - public static WxMaJscode2SessionResult fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaJscode2SessionResult.class); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * {"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","expires_in":2592000,"openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"} + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaJscode2SessionResult implements Serializable { + private static final long serialVersionUID = -1060216618475607933L; + + @SerializedName("session_key") + private String sessionKey; + + @SerializedName("expires_in") + private Integer expiresin; + + @SerializedName("openid") + private String openid; + + @SerializedName("unionid") + private String unionid; + + public static WxMaJscode2SessionResult fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaJscode2SessionResult.class); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java index 3c7e5f1f6d..ec1728db60 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java @@ -1,45 +1,45 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.builder.ImageBuilder; -import cn.binarywang.wx.miniapp.builder.TextBuilder; -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import lombok.Data; - -import java.io.Serializable; - -/** - * 客服消息 - * - * @author Binary Wang - */ -@Data -public class WxMaKefuMessage implements Serializable { - private static final long serialVersionUID = -9196732086954365246L; - - private String toUser; - private String msgType; - private String content; - private String mediaId; - private String thumbMediaId; - private String title; - private String description; - - /** - * 获得文本消息builder - */ - public static TextBuilder newTextBuilder() { - return new TextBuilder(); - } - - /** - * 获得图片消息builder - */ - public static ImageBuilder newImageBuilder() { - return new ImageBuilder(); - } - - public String toJson() { - return WxMaGsonBuilder.create().toJson(this); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.builder.ImageBuilder; +import cn.binarywang.wx.miniapp.builder.TextBuilder; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Data; + +import java.io.Serializable; + +/** + * 客服消息 + * + * @author Binary Wang + */ +@Data +public class WxMaKefuMessage implements Serializable { + private static final long serialVersionUID = -9196732086954365246L; + + private String toUser; + private String msgType; + private String content; + private String mediaId; + private String thumbMediaId; + private String title; + private String description; + + /** + * 获得文本消息builder + */ + public static TextBuilder newTextBuilder() { + return new TextBuilder(); + } + + /** + * 获得图片消息builder + */ + public static ImageBuilder newImageBuilder() { + return new ImageBuilder(); + } + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java index 2bd47d2e57..cb1fed6923 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java @@ -1,151 +1,151 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.config.WxMaConfig; -import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import cn.binarywang.wx.miniapp.util.xml.XStreamTransformer; -import com.google.gson.annotations.SerializedName; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; - -/** - * @author Binary Wang - */ -@XStreamAlias("xml") -@Data -public class WxMaMessage implements Serializable { - private static final long serialVersionUID = -3586245291677274914L; - - @SerializedName("Encrypt") - @XStreamAlias("Encrypt") - @XStreamConverter(value = XStreamCDataConverter.class) - private String encrypt; - - @SerializedName("ToUserName") - @XStreamAlias("ToUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - private String toUser; - - @SerializedName("FromUserName") - @XStreamAlias("FromUserName") - @XStreamConverter(value = XStreamCDataConverter.class) - private String fromUser; - - @SerializedName("CreateTime") - @XStreamAlias("CreateTime") - @XStreamConverter(value = XStreamCDataConverter.class) - private Integer createTime; - - @SerializedName("MsgDataFormat") - @XStreamAlias("MsgDataFormat") - @XStreamConverter(value = XStreamCDataConverter.class) - private String msgType; - - // 文本消息 - @SerializedName("Content") - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - @SerializedName("MsgId") - @XStreamAlias("MsgId") - @XStreamConverter(value = XStreamCDataConverter.class) - private Long msgId; - - // 图片消息 - @SerializedName("PicUrl") - @XStreamAlias("PicUrl") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picUrl; - - @SerializedName("MediaId") - @XStreamAlias("MediaId") - @XStreamConverter(value = XStreamCDataConverter.class) - private String mediaId; - - // 事件消息 - @SerializedName("Event") - @XStreamAlias("Event") - @XStreamConverter(value = XStreamCDataConverter.class) - private String event; - - @SerializedName("SessionFrom") - @XStreamAlias("SessionFrom") - @XStreamConverter(value = XStreamCDataConverter.class) - private String sessionFrom; - - public static WxMaMessage fromXml(String xml) { - return XStreamTransformer.fromXml(WxMaMessage.class, xml); - } - - public static WxMaMessage fromXml(InputStream is) { - return XStreamTransformer.fromXml(WxMaMessage.class, is); - } - - /** - * 从加密字符串转换 - * - * @param encryptedXml 密文 - * @param wxMaConfig 配置存储器对象 - * @param timestamp 时间戳 - * @param nonce 随机串 - * @param msgSignature 签名串 - */ - public static WxMaMessage fromEncryptedXml(String encryptedXml, - WxMaConfig wxMaConfig, String timestamp, String nonce, - String msgSignature) { - String plainText = new WxMaCryptUtils(wxMaConfig).decrypt(msgSignature, timestamp, nonce, encryptedXml); - return fromXml(plainText); - } - - public static WxMaMessage fromEncryptedXml(InputStream is, WxMaConfig wxMaConfig, String timestamp, - String nonce, String msgSignature) { - try { - return fromEncryptedXml(IOUtils.toString(is, StandardCharsets.UTF_8), wxMaConfig, - timestamp, nonce, msgSignature); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static WxMaMessage fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaMessage.class); - } - - public static WxMaMessage fromEncryptedJson(String encryptedJson, WxMaConfig config) { - try { - WxMaMessage encryptedMessage = fromJson(encryptedJson); - String plainText = new WxMaCryptUtils(config).decrypt(encryptedMessage.getEncrypt()); - return fromJson(plainText); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static WxMaMessage fromEncryptedJson(InputStream inputStream, WxMaConfig config) { - try { - return fromEncryptedJson(IOUtils.toString(inputStream, StandardCharsets.UTF_8), config); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String toJson() { - return WxMaGsonBuilder.create().toJson(this); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import cn.binarywang.wx.miniapp.util.xml.XStreamTransformer; +import com.google.gson.annotations.SerializedName; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; + +/** + * @author Binary Wang + */ +@XStreamAlias("xml") +@Data +public class WxMaMessage implements Serializable { + private static final long serialVersionUID = -3586245291677274914L; + + @SerializedName("Encrypt") + @XStreamAlias("Encrypt") + @XStreamConverter(value = XStreamCDataConverter.class) + private String encrypt; + + @SerializedName("ToUserName") + @XStreamAlias("ToUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String toUser; + + @SerializedName("FromUserName") + @XStreamAlias("FromUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String fromUser; + + @SerializedName("CreateTime") + @XStreamAlias("CreateTime") + @XStreamConverter(value = XStreamCDataConverter.class) + private Integer createTime; + + @SerializedName("MsgDataFormat") + @XStreamAlias("MsgDataFormat") + @XStreamConverter(value = XStreamCDataConverter.class) + private String msgType; + + // 文本消息 + @SerializedName("Content") + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + @SerializedName("MsgId") + @XStreamAlias("MsgId") + @XStreamConverter(value = XStreamCDataConverter.class) + private Long msgId; + + // 图片消息 + @SerializedName("PicUrl") + @XStreamAlias("PicUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picUrl; + + @SerializedName("MediaId") + @XStreamAlias("MediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mediaId; + + // 事件消息 + @SerializedName("Event") + @XStreamAlias("Event") + @XStreamConverter(value = XStreamCDataConverter.class) + private String event; + + @SerializedName("SessionFrom") + @XStreamAlias("SessionFrom") + @XStreamConverter(value = XStreamCDataConverter.class) + private String sessionFrom; + + public static WxMaMessage fromXml(String xml) { + return XStreamTransformer.fromXml(WxMaMessage.class, xml); + } + + public static WxMaMessage fromXml(InputStream is) { + return XStreamTransformer.fromXml(WxMaMessage.class, is); + } + + /** + * 从加密字符串转换 + * + * @param encryptedXml 密文 + * @param wxMaConfig 配置存储器对象 + * @param timestamp 时间戳 + * @param nonce 随机串 + * @param msgSignature 签名串 + */ + public static WxMaMessage fromEncryptedXml(String encryptedXml, + WxMaConfig wxMaConfig, String timestamp, String nonce, + String msgSignature) { + String plainText = new WxMaCryptUtils(wxMaConfig).decrypt(msgSignature, timestamp, nonce, encryptedXml); + return fromXml(plainText); + } + + public static WxMaMessage fromEncryptedXml(InputStream is, WxMaConfig wxMaConfig, String timestamp, + String nonce, String msgSignature) { + try { + return fromEncryptedXml(IOUtils.toString(is, StandardCharsets.UTF_8), wxMaConfig, + timestamp, nonce, msgSignature); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static WxMaMessage fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaMessage.class); + } + + public static WxMaMessage fromEncryptedJson(String encryptedJson, WxMaConfig config) { + try { + WxMaMessage encryptedMessage = fromJson(encryptedJson); + String plainText = new WxMaCryptUtils(config).decrypt(encryptedMessage.getEncrypt()); + return fromJson(plainText); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static WxMaMessage fromEncryptedJson(InputStream inputStream, WxMaConfig config) { + try { + return fromEncryptedJson(IOUtils.toString(inputStream, StandardCharsets.UTF_8), config); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java index 87aa3f8bdf..5c17cd1e58 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java @@ -1,32 +1,32 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxMaQrcode extends AbstractWxMaQrcodeWrapper implements Serializable { - private static final long serialVersionUID = 5777119669111011584L; - private String path; - private int width = 430; - - public WxMaQrcode(String path, int width) { - this.path = path; - this.width = width; - } - - public static WxMaQrcode fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaQrcode.class); - } - - @Override - public String toString() { - return WxMaGsonBuilder.create().toJson(this); - } -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaQrcode extends AbstractWxMaQrcodeWrapper implements Serializable { + private static final long serialVersionUID = 5777119669111011584L; + private String path; + private int width = 430; + + public WxMaQrcode(String path, int width) { + this.path = path; + this.width = width; + } + + public static WxMaQrcode fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaQrcode.class); + } + + @Override + public String toString() { + return WxMaGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java index 3e9760395e..32268b4c4b 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java @@ -1,108 +1,108 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import lombok.Builder; -import lombok.Data; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * 参考 https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#接口说明 模板消息部分 - * - * @author Binary Wang - */ -@Data -@Builder -public class WxMaTemplateMessage implements Serializable { - private static final long serialVersionUID = 5063374783759519418L; - - /** - *
-   * 参数:touser
-   * 是否必填: 是
-   * 描述: 接收者(用户)的 openid
-   * 
- */ - private String toUser; - - /** - *
-   * 参数:template_id
-   * 是否必填: 是
-   * 描述: 所需下发的模板消息的id
-   * 
- */ - private String templateId; - - /** - *
-   * 参数:page
-   * 是否必填: 否
-   * 描述: 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
-   * 
- */ - private String page; - - /** - *
-   * 参数:form_id
-   * 是否必填: 是
-   * 描述: 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id
-   * 
- */ - private String formId; - - /** - *
-   * 参数:data
-   * 是否必填: 是
-   * 描述: 模板内容,不填则下发空模板
-   * 
- */ - @Builder.Default - private final List data = new ArrayList<>(); - - /** - *
-   * 参数:color
-   * 是否必填: 否
-   * 描述: 模板内容字体的颜色,不填默认黑色
-   * 
- */ - private String color; - - /** - *
-   * 参数:emphasis_keyword
-   * 是否必填: 否
-   * 描述: 模板需要放大的关键词,不填则默认无放大
-   * 
- */ - private String emphasisKeyword; - - public String toJson() { - return WxMaGsonBuilder.create().toJson(this); - } - - @lombok.Data - public static class Data { - private String name; - private String value; - private String color; - - public Data(String name, String value) { - this.name = name; - this.value = value; - } - - public Data(String name, String value, String color) { - this.name = name; - this.value = value; - this.color = color; - } - - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 参考 https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#接口说明 模板消息部分 + * + * @author Binary Wang + */ +@Data +@Builder +public class WxMaTemplateMessage implements Serializable { + private static final long serialVersionUID = 5063374783759519418L; + + /** + *
+   * 参数:touser
+   * 是否必填: 是
+   * 描述: 接收者(用户)的 openid
+   * 
+ */ + private String toUser; + + /** + *
+   * 参数:template_id
+   * 是否必填: 是
+   * 描述: 所需下发的模板消息的id
+   * 
+ */ + private String templateId; + + /** + *
+   * 参数:page
+   * 是否必填: 否
+   * 描述: 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
+   * 
+ */ + private String page; + + /** + *
+   * 参数:form_id
+   * 是否必填: 是
+   * 描述: 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id
+   * 
+ */ + private String formId; + + /** + *
+   * 参数:data
+   * 是否必填: 是
+   * 描述: 模板内容,不填则下发空模板
+   * 
+ */ + @Builder.Default + private final List data = new ArrayList<>(); + + /** + *
+   * 参数:color
+   * 是否必填: 否
+   * 描述: 模板内容字体的颜色,不填默认黑色
+   * 
+ */ + private String color; + + /** + *
+   * 参数:emphasis_keyword
+   * 是否必填: 否
+   * 描述: 模板需要放大的关键词,不填则默认无放大
+   * 
+ */ + private String emphasisKeyword; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + + @lombok.Data + public static class Data { + private String name; + private String value; + private String color; + + public Data(String name, String value) { + this.name = name; + this.value = value; + } + + public Data(String name, String value, String color) { + this.name = name; + this.value = value; + this.color = color; + } + + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java index a16fc30a1a..8b0ed8fe6a 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java @@ -1,35 +1,35 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import lombok.Data; - -import java.io.Serializable; - -/** - * @author Binary Wang - */ -@Data -public class WxMaUserInfo implements Serializable { - private static final long serialVersionUID = 6719822331555402137L; - - private String openId; - private String nickName; - private String gender; - private String language; - private String city; - private String province; - private String country; - private String avatarUrl; - private String unionId; - private Watermark watermark; - - public static WxMaUserInfo fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaUserInfo.class); - } - - @Data - public static class Watermark { - private String timestamp; - private String appid; - } -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author Binary Wang + */ +@Data +public class WxMaUserInfo implements Serializable { + private static final long serialVersionUID = 6719822331555402137L; + + private String openId; + private String nickName; + private String gender; + private String language; + private String city; + private String province; + private String country; + private String avatarUrl; + private String unionId; + private Watermark watermark; + + public static WxMaUserInfo fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaUserInfo.class); + } + + @Data + public static class Watermark { + private String timestamp; + private String appid; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java index 7d9c60e676..8e629096c6 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java @@ -1,33 +1,33 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - * - * @author Element - * @date 2017/7/27 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxMaWxcode extends AbstractWxMaQrcodeWrapper implements Serializable { - private static final long serialVersionUID = 1287399621649210322L; - - private String path; - private int width = 430; - - @SerializedName("auto_color") - private boolean autoColor = true; - - @SerializedName("line_color") - private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); - - public static WxMaWxcode fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaWxcode.class); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * + * @author Element + * @date 2017/7/27 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaWxcode extends AbstractWxMaQrcodeWrapper implements Serializable { + private static final long serialVersionUID = 1287399621649210322L; + + private String path; + private int width = 430; + + @SerializedName("auto_color") + private boolean autoColor = true; + + @SerializedName("line_color") + private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); + + public static WxMaWxcode fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaWxcode.class); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java index 928e9b7d91..5f76273b54 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java @@ -1,34 +1,34 @@ -package cn.binarywang.wx.miniapp.bean; - -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - * - * @author Element - * @date 2017/7/27 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxMaWxcodeLimit extends AbstractWxMaQrcodeWrapper implements Serializable { - private static final long serialVersionUID = 4782193774524960401L; - private String scene; - private String page; - - private int width = 430; - - @SerializedName("auto_color") - private boolean autoColor = true; - - @SerializedName("line_color") - private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); - - public static WxMaWxcodeLimit fromJson(String json) { - return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * + * @author Element + * @date 2017/7/27 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaWxcodeLimit extends AbstractWxMaQrcodeWrapper implements Serializable { + private static final long serialVersionUID = 4782193774524960401L; + private String scene; + private String page; + + private int width = 430; + + @SerializedName("auto_color") + private boolean autoColor = true; + + @SerializedName("line_color") + private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); + + public static WxMaWxcodeLimit fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class); + } + +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java index 39475453a0..d6aa31a71f 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java @@ -1,73 +1,73 @@ -package cn.binarywang.wx.miniapp.api.impl; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; -import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; -import cn.binarywang.wx.miniapp.test.ApiTestModule; -import cn.binarywang.wx.miniapp.test.TestConfig; -import com.google.common.collect.Lists; -import com.google.inject.Inject; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.exception.WxErrorException; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; - -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * 测试客服相关接口 - * - * @author Binary Wang - */ -@Test -@Guice(modules = ApiTestModule.class) -public class WxMaMsgServiceImplTest { - - @Inject - protected WxMaService wxService; - - public void testSendKefuMpNewsMessage() throws WxErrorException { - TestConfig configStorage = (TestConfig) this.wxService - .getWxMaConfig(); - WxMaKefuMessage message = new WxMaKefuMessage(); - message.setMsgType(WxConsts.KefuMsgType.MPNEWS); - message.setToUser(configStorage.getOpenid()); - - this.wxService.getMsgService().sendKefuMsg(message); - } - - public void testSendKefuMessage() throws WxErrorException { - TestConfig config = (TestConfig) this.wxService - .getWxMaConfig(); - WxMaKefuMessage message = new WxMaKefuMessage(); - message.setMsgType(WxConsts.KefuMsgType.TEXT); - message.setToUser(config.getOpenid()); - message.setContent( - "欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); - - this.wxService.getMsgService().sendKefuMsg(message); - } - - @Test(invocationCount = 5, threadPoolSize = 3) - public void testSendTemplateMsg() throws WxErrorException { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); - - WxMaTemplateMessage templateMessage = WxMaTemplateMessage.builder() - .toUser(config.getOpenid()) - .formId("FORMID") - .page("index") - .data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), - new WxMaTemplateMessage.Data("keyword2", dateFormat.format(new Date()), "#173177"), - new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), - new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) - .templateId(config.getTemplateId()) - .emphasisKeyword("keyword1.DATA") - .build(); - - this.wxService.getMsgService().sendTemplateMsg(templateMessage); - } - -} +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; +import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import cn.binarywang.wx.miniapp.test.TestConfig; +import com.google.common.collect.Lists; +import com.google.inject.Inject; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.exception.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 测试客服相关接口 + * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaMsgServiceImplTest { + + @Inject + protected WxMaService wxService; + + public void testSendKefuMpNewsMessage() throws WxErrorException { + TestConfig configStorage = (TestConfig) this.wxService + .getWxMaConfig(); + WxMaKefuMessage message = new WxMaKefuMessage(); + message.setMsgType(WxConsts.KefuMsgType.MPNEWS); + message.setToUser(configStorage.getOpenid()); + + this.wxService.getMsgService().sendKefuMsg(message); + } + + public void testSendKefuMessage() throws WxErrorException { + TestConfig config = (TestConfig) this.wxService + .getWxMaConfig(); + WxMaKefuMessage message = new WxMaKefuMessage(); + message.setMsgType(WxConsts.KefuMsgType.TEXT); + message.setToUser(config.getOpenid()); + message.setContent( + "欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); + + this.wxService.getMsgService().sendKefuMsg(message); + } + + @Test(invocationCount = 5, threadPoolSize = 3) + public void testSendTemplateMsg() throws WxErrorException { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); + + WxMaTemplateMessage templateMessage = WxMaTemplateMessage.builder() + .toUser(config.getOpenid()) + .formId("FORMID") + .page("index") + .data(Lists.newArrayList( + new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), + new WxMaTemplateMessage.Data("keyword2", dateFormat.format(new Date()), "#173177"), + new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), + new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) + .templateId(config.getTemplateId()) + .emphasisKeyword("keyword1.DATA") + .build(); + + this.wxService.getMsgService().sendTemplateMsg(templateMessage); + } + +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java index e1db78f8de..d4464312eb 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java @@ -1,31 +1,31 @@ -package cn.binarywang.wx.miniapp.bean; - -import com.google.common.collect.Lists; -import org.testng.annotations.Test; - -import static org.testng.AssertJUnit.assertEquals; - -/** - * @author Binary Wang - */ -public class WxMaTemplateMessageTest { - @Test - public void testToJson() throws Exception { - WxMaTemplateMessage tm = WxMaTemplateMessage.builder() - .toUser("OPENID") - //.color("aaaaa") - .formId("FORMID") - .page("index") - .data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), - new WxMaTemplateMessage.Data("keyword2", "2015年01月05日12:30", "#173177"), - new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), - new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) - .templateId("TEMPLATE_ID") - .emphasisKeyword("keyword1.DATA") - .build(); - - assertEquals(tm.toJson(), "{\"touser\":\"OPENID\",\"template_id\":\"TEMPLATE_ID\",\"page\":\"index\",\"form_id\":\"FORMID\",\"emphasis_keyword\":\"keyword1.DATA\",\"data\":{\"keyword1\":{\"value\":\"339208499\",\"color\":\"#173177\"},\"keyword2\":{\"value\":\"2015年01月05日12:30\",\"color\":\"#173177\"},\"keyword3\":{\"value\":\"粤海喜来登酒店\",\"color\":\"#173177\"},\"keyword4\":{\"value\":\"广州市天河区天河路208号\",\"color\":\"#173177\"}}}"); - } - -} +package cn.binarywang.wx.miniapp.bean; + +import com.google.common.collect.Lists; +import org.testng.annotations.Test; + +import static org.testng.AssertJUnit.assertEquals; + +/** + * @author Binary Wang + */ +public class WxMaTemplateMessageTest { + @Test + public void testToJson() throws Exception { + WxMaTemplateMessage tm = WxMaTemplateMessage.builder() + .toUser("OPENID") + //.color("aaaaa") + .formId("FORMID") + .page("index") + .data(Lists.newArrayList( + new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), + new WxMaTemplateMessage.Data("keyword2", "2015年01月05日12:30", "#173177"), + new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), + new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) + .templateId("TEMPLATE_ID") + .emphasisKeyword("keyword1.DATA") + .build(); + + assertEquals(tm.toJson(), "{\"touser\":\"OPENID\",\"template_id\":\"TEMPLATE_ID\",\"page\":\"index\",\"form_id\":\"FORMID\",\"emphasis_keyword\":\"keyword1.DATA\",\"data\":{\"keyword1\":{\"value\":\"339208499\",\"color\":\"#173177\"},\"keyword2\":{\"value\":\"2015年01月05日12:30\",\"color\":\"#173177\"},\"keyword3\":{\"value\":\"粤海喜来登酒店\",\"color\":\"#173177\"},\"keyword4\":{\"value\":\"广州市天河区天河路208号\",\"color\":\"#173177\"}}}"); + } + +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java index bc0f6bb000..8d14b261ff 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java @@ -1,148 +1,148 @@ -package cn.binarywang.wx.miniapp.demo; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; -import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; -import cn.binarywang.wx.miniapp.bean.WxMaMessage; -import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; -import cn.binarywang.wx.miniapp.config.WxMaConfig; -import cn.binarywang.wx.miniapp.constant.WxMaConstants; -import cn.binarywang.wx.miniapp.message.WxMaMessageHandler; -import cn.binarywang.wx.miniapp.message.WxMaMessageRouter; -import cn.binarywang.wx.miniapp.test.TestConfig; -import com.google.common.collect.Lists; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.session.WxSessionManager; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletHandler; -import org.eclipse.jetty.servlet.ServletHolder; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.concurrent.locks.ReentrantLock; - -/** - * @author Binary Wang - */ -public class WxMaDemoServer { - - private static final WxMaMessageHandler logHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) throws WxErrorException { - System.out.println("收到消息:" + wxMessage.toString()); - service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson()) - .toUser(wxMessage.getFromUser()).build()); - } - }; - - private static final WxMaMessageHandler textHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) - throws WxErrorException { - service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息") - .toUser(wxMessage.getFromUser()).build()); - } - - }; - - private static final WxMaMessageHandler picHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) throws WxErrorException { - try { - WxMediaUploadResult uploadResult = service.getMediaService() - .uploadMedia(WxMaConstants.MediaType.IMAGE, "png", - ClassLoader.getSystemResourceAsStream("tmp.png")); - service.getMsgService().sendKefuMsg( - WxMaKefuMessage - .newImageBuilder() - .mediaId(uploadResult.getMediaId()) - .toUser(wxMessage.getFromUser()) - .build()); - } catch (WxErrorException e) { - e.printStackTrace(); - } - } - }; - - private static final WxMaMessageHandler qrcodeHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) throws WxErrorException { - try { - final File file = service.getQrcodeService().createQrcode("123", 430); - WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia(WxMaConstants.MediaType.IMAGE, file); - service.getMsgService().sendKefuMsg( - WxMaKefuMessage - .newImageBuilder() - .mediaId(uploadResult.getMediaId()) - .toUser(wxMessage.getFromUser()) - .build()); - } catch (WxErrorException e) { - e.printStackTrace(); - } - } - }; - - private static final WxMaMessageHandler templateMsgHandler = new WxMaMessageHandler() { - @Override - public void handle(WxMaMessage wxMessage, Map context, - WxMaService service, WxSessionManager sessionManager) - throws WxErrorException { - service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder() - .templateId(templateId).data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"))) - .toUser(wxMessage.getFromUser()) - .formId("自己替换可用的formid") - .build()); - } - - }; - - private static WxMaConfig config; - private static WxMaService service; - private static WxMaMessageRouter router; - private static String templateId; - - public static void main(String[] args) throws Exception { - init(); - - Server server = new Server(8080); - - ServletHandler servletHandler = new ServletHandler(); - server.setHandler(servletHandler); - - ServletHolder endpointServletHolder = new ServletHolder(new WxMaPortalServlet(config, service, router)); - servletHandler.addServletWithMapping(endpointServletHolder, "/*"); - - server.start(); - server.join(); - } - - private static void init() { - try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) { - TestConfig config = TestConfig.fromXml(is1); - config.setAccessTokenLock(new ReentrantLock()); - templateId = config.getTemplateId(); - - WxMaDemoServer.config = config; - service = new WxMaServiceImpl(); - service.setWxMaConfig(config); - - router = new WxMaMessageRouter(service); - - router.rule().handler(logHandler).next() - .rule().async(false).content("模板").handler(templateMsgHandler).end() - .rule().async(false).content("文本").handler(textHandler).end() - .rule().async(false).content("图片").handler(picHandler).end() - .rule().async(false).content("二维码").handler(qrcodeHandler).end(); - } catch (IOException e) { - e.printStackTrace(); - } - } -} +package cn.binarywang.wx.miniapp.demo; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; +import cn.binarywang.wx.miniapp.bean.WxMaMessage; +import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.constant.WxMaConstants; +import cn.binarywang.wx.miniapp.message.WxMaMessageHandler; +import cn.binarywang.wx.miniapp.message.WxMaMessageRouter; +import cn.binarywang.wx.miniapp.test.TestConfig; +import com.google.common.collect.Lists; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.session.WxSessionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author Binary Wang + */ +public class WxMaDemoServer { + + private static final WxMaMessageHandler logHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) throws WxErrorException { + System.out.println("收到消息:" + wxMessage.toString()); + service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson()) + .toUser(wxMessage.getFromUser()).build()); + } + }; + + private static final WxMaMessageHandler textHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) + throws WxErrorException { + service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息") + .toUser(wxMessage.getFromUser()).build()); + } + + }; + + private static final WxMaMessageHandler picHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) throws WxErrorException { + try { + WxMediaUploadResult uploadResult = service.getMediaService() + .uploadMedia(WxMaConstants.MediaType.IMAGE, "png", + ClassLoader.getSystemResourceAsStream("tmp.png")); + service.getMsgService().sendKefuMsg( + WxMaKefuMessage + .newImageBuilder() + .mediaId(uploadResult.getMediaId()) + .toUser(wxMessage.getFromUser()) + .build()); + } catch (WxErrorException e) { + e.printStackTrace(); + } + } + }; + + private static final WxMaMessageHandler qrcodeHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) throws WxErrorException { + try { + final File file = service.getQrcodeService().createQrcode("123", 430); + WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia(WxMaConstants.MediaType.IMAGE, file); + service.getMsgService().sendKefuMsg( + WxMaKefuMessage + .newImageBuilder() + .mediaId(uploadResult.getMediaId()) + .toUser(wxMessage.getFromUser()) + .build()); + } catch (WxErrorException e) { + e.printStackTrace(); + } + } + }; + + private static final WxMaMessageHandler templateMsgHandler = new WxMaMessageHandler() { + @Override + public void handle(WxMaMessage wxMessage, Map context, + WxMaService service, WxSessionManager sessionManager) + throws WxErrorException { + service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder() + .templateId(templateId).data(Lists.newArrayList( + new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"))) + .toUser(wxMessage.getFromUser()) + .formId("自己替换可用的formid") + .build()); + } + + }; + + private static WxMaConfig config; + private static WxMaService service; + private static WxMaMessageRouter router; + private static String templateId; + + public static void main(String[] args) throws Exception { + init(); + + Server server = new Server(8080); + + ServletHandler servletHandler = new ServletHandler(); + server.setHandler(servletHandler); + + ServletHolder endpointServletHolder = new ServletHolder(new WxMaPortalServlet(config, service, router)); + servletHandler.addServletWithMapping(endpointServletHolder, "/*"); + + server.start(); + server.join(); + } + + private static void init() { + try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) { + TestConfig config = TestConfig.fromXml(is1); + config.setAccessTokenLock(new ReentrantLock()); + templateId = config.getTemplateId(); + + WxMaDemoServer.config = config; + service = new WxMaServiceImpl(); + service.setWxMaConfig(config); + + router = new WxMaMessageRouter(service); + + router.rule().handler(logHandler).next() + .rule().async(false).content("模板").handler(templateMsgHandler).end() + .rule().async(false).content("文本").handler(textHandler).end() + .rule().async(false).content("图片").handler(picHandler).end() + .rule().async(false).content("二维码").handler(qrcodeHandler).end(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 0b492b5a82..81bf0008c5 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -1,84 +1,84 @@ - - - 4.0.0 - - com.github.binarywang - weixin-java-parent - 2.8.8.BETA - - weixin-java-mp - WeiXin Java Tools - MP - 微信公众号Java SDK - - - - com.github.binarywang - weixin-java-common - ${project.version} - - - - org.jodd - jodd-http - provided - - - com.squareup.okhttp3 - okhttp - provided - - - - org.testng - testng - test - - - com.google.inject - guice - test - - - org.eclipse.jetty - jetty-server - test - - - org.eclipse.jetty - jetty-servlet - test - - - joda-time - joda-time - test - - - redis.clients - jedis - - - ch.qos.logback - logback-classic - test - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - src/test/resources/testng.xml - - - - - - - + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 2.8.8.BETA + + weixin-java-mp + WeiXin Java Tools - MP + 微信公众号Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + + org.testng + testng + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + joda-time + joda-time + test + + + redis.clients + jedis + + + ch.qos.logback + logback-classic + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java index 36ca511b6d..a7aacd544c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java @@ -1,119 +1,119 @@ -package me.chanjar.weixin.mp.api; - -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.*; -import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; - -/** - *
- * 群发消息服务类
- * Created by Binary Wang on 2017-8-16.
- * 
- * - * @author Binary Wang - */ -public interface WxMpMassMessageService { - /** - * 上传群发用的图文消息 - */ - String MEDIA_UPLOAD_NEWS_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; - /** - * 上传群发用的视频 - */ - String MEDIA_UPLOAD_VIDEO_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadvideo"; - /** - * 分组群发消息 - */ - String MESSAGE_MASS_SENDALL_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall"; - /** - * 按openId列表群发消息 - */ - String MESSAGE_MASS_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/send"; - /** - * 群发消息预览接口 - */ - String MESSAGE_MASS_PREVIEW_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/preview"; - /** - * 删除群发接口 - */ - String MESSAGE_MASS_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/delete"; - - /** - *
-   * 上传群发用的图文消息,上传后才能群发图文消息
-   *
-   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- * - * @see #massGroupMessageSend(WxMpMassTagMessage) - * @see #massOpenIdsMessageSend(WxMpMassOpenIdsMessage) - */ - WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException; - - /** - *
-   * 上传群发用的视频,上传后才能群发视频消息
-   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- * - * @see #massGroupMessageSend(WxMpMassTagMessage) - * @see #massOpenIdsMessageSend(WxMpMassOpenIdsMessage) - */ - WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException; - - /** - *
-   * 分组群发消息
-   * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
-   * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
-   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- */ - WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException; - - /** - *
-   * 按openId列表群发消息
-   * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
-   * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
-   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- */ - WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException; - - /** - *
-   * 群发消息预览接口
-   * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100次),请勿滥用。
-   * 接口调用请求说明
-   *  http请求方式: POST
-   *  https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN
-   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
-   * 
- * - * @return wxMpMassSendResult - */ - WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException; - - /** - *
-   * 删除群发
-   * 群发之后,随时可以通过该接口删除群发。
-   * 请注意:
-   * 1、只有已经发送成功的消息才能删除
-   * 2、删除消息是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片。
-   * 3、删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。
-   * 4、如果多次群发发送的是一个图文消息,那么删除其中一次群发,就会删除掉这个图文消息也,导致所有群发都失效
-   * 接口调用请求说明:
-   *  http请求方式: POST
-   *  https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=ACCESS_TOKEN
-   * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1481187827_i0l21
-   * 
- * - * @param msgId 发送出去的消息ID - * @param articleIndex 要删除的文章在图文消息中的位置,第一篇编号为1,该字段不填或填0会删除全部文章 - */ - void delete(Integer msgId, Integer articleIndex) throws WxErrorException; - -} +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; +import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; + +/** + *
+ * 群发消息服务类
+ * Created by Binary Wang on 2017-8-16.
+ * 
+ * + * @author Binary Wang + */ +public interface WxMpMassMessageService { + /** + * 上传群发用的图文消息 + */ + String MEDIA_UPLOAD_NEWS_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; + /** + * 上传群发用的视频 + */ + String MEDIA_UPLOAD_VIDEO_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadvideo"; + /** + * 分组群发消息 + */ + String MESSAGE_MASS_SENDALL_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall"; + /** + * 按openId列表群发消息 + */ + String MESSAGE_MASS_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/send"; + /** + * 群发消息预览接口 + */ + String MESSAGE_MASS_PREVIEW_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/preview"; + /** + * 删除群发接口 + */ + String MESSAGE_MASS_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/delete"; + + /** + *
+   * 上传群发用的图文消息,上传后才能群发图文消息
+   *
+   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ * + * @see #massGroupMessageSend(WxMpMassTagMessage) + * @see #massOpenIdsMessageSend(WxMpMassOpenIdsMessage) + */ + WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException; + + /** + *
+   * 上传群发用的视频,上传后才能群发视频消息
+   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ * + * @see #massGroupMessageSend(WxMpMassTagMessage) + * @see #massOpenIdsMessageSend(WxMpMassOpenIdsMessage) + */ + WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException; + + /** + *
+   * 分组群发消息
+   * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
+   * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
+   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ */ + WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException; + + /** + *
+   * 按openId列表群发消息
+   * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
+   * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
+   * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ */ + WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException; + + /** + *
+   * 群发消息预览接口
+   * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100次),请勿滥用。
+   * 接口调用请求说明
+   *  http请求方式: POST
+   *  https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN
+   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+   * 
+ * + * @return wxMpMassSendResult + */ + WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException; + + /** + *
+   * 删除群发
+   * 群发之后,随时可以通过该接口删除群发。
+   * 请注意:
+   * 1、只有已经发送成功的消息才能删除
+   * 2、删除消息是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片。
+   * 3、删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。
+   * 4、如果多次群发发送的是一个图文消息,那么删除其中一次群发,就会删除掉这个图文消息也,导致所有群发都失效
+   * 接口调用请求说明:
+   *  http请求方式: POST
+   *  https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=ACCESS_TOKEN
+   * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1481187827_i0l21
+   * 
+ * + * @param msgId 发送出去的消息ID + * @param articleIndex 要删除的文章在图文消息中的位置,第一篇编号为1,该字段不填或填0会删除全部文章 + */ + void delete(Integer msgId, Integer articleIndex) throws WxErrorException; + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java index 3d423b0feb..697bfe899d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java @@ -1,61 +1,61 @@ -package me.chanjar.weixin.mp.api; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; -import me.chanjar.weixin.mp.bean.WxMpShakeQuery; -import me.chanjar.weixin.mp.bean.shake.*; - -/** - * 摇一摇周边的相关接口 - * - * @author rememberber - */ -public interface WxMpShakeService { - - /** - *
-   * 获取设备及用户信息
- * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 - * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963 - * http请求方式: POST(请使用https协议) - * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE - *
- * - * @param wxMpShakeQuery 查询参数 - */ - WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException; - - /** - *
-   * 页面管理
- * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459246752 - *
- * @param shakeAroundPageAddQuery - * @return - * @throws WxErrorException - */ - WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException; - - /** - *
-   * 配置设备与页面的关联关系
- * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459301931 - *
- * @param shakeAroundDeviceBindPageQuery - * @return - * @throws WxErrorException - */ - WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException; - - /** - *
-   * 查询设备与页面的关联关系
- * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443447914 - *
- * @param shakeAroundRelationSearchQuery - * @return - * @throws WxErrorException - */ - WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException; -} +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; +import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; + +/** + * 摇一摇周边的相关接口 + * + * @author rememberber + */ +public interface WxMpShakeService { + + /** + *
+   * 获取设备及用户信息
+ * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 + * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963 + * http请求方式: POST(请使用https协议) + * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE + *
+ * + * @param wxMpShakeQuery 查询参数 + */ + WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException; + + /** + *
+   * 页面管理
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459246752 + *
+ * @param shakeAroundPageAddQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException; + + /** + *
+   * 配置设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459301931 + *
+ * @param shakeAroundDeviceBindPageQuery + * @return + * @throws WxErrorException + */ + WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException; + + /** + *
+   * 查询设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443447914 + *
+ * @param shakeAroundRelationSearchQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java index 4fe596442c..49ed7589f3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java @@ -1,239 +1,239 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; -import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.bean.WxCardApiSignature; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.RandomUtils; -import me.chanjar.weixin.common.util.crypto.SHA1; -import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; -import me.chanjar.weixin.mp.api.WxMpCardService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpCardResult; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; -import java.util.concurrent.locks.Lock; - -/** - * Created by Binary Wang on 2016/7/27. - */ -public class WxMpCardServiceImpl implements WxMpCardService { - - private final Logger log = LoggerFactory.getLogger(WxMpCardServiceImpl.class); - - private WxMpService wxMpService; - - public WxMpCardServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public WxMpService getWxMpService() { - return this.wxMpService; - } - - /** - * 获得卡券api_ticket,不强制刷新卡券api_ticket - * - * @return 卡券api_ticket - * @see #getCardApiTicket(boolean) - */ - @Override - public String getCardApiTicket() throws WxErrorException { - return getCardApiTicket(false); - } - - /** - *
-   * 获得卡券api_ticket
-   * 获得时会检查卡券apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
-   *
-   * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
-   * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
-   * .9F.E6.88.90.E7.AE.97.E6.B3.95
-   * 
- * - * @param forceRefresh 强制刷新 - * @return 卡券api_ticket - */ - @Override - public String getCardApiTicket(boolean forceRefresh) throws WxErrorException { - Lock lock = getWxMpService().getWxMpConfigStorage().getCardApiTicketLock(); - try { - lock.lock(); - - if (forceRefresh) { - this.getWxMpService().getWxMpConfigStorage().expireCardApiTicket(); - } - - if (this.getWxMpService().getWxMpConfigStorage().isCardApiTicketExpired()) { - String responseContent = this.wxMpService.execute(SimpleGetRequestExecutor.create(this.getWxMpService().getRequestHttp()), CARD_GET_TICKET, null); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); - String cardApiTicket = tmpJsonObject.get("ticket").getAsString(); - int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); - this.getWxMpService().getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds); - } - } finally { - lock.unlock(); - } - return this.getWxMpService().getWxMpConfigStorage().getCardApiTicket(); - } - - /** - *
-   * 创建调用卡券api时所需要的签名
-   *
-   * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
-   * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
-   * .9F.E6.88.90.E7.AE.97.E6.B3.95
-   * 
- * - * @param optionalSignParam 参与签名的参数数组。 - * 可以为下列字段:app_id, card_id, card_type, code, openid, location_id - *
注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空 - * @return 卡券Api签名对象 - */ - @Override - public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws - WxErrorException { - long timestamp = System.currentTimeMillis() / 1000; - String nonceStr = RandomUtils.getRandomStr(); - String cardApiTicket = getCardApiTicket(false); - - String[] signParam = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3); - signParam[optionalSignParam.length] = String.valueOf(timestamp); - signParam[optionalSignParam.length + 1] = nonceStr; - signParam[optionalSignParam.length + 2] = cardApiTicket; - String signature = SHA1.gen(signParam); - WxCardApiSignature cardApiSignature = new WxCardApiSignature(); - cardApiSignature.setTimestamp(timestamp); - cardApiSignature.setNonceStr(nonceStr); - cardApiSignature.setSignature(signature); - return cardApiSignature; - } - - /** - * 卡券Code解码 - * - * @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得 - * @return 解密后的Code - */ - @Override - public String decryptCardCode(String encryptCode) throws WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("encrypt_code", encryptCode); - String responseContent = this.wxMpService.post(CARD_CODE_DECRYPT, param.toString()); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); - JsonPrimitive jsonPrimitive = tmpJsonObject.getAsJsonPrimitive("code"); - return jsonPrimitive.getAsString(); - } - - /** - * 卡券Code查询 - * - * @param cardId 卡券ID代表一类卡券 - * @param code 单张卡券的唯一标准 - * @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同 - * @return WxMpCardResult对象 - */ - @Override - public WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume) throws WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("card_id", cardId); - param.addProperty("code", code); - param.addProperty("check_consume", checkConsume); - String responseContent = this.wxMpService.post(CARD_CODE_GET, param.toString()); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, - new TypeToken() { - }.getType()); - } - - /** - * 卡券Code核销。核销失败会抛出异常 - * - * @param code 单张卡券的唯一标准 - * @return 调用返回的JSON字符串。 - *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 - */ - @Override - public String consumeCardCode(String code) throws WxErrorException { - return consumeCardCode(code, null); - } - - /** - * 卡券Code核销。核销失败会抛出异常 - * - * @param code 单张卡券的唯一标准 - * @param cardId 当自定义Code卡券时需要传入card_id - * @return 调用返回的JSON字符串。 - *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 - */ - @Override - public String consumeCardCode(String code, String cardId) throws WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("code", code); - - if (cardId != null && !"".equals(cardId)) { - param.addProperty("card_id", cardId); - } - - return this.wxMpService.post(CARD_CODE_CONSUME, param.toString()); - } - - /** - * 卡券Mark接口。 - * 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住), - * 才能进一步调用核销接口,否则报错。 - * - * @param code 卡券的code码 - * @param cardId 卡券的ID - * @param openId 用券用户的openid - * @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用 - */ - @Override - public void markCardCode(String code, String cardId, String openId, boolean isMark) throws - WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("code", code); - param.addProperty("card_id", cardId); - param.addProperty("openid", openId); - param.addProperty("is_mark", isMark); - String responseContent = this.getWxMpService().post(CARD_CODE_MARK, param.toString()); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - WxMpCardResult cardResult = WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, - new TypeToken() { - }.getType()); - if (!cardResult.getErrorCode().equals("0")) { - this.log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg()); - } - } - - @Override - public String getCardDetail(String cardId) throws WxErrorException { - JsonObject param = new JsonObject(); - param.addProperty("card_id", cardId); - String responseContent = this.wxMpService.post(CARD_GET, param.toString()); - - // 判断返回值 - JsonObject json = (new JsonParser()).parse(responseContent).getAsJsonObject(); - String errcode = json.get("errcode").getAsString(); - if (!"0".equals(errcode)) { - String errmsg = json.get("errmsg").getAsString(); - throw new WxErrorException(WxError.builder() - .errorCode(Integer.valueOf(errcode)).errorMsg(errmsg) - .build()); - } - - return responseContent; - } -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.bean.WxCardApiSignature; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.RandomUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; +import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; +import me.chanjar.weixin.mp.api.WxMpCardService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpCardResult; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.concurrent.locks.Lock; + +/** + * Created by Binary Wang on 2016/7/27. + */ +public class WxMpCardServiceImpl implements WxMpCardService { + + private final Logger log = LoggerFactory.getLogger(WxMpCardServiceImpl.class); + + private WxMpService wxMpService; + + public WxMpCardServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMpService getWxMpService() { + return this.wxMpService; + } + + /** + * 获得卡券api_ticket,不强制刷新卡券api_ticket + * + * @return 卡券api_ticket + * @see #getCardApiTicket(boolean) + */ + @Override + public String getCardApiTicket() throws WxErrorException { + return getCardApiTicket(false); + } + + /** + *
+   * 获得卡券api_ticket
+   * 获得时会检查卡券apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
+   *
+   * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
+   * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
+   * .9F.E6.88.90.E7.AE.97.E6.B3.95
+   * 
+ * + * @param forceRefresh 强制刷新 + * @return 卡券api_ticket + */ + @Override + public String getCardApiTicket(boolean forceRefresh) throws WxErrorException { + Lock lock = getWxMpService().getWxMpConfigStorage().getCardApiTicketLock(); + try { + lock.lock(); + + if (forceRefresh) { + this.getWxMpService().getWxMpConfigStorage().expireCardApiTicket(); + } + + if (this.getWxMpService().getWxMpConfigStorage().isCardApiTicketExpired()) { + String responseContent = this.wxMpService.execute(SimpleGetRequestExecutor.create(this.getWxMpService().getRequestHttp()), CARD_GET_TICKET, null); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); + String cardApiTicket = tmpJsonObject.get("ticket").getAsString(); + int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); + this.getWxMpService().getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds); + } + } finally { + lock.unlock(); + } + return this.getWxMpService().getWxMpConfigStorage().getCardApiTicket(); + } + + /** + *
+   * 创建调用卡券api时所需要的签名
+   *
+   * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
+   * .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
+   * .9F.E6.88.90.E7.AE.97.E6.B3.95
+   * 
+ * + * @param optionalSignParam 参与签名的参数数组。 + * 可以为下列字段:app_id, card_id, card_type, code, openid, location_id + *
注意:当做wx.chooseCard调用时,必须传入app_id参与签名,否则会造成签名失败导致拉取卡券列表为空 + * @return 卡券Api签名对象 + */ + @Override + public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws + WxErrorException { + long timestamp = System.currentTimeMillis() / 1000; + String nonceStr = RandomUtils.getRandomStr(); + String cardApiTicket = getCardApiTicket(false); + + String[] signParam = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3); + signParam[optionalSignParam.length] = String.valueOf(timestamp); + signParam[optionalSignParam.length + 1] = nonceStr; + signParam[optionalSignParam.length + 2] = cardApiTicket; + String signature = SHA1.gen(signParam); + WxCardApiSignature cardApiSignature = new WxCardApiSignature(); + cardApiSignature.setTimestamp(timestamp); + cardApiSignature.setNonceStr(nonceStr); + cardApiSignature.setSignature(signature); + return cardApiSignature; + } + + /** + * 卡券Code解码 + * + * @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得 + * @return 解密后的Code + */ + @Override + public String decryptCardCode(String encryptCode) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("encrypt_code", encryptCode); + String responseContent = this.wxMpService.post(CARD_CODE_DECRYPT, param.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); + JsonPrimitive jsonPrimitive = tmpJsonObject.getAsJsonPrimitive("code"); + return jsonPrimitive.getAsString(); + } + + /** + * 卡券Code查询 + * + * @param cardId 卡券ID代表一类卡券 + * @param code 单张卡券的唯一标准 + * @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同 + * @return WxMpCardResult对象 + */ + @Override + public WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("card_id", cardId); + param.addProperty("code", code); + param.addProperty("check_consume", checkConsume); + String responseContent = this.wxMpService.post(CARD_CODE_GET, param.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, + new TypeToken() { + }.getType()); + } + + /** + * 卡券Code核销。核销失败会抛出异常 + * + * @param code 单张卡券的唯一标准 + * @return 调用返回的JSON字符串。 + *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 + */ + @Override + public String consumeCardCode(String code) throws WxErrorException { + return consumeCardCode(code, null); + } + + /** + * 卡券Code核销。核销失败会抛出异常 + * + * @param code 单张卡券的唯一标准 + * @param cardId 当自定义Code卡券时需要传入card_id + * @return 调用返回的JSON字符串。 + *
可用 com.google.gson.JsonParser#parse 等方法直接取JSON串中的errcode等信息。 + */ + @Override + public String consumeCardCode(String code, String cardId) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("code", code); + + if (cardId != null && !"".equals(cardId)) { + param.addProperty("card_id", cardId); + } + + return this.wxMpService.post(CARD_CODE_CONSUME, param.toString()); + } + + /** + * 卡券Mark接口。 + * 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住), + * 才能进一步调用核销接口,否则报错。 + * + * @param code 卡券的code码 + * @param cardId 卡券的ID + * @param openId 用券用户的openid + * @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用 + */ + @Override + public void markCardCode(String code, String cardId, String openId, boolean isMark) throws + WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("code", code); + param.addProperty("card_id", cardId); + param.addProperty("openid", openId); + param.addProperty("is_mark", isMark); + String responseContent = this.getWxMpService().post(CARD_CODE_MARK, param.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + WxMpCardResult cardResult = WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, + new TypeToken() { + }.getType()); + if (!cardResult.getErrorCode().equals("0")) { + this.log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg()); + } + } + + @Override + public String getCardDetail(String cardId) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("card_id", cardId); + String responseContent = this.wxMpService.post(CARD_GET, param.toString()); + + // 判断返回值 + JsonObject json = (new JsonParser()).parse(responseContent).getAsJsonObject(); + String errcode = json.get("errcode").getAsString(); + if (!"0".equals(errcode)) { + String errmsg = json.get("errmsg").getAsString(); + throw new WxErrorException(WxError.builder() + .errorCode(Integer.valueOf(errcode)).errorMsg(errmsg) + .build()); + } + + return responseContent; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java index 4301bc2c73..6bda9e5caf 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java @@ -1,152 +1,152 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonObject; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; -import me.chanjar.weixin.mp.api.WxMpKefuService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; -import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; -import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest; -import me.chanjar.weixin.mp.bean.kefu.result.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.Date; - -/** - * @author Binary Wang - */ -public class WxMpKefuServiceImpl implements WxMpKefuService { - protected final Logger log = LoggerFactory.getLogger(this.getClass()); - private WxMpService wxMpService; - - public WxMpKefuServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public boolean sendKefuMessage(WxMpKefuMessage message) throws WxErrorException { - String responseContent = this.wxMpService.post(MESSAGE_CUSTOM_SEND, message.toJson()); - return responseContent != null; - } - - @Override - public WxMpKfList kfList() throws WxErrorException { - String responseContent = this.wxMpService.get(GET_KF_LIST, null); - return WxMpKfList.fromJson(responseContent); - } - - @Override - public WxMpKfOnlineList kfOnlineList() throws WxErrorException { - String responseContent = this.wxMpService.get(GET_ONLINE_KF_LIST, null); - return WxMpKfOnlineList.fromJson(responseContent); - } - - @Override - public boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException { - String responseContent = this.wxMpService.post(KFACCOUNT_ADD, request.toJson()); - return responseContent != null; - } - - @Override - public boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException { - String responseContent = this.wxMpService.post(KFACCOUNT_UPDATE, request.toJson()); - return responseContent != null; - } - - @Override - public boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException { - String responseContent = this.wxMpService.post(KFACCOUNT_INVITE_WORKER, request.toJson()); - return responseContent != null; - } - - @Override - public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException { - WxMediaUploadResult responseContent = this.wxMpService - .execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), String.format(KFACCOUNT_UPLOAD_HEAD_IMG, kfAccount), imgFile); - return responseContent != null; - } - - @Override - public boolean kfAccountDel(String kfAccount) throws WxErrorException { - String responseContent = this.wxMpService.get(String.format(KFACCOUNT_DEL, kfAccount), null); - return responseContent != null; - } - - @Override - public boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException { - WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); - String responseContent = this.wxMpService.post(KFSESSION_CREATE, request.toJson()); - return responseContent != null; - } - - @Override - public boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException { - WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); - String responseContent = this.wxMpService.post(KFSESSION_CLOSE, request.toJson()); - return responseContent != null; - } - - @Override - public WxMpKfSessionGetResult kfSessionGet(String openid) throws WxErrorException { - String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION, openid), null); - return WxMpKfSessionGetResult.fromJson(responseContent); - } - - @Override - public WxMpKfSessionList kfSessionList(String kfAccount) throws WxErrorException { - String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION_LIST, kfAccount), null); - return WxMpKfSessionList.fromJson(responseContent); - } - - @Override - public WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException { - String responseContent = this.wxMpService.get(KFSESSION_GET_WAIT_CASE, null); - return WxMpKfSessionWaitCaseList.fromJson(responseContent); - } - - @Override - public WxMpKfMsgList kfMsgList(Date startTime, Date endTime, Long msgId, Integer number) throws WxErrorException { - if (number > 10000) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法参数请求,每次最多查询10000条记录!").build()); - } - - if (startTime.after(endTime)) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("起始时间不能晚于结束时间!").build()); - } - - JsonObject param = new JsonObject(); - param.addProperty("starttime", startTime.getTime() / 1000); //starttime 起始时间,unix时间戳 - param.addProperty("endtime", endTime.getTime() / 1000); //endtime 结束时间,unix时间戳,每次查询时段不能超过24小时 - param.addProperty("msgid", msgId); //msgid 消息id顺序从小到大,从1开始 - param.addProperty("number", number); //number 每次获取条数,最多10000条 - - String responseContent = this.wxMpService.post(MSGRECORD_GET_MSG_LIST, param.toString()); - - return WxMpKfMsgList.fromJson(responseContent); - } - - @Override - public WxMpKfMsgList kfMsgList(Date startTime, Date endTime) throws WxErrorException { - int number = 10000; - WxMpKfMsgList result = this.kfMsgList(startTime, endTime, 1L, number); - - if (result != null && result.getNumber() == number) { - Long msgId = result.getMsgId(); - WxMpKfMsgList followingResult = this.kfMsgList(startTime, endTime, msgId, number); - while (followingResult != null && followingResult.getRecords().size() > 0) { - result.getRecords().addAll(followingResult.getRecords()); - result.setNumber(result.getNumber() + followingResult.getNumber()); - result.setMsgId(followingResult.getMsgId()); - followingResult = this.kfMsgList(startTime, endTime, followingResult.getMsgId(), number); - } - } - - return result; - } - -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; +import me.chanjar.weixin.mp.api.WxMpKefuService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; +import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; +import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest; +import me.chanjar.weixin.mp.bean.kefu.result.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.Date; + +/** + * @author Binary Wang + */ +public class WxMpKefuServiceImpl implements WxMpKefuService { + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + private WxMpService wxMpService; + + public WxMpKefuServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public boolean sendKefuMessage(WxMpKefuMessage message) throws WxErrorException { + String responseContent = this.wxMpService.post(MESSAGE_CUSTOM_SEND, message.toJson()); + return responseContent != null; + } + + @Override + public WxMpKfList kfList() throws WxErrorException { + String responseContent = this.wxMpService.get(GET_KF_LIST, null); + return WxMpKfList.fromJson(responseContent); + } + + @Override + public WxMpKfOnlineList kfOnlineList() throws WxErrorException { + String responseContent = this.wxMpService.get(GET_ONLINE_KF_LIST, null); + return WxMpKfOnlineList.fromJson(responseContent); + } + + @Override + public boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException { + String responseContent = this.wxMpService.post(KFACCOUNT_ADD, request.toJson()); + return responseContent != null; + } + + @Override + public boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException { + String responseContent = this.wxMpService.post(KFACCOUNT_UPDATE, request.toJson()); + return responseContent != null; + } + + @Override + public boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException { + String responseContent = this.wxMpService.post(KFACCOUNT_INVITE_WORKER, request.toJson()); + return responseContent != null; + } + + @Override + public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException { + WxMediaUploadResult responseContent = this.wxMpService + .execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), String.format(KFACCOUNT_UPLOAD_HEAD_IMG, kfAccount), imgFile); + return responseContent != null; + } + + @Override + public boolean kfAccountDel(String kfAccount) throws WxErrorException { + String responseContent = this.wxMpService.get(String.format(KFACCOUNT_DEL, kfAccount), null); + return responseContent != null; + } + + @Override + public boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException { + WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); + String responseContent = this.wxMpService.post(KFSESSION_CREATE, request.toJson()); + return responseContent != null; + } + + @Override + public boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException { + WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); + String responseContent = this.wxMpService.post(KFSESSION_CLOSE, request.toJson()); + return responseContent != null; + } + + @Override + public WxMpKfSessionGetResult kfSessionGet(String openid) throws WxErrorException { + String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION, openid), null); + return WxMpKfSessionGetResult.fromJson(responseContent); + } + + @Override + public WxMpKfSessionList kfSessionList(String kfAccount) throws WxErrorException { + String responseContent = this.wxMpService.get(String.format(KFSESSION_GET_SESSION_LIST, kfAccount), null); + return WxMpKfSessionList.fromJson(responseContent); + } + + @Override + public WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException { + String responseContent = this.wxMpService.get(KFSESSION_GET_WAIT_CASE, null); + return WxMpKfSessionWaitCaseList.fromJson(responseContent); + } + + @Override + public WxMpKfMsgList kfMsgList(Date startTime, Date endTime, Long msgId, Integer number) throws WxErrorException { + if (number > 10000) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法参数请求,每次最多查询10000条记录!").build()); + } + + if (startTime.after(endTime)) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("起始时间不能晚于结束时间!").build()); + } + + JsonObject param = new JsonObject(); + param.addProperty("starttime", startTime.getTime() / 1000); //starttime 起始时间,unix时间戳 + param.addProperty("endtime", endTime.getTime() / 1000); //endtime 结束时间,unix时间戳,每次查询时段不能超过24小时 + param.addProperty("msgid", msgId); //msgid 消息id顺序从小到大,从1开始 + param.addProperty("number", number); //number 每次获取条数,最多10000条 + + String responseContent = this.wxMpService.post(MSGRECORD_GET_MSG_LIST, param.toString()); + + return WxMpKfMsgList.fromJson(responseContent); + } + + @Override + public WxMpKfMsgList kfMsgList(Date startTime, Date endTime) throws WxErrorException { + int number = 10000; + WxMpKfMsgList result = this.kfMsgList(startTime, endTime, 1L, number); + + if (result != null && result.getNumber() == number) { + Long msgId = result.getMsgId(); + WxMpKfMsgList followingResult = this.kfMsgList(startTime, endTime, msgId, number); + while (followingResult != null && followingResult.getRecords().size() > 0) { + result.getRecords().addAll(followingResult.getRecords()); + result.setNumber(result.getNumber() + followingResult.getNumber()); + result.setMsgId(followingResult.getMsgId()); + followingResult = this.kfMsgList(startTime, endTime, followingResult.getMsgId(), number); + } + } + + return result; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java index 21555628d1..779bbc4d9d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java @@ -1,67 +1,67 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonObject; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpMassMessageService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.*; -import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - *
- * 群发消息服务类
- * Created by Binary Wang on 2017-8-16.
- * 
- * - * @author Binary Wang - */ -public class WxMpMassMessageServiceImpl implements WxMpMassMessageService { - protected final Logger log = LoggerFactory.getLogger(this.getClass()); - private WxMpService wxMpService; - - public WxMpMassMessageServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException { - String responseContent = this.wxMpService.post(MEDIA_UPLOAD_NEWS_URL, news.toJson()); - return WxMpMassUploadResult.fromJson(responseContent); - } - - @Override - public WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException { - String responseContent = this.wxMpService.post(MEDIA_UPLOAD_VIDEO_URL, video.toJson()); - return WxMpMassUploadResult.fromJson(responseContent); - } - - @Override - public WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException { - String responseContent = this.wxMpService.post(WxMpMassMessageService.MESSAGE_MASS_SENDALL_URL, message.toJson()); - return WxMpMassSendResult.fromJson(responseContent); - } - - @Override - public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException { - String responseContent = this.wxMpService.post(MESSAGE_MASS_SEND_URL, message.toJson()); - return WxMpMassSendResult.fromJson(responseContent); - } - - @Override - public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException { - String responseContent = this.wxMpService.post(MESSAGE_MASS_PREVIEW_URL, wxMpMassPreviewMessage.toJson()); - return WxMpMassSendResult.fromJson(responseContent); - } - - @Override - public void delete(Integer msgId, Integer articleIndex) throws WxErrorException { - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("msg_id", msgId); - jsonObject.addProperty("article_idx", articleIndex); - this.wxMpService.post(MESSAGE_MASS_DELETE_URL, jsonObject.toString()); - } - -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpMassMessageService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; +import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *
+ * 群发消息服务类
+ * Created by Binary Wang on 2017-8-16.
+ * 
+ * + * @author Binary Wang + */ +public class WxMpMassMessageServiceImpl implements WxMpMassMessageService { + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + private WxMpService wxMpService; + + public WxMpMassMessageServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException { + String responseContent = this.wxMpService.post(MEDIA_UPLOAD_NEWS_URL, news.toJson()); + return WxMpMassUploadResult.fromJson(responseContent); + } + + @Override + public WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException { + String responseContent = this.wxMpService.post(MEDIA_UPLOAD_VIDEO_URL, video.toJson()); + return WxMpMassUploadResult.fromJson(responseContent); + } + + @Override + public WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException { + String responseContent = this.wxMpService.post(WxMpMassMessageService.MESSAGE_MASS_SENDALL_URL, message.toJson()); + return WxMpMassSendResult.fromJson(responseContent); + } + + @Override + public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException { + String responseContent = this.wxMpService.post(MESSAGE_MASS_SEND_URL, message.toJson()); + return WxMpMassSendResult.fromJson(responseContent); + } + + @Override + public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException { + String responseContent = this.wxMpService.post(MESSAGE_MASS_PREVIEW_URL, wxMpMassPreviewMessage.toJson()); + return WxMpMassSendResult.fromJson(responseContent); + } + + @Override + public void delete(Integer msgId, Integer articleIndex) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("msg_id", msgId); + jsonObject.addProperty("article_idx", articleIndex); + this.wxMpService.post(MESSAGE_MASS_DELETE_URL, jsonObject.toString()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java index e5283a7b28..520f69ea0d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java @@ -1,151 +1,151 @@ -package me.chanjar.weixin.mp.api.impl; - -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.fs.FileUtils; -import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; -import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.api.WxMpMaterialService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.material.*; -import me.chanjar.weixin.mp.util.http.*; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -/** - * Created by Binary Wang on 2016/7/21. - */ -public class WxMpMaterialServiceImpl implements WxMpMaterialService { - - private WxMpService wxMpService; - - public WxMpMaterialServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { - try { - return this.mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); - } catch (IOException e) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build(), e); - } - } - - @Override - public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { - String url = String.format(MEDIA_UPLOAD_URL, mediaType); - return this.wxMpService.execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, file); - } - - @Override - public File mediaDownload(String mediaId) throws WxErrorException { - return this.wxMpService.execute( - BaseMediaDownloadRequestExecutor.create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), - MEDIA_GET_URL, - "media_id=" + mediaId); - } - - @Override - public WxMediaImgUploadResult mediaImgUpload(File file) throws WxErrorException { - return this.wxMpService.execute(MediaImgUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), IMG_UPLOAD_URL, file); - } - - @Override - public WxMpMaterialUploadResult materialFileUpload(String mediaType, WxMpMaterial material) throws WxErrorException { - String url = String.format(MATERIAL_ADD_URL, mediaType); - return this.wxMpService.execute(MaterialUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, material); - } - - @Override - public WxMpMaterialUploadResult materialNewsUpload(WxMpMaterialNews news) throws WxErrorException { - if (news == null || news.isEmpty()) { - throw new IllegalArgumentException("news is empty!"); - } - String responseContent = this.wxMpService.post(NEWS_ADD_URL, news.toJson()); - return WxMpMaterialUploadResult.fromJson(responseContent); - } - - @Override - public InputStream materialImageOrVoiceDownload(String mediaId) throws WxErrorException { - return this.wxMpService.execute(MaterialVoiceAndImageDownloadRequestExecutor - .create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), MATERIAL_GET_URL, mediaId); - } - - @Override - public WxMpMaterialVideoInfoResult materialVideoInfo(String mediaId) throws WxErrorException { - return this.wxMpService.execute(MaterialVideoInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId); - } - - @Override - public WxMpMaterialNews materialNewsInfo(String mediaId) throws WxErrorException { - return this.wxMpService.execute(MaterialNewsInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId); - } - - @Override - public boolean materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException { - String responseText = this.wxMpService.post(NEWS_UPDATE_URL, wxMpMaterialArticleUpdate.toJson()); - WxError wxError = WxError.fromJson(responseText); - if (wxError.getErrorCode() == 0) { - return true; - } else { - throw new WxErrorException(wxError); - } - } - - @Override - public boolean materialDelete(String mediaId) throws WxErrorException { - return this.wxMpService.execute(MaterialDeleteRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_DEL_URL, mediaId); - } - - @Override - public WxMpMaterialCountResult materialCount() throws WxErrorException { - String responseText = this.wxMpService.get(MATERIAL_GET_COUNT_URL, null); - WxError wxError = WxError.fromJson(responseText); - if (wxError.getErrorCode() == 0) { - return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialCountResult.class); - } else { - throw new WxErrorException(wxError); - } - } - - @Override - public WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException { - Map params = new HashMap<>(); - params.put("type", WxConsts.MaterialType.NEWS); - params.put("offset", offset); - params.put("count", count); - String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); - WxError wxError = WxError.fromJson(responseText); - if (wxError.getErrorCode() == 0) { - return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialNewsBatchGetResult.class); - } else { - throw new WxErrorException(wxError); - } - } - - @Override - public WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offset, int count) throws WxErrorException { - Map params = new HashMap<>(); - params.put("type", type); - params.put("offset", offset); - params.put("count", count); - String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); - WxError wxError = WxError.fromJson(responseText); - if (wxError.getErrorCode() == 0) { - return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialFileBatchGetResult.class); - } else { - throw new WxErrorException(wxError); - } - } - -} +package me.chanjar.weixin.mp.api.impl; + +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.api.WxMpMaterialService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.material.*; +import me.chanjar.weixin.mp.util.http.*; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Created by Binary Wang on 2016/7/21. + */ +public class WxMpMaterialServiceImpl implements WxMpMaterialService { + + private WxMpService wxMpService; + + public WxMpMaterialServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { + try { + return this.mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); + } catch (IOException e) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build(), e); + } + } + + @Override + public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { + String url = String.format(MEDIA_UPLOAD_URL, mediaType); + return this.wxMpService.execute(MediaUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, file); + } + + @Override + public File mediaDownload(String mediaId) throws WxErrorException { + return this.wxMpService.execute( + BaseMediaDownloadRequestExecutor.create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), + MEDIA_GET_URL, + "media_id=" + mediaId); + } + + @Override + public WxMediaImgUploadResult mediaImgUpload(File file) throws WxErrorException { + return this.wxMpService.execute(MediaImgUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), IMG_UPLOAD_URL, file); + } + + @Override + public WxMpMaterialUploadResult materialFileUpload(String mediaType, WxMpMaterial material) throws WxErrorException { + String url = String.format(MATERIAL_ADD_URL, mediaType); + return this.wxMpService.execute(MaterialUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), url, material); + } + + @Override + public WxMpMaterialUploadResult materialNewsUpload(WxMpMaterialNews news) throws WxErrorException { + if (news == null || news.isEmpty()) { + throw new IllegalArgumentException("news is empty!"); + } + String responseContent = this.wxMpService.post(NEWS_ADD_URL, news.toJson()); + return WxMpMaterialUploadResult.fromJson(responseContent); + } + + @Override + public InputStream materialImageOrVoiceDownload(String mediaId) throws WxErrorException { + return this.wxMpService.execute(MaterialVoiceAndImageDownloadRequestExecutor + .create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), MATERIAL_GET_URL, mediaId); + } + + @Override + public WxMpMaterialVideoInfoResult materialVideoInfo(String mediaId) throws WxErrorException { + return this.wxMpService.execute(MaterialVideoInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId); + } + + @Override + public WxMpMaterialNews materialNewsInfo(String mediaId) throws WxErrorException { + return this.wxMpService.execute(MaterialNewsInfoRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_GET_URL, mediaId); + } + + @Override + public boolean materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException { + String responseText = this.wxMpService.post(NEWS_UPDATE_URL, wxMpMaterialArticleUpdate.toJson()); + WxError wxError = WxError.fromJson(responseText); + if (wxError.getErrorCode() == 0) { + return true; + } else { + throw new WxErrorException(wxError); + } + } + + @Override + public boolean materialDelete(String mediaId) throws WxErrorException { + return this.wxMpService.execute(MaterialDeleteRequestExecutor.create(this.wxMpService.getRequestHttp()), MATERIAL_DEL_URL, mediaId); + } + + @Override + public WxMpMaterialCountResult materialCount() throws WxErrorException { + String responseText = this.wxMpService.get(MATERIAL_GET_COUNT_URL, null); + WxError wxError = WxError.fromJson(responseText); + if (wxError.getErrorCode() == 0) { + return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialCountResult.class); + } else { + throw new WxErrorException(wxError); + } + } + + @Override + public WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException { + Map params = new HashMap<>(); + params.put("type", WxConsts.MaterialType.NEWS); + params.put("offset", offset); + params.put("count", count); + String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if (wxError.getErrorCode() == 0) { + return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialNewsBatchGetResult.class); + } else { + throw new WxErrorException(wxError); + } + } + + @Override + public WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offset, int count) throws WxErrorException { + Map params = new HashMap<>(); + params.put("type", type); + params.put("offset", offset); + params.put("count", count); + String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if (wxError.getErrorCode() == 0) { + return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialFileBatchGetResult.class); + } else { + throw new WxErrorException(wxError); + } + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java index 0c2ca1b142..f6af96e5f8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java @@ -1,151 +1,151 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonObject; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpQrcodeService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; -import org.apache.commons.lang3.StringUtils; - -import java.io.File; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; - -/** - * Created by Binary Wang on 2016/7/21. - */ -public class WxMpQrcodeServiceImpl implements WxMpQrcodeService { - private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/qrcode"; - private WxMpService wxMpService; - - public WxMpQrcodeServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - @Override - public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds) throws WxErrorException { - if (sceneId == 0) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为0!").build()); - } - - //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 - if (expireSeconds != null && expireSeconds > 2592000) { - throw new WxErrorException(WxError.builder().errorCode(-1) - .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); - } - - if (expireSeconds == null) { - expireSeconds = 30; - } - - String url = API_URL_PREFIX + "/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_SCENE"); - json.addProperty("expire_seconds", expireSeconds); - - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_id", sceneId); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = this.wxMpService.post(url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - - @Override - public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSeconds) throws WxErrorException { - if (StringUtils.isBlank(sceneStr)) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为空!").build()); - } - - //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 - if (expireSeconds != null && expireSeconds > 2592000) { - throw new WxErrorException(WxError.builder().errorCode(-1) - .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); - } - - if (expireSeconds == null) { - expireSeconds = 30; - } - - String url = API_URL_PREFIX + "/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_STR_SCENE"); - json.addProperty("expire_seconds", expireSeconds); - - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_str", sceneStr); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = this.wxMpService.post(url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - - @Override - public WxMpQrCodeTicket qrCodeCreateLastTicket(int sceneId) throws WxErrorException { - if (sceneId < 1 || sceneId > 100000) { - throw new WxErrorException(WxError.builder().errorCode(-1) - .errorMsg("永久二维码的场景值目前只支持1--100000!") - .build()); - } - - String url = API_URL_PREFIX + "/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_LIMIT_SCENE"); - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_id", sceneId); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = this.wxMpService.post(url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - @Override - public WxMpQrCodeTicket qrCodeCreateLastTicket(String sceneStr) throws WxErrorException { - String url = API_URL_PREFIX + "/create"; - JsonObject json = new JsonObject(); - json.addProperty("action_name", "QR_LIMIT_STR_SCENE"); - JsonObject actionInfo = new JsonObject(); - JsonObject scene = new JsonObject(); - scene.addProperty("scene_str", sceneStr); - actionInfo.add("scene", scene); - json.add("action_info", actionInfo); - String responseContent = this.wxMpService.post(url, json.toString()); - return WxMpQrCodeTicket.fromJson(responseContent); - } - - @Override - public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { - String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; - return this.wxMpService.execute(QrCodeRequestExecutor.create(this.wxMpService.getRequestHttp()), url, ticket); - } - - @Override - public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException { - String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s"; - try { - String resultUrl = String.format(url, - URLEncoder.encode(ticket, StandardCharsets.UTF_8.name())); - if (needShortUrl) { - return this.wxMpService.shortUrl(resultUrl); - } - - return resultUrl; - } catch (UnsupportedEncodingException e) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build()); - } - } - - @Override - public String qrCodePictureUrl(String ticket) throws WxErrorException { - return qrCodePictureUrl(ticket, false); - } - -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpQrcodeService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +/** + * Created by Binary Wang on 2016/7/21. + */ +public class WxMpQrcodeServiceImpl implements WxMpQrcodeService { + private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/qrcode"; + private WxMpService wxMpService; + + public WxMpQrcodeServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds) throws WxErrorException { + if (sceneId == 0) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为0!").build()); + } + + //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 + if (expireSeconds != null && expireSeconds > 2592000) { + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); + } + + if (expireSeconds == null) { + expireSeconds = 30; + } + + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_SCENE"); + json.addProperty("expire_seconds", expireSeconds); + + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_id", sceneId); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.post(url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + + @Override + public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSeconds) throws WxErrorException { + if (StringUtils.isBlank(sceneStr)) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为空!").build()); + } + + //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 + if (expireSeconds != null && expireSeconds > 2592000) { + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); + } + + if (expireSeconds == null) { + expireSeconds = 30; + } + + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_STR_SCENE"); + json.addProperty("expire_seconds", expireSeconds); + + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_str", sceneStr); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.post(url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + + @Override + public WxMpQrCodeTicket qrCodeCreateLastTicket(int sceneId) throws WxErrorException { + if (sceneId < 1 || sceneId > 100000) { + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("永久二维码的场景值目前只支持1--100000!") + .build()); + } + + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_LIMIT_SCENE"); + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_id", sceneId); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.post(url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + @Override + public WxMpQrCodeTicket qrCodeCreateLastTicket(String sceneStr) throws WxErrorException { + String url = API_URL_PREFIX + "/create"; + JsonObject json = new JsonObject(); + json.addProperty("action_name", "QR_LIMIT_STR_SCENE"); + JsonObject actionInfo = new JsonObject(); + JsonObject scene = new JsonObject(); + scene.addProperty("scene_str", sceneStr); + actionInfo.add("scene", scene); + json.add("action_info", actionInfo); + String responseContent = this.wxMpService.post(url, json.toString()); + return WxMpQrCodeTicket.fromJson(responseContent); + } + + @Override + public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { + String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; + return this.wxMpService.execute(QrCodeRequestExecutor.create(this.wxMpService.getRequestHttp()), url, ticket); + } + + @Override + public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException { + String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s"; + try { + String resultUrl = String.format(url, + URLEncoder.encode(ticket, StandardCharsets.UTF_8.name())); + if (needShortUrl) { + return this.wxMpService.shortUrl(resultUrl); + } + + return resultUrl; + } catch (UnsupportedEncodingException e) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build()); + } + } + + @Override + public String qrCodePictureUrl(String ticket) throws WxErrorException { + return qrCodePictureUrl(ticket, false); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java index c5d71693b0..420cb25249 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java @@ -1,469 +1,469 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import me.chanjar.weixin.common.bean.WxJsapiSignature; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.session.StandardSessionManager; -import me.chanjar.weixin.common.session.WxSessionManager; -import me.chanjar.weixin.common.util.RandomUtils; -import me.chanjar.weixin.common.util.crypto.SHA1; -import me.chanjar.weixin.common.util.http.*; -import me.chanjar.weixin.mp.api.*; -import me.chanjar.weixin.mp.bean.*; -import me.chanjar.weixin.mp.bean.result.*; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.concurrent.locks.Lock; - -public abstract class WxMpServiceAbstractImpl implements WxMpService, RequestHttp { - - private static final JsonParser JSON_PARSER = new JsonParser(); - - protected final Logger log = LoggerFactory.getLogger(this.getClass()); - protected WxSessionManager sessionManager = new StandardSessionManager(); - protected WxMpConfigStorage wxMpConfigStorage; - private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); - private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); - private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); - private WxMpUserService userService = new WxMpUserServiceImpl(this); - private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this); - private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); - private WxMpCardService cardService = new WxMpCardServiceImpl(this); - private WxMpStoreService storeService = new WxMpStoreServiceImpl(this); - private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); - private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); - private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); - private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); - private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this); - private WxMpMemberCardService memberCardService = new WxMpMemberCardServiceImpl(this); - private WxMpMassMessageService massMessageService = new WxMpMassMessageServiceImpl(this); - - private int retrySleepMillis = 1000; - private int maxRetryTimes = 5; - - - @Override - public boolean checkSignature(String timestamp, String nonce, String signature) { - try { - return SHA1.gen(this.getWxMpConfigStorage().getToken(), timestamp, nonce) - .equals(signature); - } catch (Exception e) { - this.log.error("Checking signature failed, and the reason is :" + e.getMessage()); - return false; - } - } - - @Override - public String getJsapiTicket() throws WxErrorException { - return getJsapiTicket(false); - } - - @Override - public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { - Lock lock = this.getWxMpConfigStorage().getJsapiTicketLock(); - try { - lock.lock(); - if (forceRefresh) { - this.getWxMpConfigStorage().expireJsapiTicket(); - } - - if (this.getWxMpConfigStorage().isJsapiTicketExpired()) { - String responseContent = execute(SimpleGetRequestExecutor.create(this), WxMpService.GET_JSAPI_TICKET_URL, null); - JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); - JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); - String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); - int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); - this.getWxMpConfigStorage().updateJsapiTicket(jsapiTicket, expiresInSeconds); - } - } finally { - lock.unlock(); - } - return this.getWxMpConfigStorage().getJsapiTicket(); - } - - @Override - public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { - long timestamp = System.currentTimeMillis() / 1000; - String noncestr = RandomUtils.getRandomStr(); - String jsapiTicket = getJsapiTicket(false); - String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, - "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); - WxJsapiSignature jsapiSignature = new WxJsapiSignature(); - jsapiSignature.setAppId(this.getWxMpConfigStorage().getAppId()); - jsapiSignature.setTimestamp(timestamp); - jsapiSignature.setNonceStr(noncestr); - jsapiSignature.setUrl(url); - jsapiSignature.setSignature(signature); - return jsapiSignature; - } - - @Override - public String getAccessToken() throws WxErrorException { - return getAccessToken(false); - } - - @Override - public String shortUrl(String long_url) throws WxErrorException { - JsonObject o = new JsonObject(); - o.addProperty("action", "long2short"); - o.addProperty("long_url", long_url); - String responseContent = this.post(WxMpService.SHORTURL_API_URL, o.toString()); - JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); - return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); - } - - @Override - public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException { - String responseContent = this.post(WxMpService.SEMANTIC_SEMPROXY_SEARCH_URL, semanticQuery.toJson()); - return WxMpSemanticQueryResult.fromJson(responseContent); - } - - @Override - public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) { - return String.format(WxMpService.CONNECT_OAUTH2_AUTHORIZE_URL, - this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); - } - - @Override - public String buildQrConnectUrl(String redirectURI, String scope, String state) { - return String.format(WxMpService.QRCONNECT_URL, - this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); - } - - private WxMpOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException { - try { - RequestExecutor executor = SimpleGetRequestExecutor.create(this); - String responseText = executor.execute(url, null); - return WxMpOAuth2AccessToken.fromJson(responseText); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException { - String url = String.format(WxMpService.OAUTH2_ACCESS_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret(), code); - return this.getOAuth2AccessToken(url); - } - - @Override - public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException { - String url = String.format(WxMpService.OAUTH2_REFRESH_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), refreshToken); - return this.getOAuth2AccessToken(url); - } - - @Override - public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException { - if (lang == null) { - lang = "zh_CN"; - } - - String url = String.format(WxMpService.OAUTH2_USERINFO_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId(), lang); - - try { - RequestExecutor executor = SimpleGetRequestExecutor.create(this); - String responseText = executor.execute(url, null); - return WxMpUser.fromJson(responseText); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken) { - String url = String.format(WxMpService.OAUTH2_VALIDATE_TOKEN_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId()); - - try { - SimpleGetRequestExecutor.create(this).execute(url, null); - } catch (IOException e) { - throw new RuntimeException(e); - } catch (WxErrorException e) { - return false; - } - return true; - } - - @Override - public String[] getCallbackIP() throws WxErrorException { - String responseContent = this.get(WxMpService.GET_CALLBACK_IP_URL, null); - JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); - JsonArray ipList = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray(); - String[] ipArray = new String[ipList.size()]; - for (int i = 0; i < ipList.size(); i++) { - ipArray[i] = ipList.get(i).getAsString(); - } - return ipArray; - } - - @Override - public WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException { - return WxMpCurrentAutoReplyInfo.fromJson(this.get(GET_CURRENT_AUTOREPLY_INFO_URL, null)); - } - - @Override - public String get(String url, String queryParam) throws WxErrorException { - return execute(SimpleGetRequestExecutor.create(this), url, queryParam); - } - - @Override - public String post(String url, String postData) throws WxErrorException { - return execute(SimplePostRequestExecutor.create(this), url, postData); - } - - /** - * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 - */ - public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { - int retryTimes = 0; - do { - try { - return this.executeInternal(executor, uri, data); - } catch (WxErrorException e) { - if (retryTimes + 1 > this.maxRetryTimes) { - this.log.warn("重试达到最大次数【{}】", maxRetryTimes); - //最后一次重试失败后,直接抛出异常,不再等待 - throw new RuntimeException("微信服务端异常,超出重试次数"); - } - - WxError error = e.getError(); - // -1 系统繁忙, 1000ms后重试 - if (error.getErrorCode() == -1) { - int sleepMillis = this.retrySleepMillis * (1 << retryTimes); - try { - this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); - Thread.sleep(sleepMillis); - } catch (InterruptedException e1) { - throw new RuntimeException(e1); - } - } else { - throw e; - } - } - } while (retryTimes++ < this.maxRetryTimes); - - this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); - throw new RuntimeException("微信服务端异常,超出重试次数"); - } - - public synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { - if (uri.contains("access_token=")) { - throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); - } - String accessToken = getAccessToken(false); - - String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken; - - try { - T result = executor.execute(uriWithAccessToken, data); - this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); - return result; - } catch (WxErrorException e) { - WxError error = e.getError(); - /* - * 发生以下情况时尝试刷新access_token - * 40001 获取access_token时AppSecret错误,或者access_token无效 - * 42001 access_token超时 - * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 - */ - if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { - // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token - this.getWxMpConfigStorage().expireAccessToken(); - if (this.getWxMpConfigStorage().autoRefreshToken()) { - return this.execute(executor, uri, data); - } - } - - if (error.getErrorCode() != 0) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); - throw new WxErrorException(error, e); - } - return null; - } catch (IOException e) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); - throw new RuntimeException(e); - } - } - - @Override - public WxMpConfigStorage getWxMpConfigStorage() { - return this.wxMpConfigStorage; - } - - @Override - public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { - this.wxMpConfigStorage = wxConfigProvider; - this.initHttp(); - } - - @Override - public void setRetrySleepMillis(int retrySleepMillis) { - this.retrySleepMillis = retrySleepMillis; - } - - @Override - public void setMaxRetryTimes(int maxRetryTimes) { - this.maxRetryTimes = maxRetryTimes; - } - - @Override - public WxMpKefuService getKefuService() { - return this.kefuService; - } - - @Override - public WxMpMaterialService getMaterialService() { - return this.materialService; - } - - @Override - public WxMpMenuService getMenuService() { - return this.menuService; - } - - @Override - public WxMpUserService getUserService() { - return this.userService; - } - - @Override - public WxMpUserTagService getUserTagService() { - return this.tagService; - } - - @Override - public WxMpQrcodeService getQrcodeService() { - return this.qrCodeService; - } - - @Override - public WxMpCardService getCardService() { - return this.cardService; - } - - @Override - public WxMpDataCubeService getDataCubeService() { - return this.dataCubeService; - } - - @Override - public WxMpUserBlacklistService getBlackListService() { - return this.blackListService; - } - - @Override - public WxMpStoreService getStoreService() { - return this.storeService; - } - - @Override - public WxMpTemplateMsgService getTemplateMsgService() { - return this.templateMsgService; - } - - @Override - public WxMpDeviceService getDeviceService() { - return this.deviceService; - } - - @Override - public WxMpShakeService getShakeService() { - return this.shakeService; - } - - @Override - public WxMpMemberCardService getMemberCardService() { - return this.memberCardService; - } - - @Override - public RequestHttp getRequestHttp() { - return this; - } - - @Override - public WxMpMassMessageService getMassMessageService() { - return this.massMessageService; - } - - @Override - public void setKefuService(WxMpKefuService kefuService) { - this.kefuService = kefuService; - } - - @Override - public void setMaterialService(WxMpMaterialService materialService) { - this.materialService = materialService; - } - - @Override - public void setMenuService(WxMpMenuService menuService) { - this.menuService = menuService; - } - - @Override - public void setUserService(WxMpUserService userService) { - this.userService = userService; - } - - @Override - public void setTagService(WxMpUserTagService tagService) { - this.tagService = tagService; - } - - @Override - public void setQrCodeService(WxMpQrcodeService qrCodeService) { - this.qrCodeService = qrCodeService; - } - - @Override - public void setCardService(WxMpCardService cardService) { - this.cardService = cardService; - } - - @Override - public void setStoreService(WxMpStoreService storeService) { - this.storeService = storeService; - } - - @Override - public void setDataCubeService(WxMpDataCubeService dataCubeService) { - this.dataCubeService = dataCubeService; - } - - @Override - public void setBlackListService(WxMpUserBlacklistService blackListService) { - this.blackListService = blackListService; - } - - @Override - public void setTemplateMsgService(WxMpTemplateMsgService templateMsgService) { - this.templateMsgService = templateMsgService; - } - - @Override - public void setDeviceService(WxMpDeviceService deviceService) { - this.deviceService = deviceService; - } - - @Override - public void setShakeService(WxMpShakeService shakeService) { - this.shakeService = shakeService; - } - - @Override - public void setMemberCardService(WxMpMemberCardService memberCardService) { - this.memberCardService = memberCardService; - } - - @Override - public void setMassMessageService(WxMpMassMessageService massMessageService) { - this.massMessageService = massMessageService; - } -} +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.session.StandardSessionManager; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.common.util.RandomUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; +import me.chanjar.weixin.common.util.http.*; +import me.chanjar.weixin.mp.api.*; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.*; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.concurrent.locks.Lock; + +public abstract class WxMpServiceAbstractImpl implements WxMpService, RequestHttp { + + private static final JsonParser JSON_PARSER = new JsonParser(); + + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + protected WxSessionManager sessionManager = new StandardSessionManager(); + protected WxMpConfigStorage wxMpConfigStorage; + private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); + private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); + private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); + private WxMpUserService userService = new WxMpUserServiceImpl(this); + private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this); + private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); + private WxMpCardService cardService = new WxMpCardServiceImpl(this); + private WxMpStoreService storeService = new WxMpStoreServiceImpl(this); + private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); + private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); + private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); + private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); + private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this); + private WxMpMemberCardService memberCardService = new WxMpMemberCardServiceImpl(this); + private WxMpMassMessageService massMessageService = new WxMpMassMessageServiceImpl(this); + + private int retrySleepMillis = 1000; + private int maxRetryTimes = 5; + + + @Override + public boolean checkSignature(String timestamp, String nonce, String signature) { + try { + return SHA1.gen(this.getWxMpConfigStorage().getToken(), timestamp, nonce) + .equals(signature); + } catch (Exception e) { + this.log.error("Checking signature failed, and the reason is :" + e.getMessage()); + return false; + } + } + + @Override + public String getJsapiTicket() throws WxErrorException { + return getJsapiTicket(false); + } + + @Override + public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { + Lock lock = this.getWxMpConfigStorage().getJsapiTicketLock(); + try { + lock.lock(); + if (forceRefresh) { + this.getWxMpConfigStorage().expireJsapiTicket(); + } + + if (this.getWxMpConfigStorage().isJsapiTicketExpired()) { + String responseContent = execute(SimpleGetRequestExecutor.create(this), WxMpService.GET_JSAPI_TICKET_URL, null); + JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); + JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); + String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); + int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); + this.getWxMpConfigStorage().updateJsapiTicket(jsapiTicket, expiresInSeconds); + } + } finally { + lock.unlock(); + } + return this.getWxMpConfigStorage().getJsapiTicket(); + } + + @Override + public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { + long timestamp = System.currentTimeMillis() / 1000; + String noncestr = RandomUtils.getRandomStr(); + String jsapiTicket = getJsapiTicket(false); + String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, + "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); + WxJsapiSignature jsapiSignature = new WxJsapiSignature(); + jsapiSignature.setAppId(this.getWxMpConfigStorage().getAppId()); + jsapiSignature.setTimestamp(timestamp); + jsapiSignature.setNonceStr(noncestr); + jsapiSignature.setUrl(url); + jsapiSignature.setSignature(signature); + return jsapiSignature; + } + + @Override + public String getAccessToken() throws WxErrorException { + return getAccessToken(false); + } + + @Override + public String shortUrl(String long_url) throws WxErrorException { + JsonObject o = new JsonObject(); + o.addProperty("action", "long2short"); + o.addProperty("long_url", long_url); + String responseContent = this.post(WxMpService.SHORTURL_API_URL, o.toString()); + JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); + return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); + } + + @Override + public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException { + String responseContent = this.post(WxMpService.SEMANTIC_SEMPROXY_SEARCH_URL, semanticQuery.toJson()); + return WxMpSemanticQueryResult.fromJson(responseContent); + } + + @Override + public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) { + return String.format(WxMpService.CONNECT_OAUTH2_AUTHORIZE_URL, + this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); + } + + @Override + public String buildQrConnectUrl(String redirectURI, String scope, String state) { + return String.format(WxMpService.QRCONNECT_URL, + this.getWxMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state)); + } + + private WxMpOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException { + try { + RequestExecutor executor = SimpleGetRequestExecutor.create(this); + String responseText = executor.execute(url, null); + return WxMpOAuth2AccessToken.fromJson(responseText); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException { + String url = String.format(WxMpService.OAUTH2_ACCESS_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret(), code); + return this.getOAuth2AccessToken(url); + } + + @Override + public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException { + String url = String.format(WxMpService.OAUTH2_REFRESH_TOKEN_URL, this.getWxMpConfigStorage().getAppId(), refreshToken); + return this.getOAuth2AccessToken(url); + } + + @Override + public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException { + if (lang == null) { + lang = "zh_CN"; + } + + String url = String.format(WxMpService.OAUTH2_USERINFO_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId(), lang); + + try { + RequestExecutor executor = SimpleGetRequestExecutor.create(this); + String responseText = executor.execute(url, null); + return WxMpUser.fromJson(responseText); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken) { + String url = String.format(WxMpService.OAUTH2_VALIDATE_TOKEN_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId()); + + try { + SimpleGetRequestExecutor.create(this).execute(url, null); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (WxErrorException e) { + return false; + } + return true; + } + + @Override + public String[] getCallbackIP() throws WxErrorException { + String responseContent = this.get(WxMpService.GET_CALLBACK_IP_URL, null); + JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); + JsonArray ipList = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray(); + String[] ipArray = new String[ipList.size()]; + for (int i = 0; i < ipList.size(); i++) { + ipArray[i] = ipList.get(i).getAsString(); + } + return ipArray; + } + + @Override + public WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException { + return WxMpCurrentAutoReplyInfo.fromJson(this.get(GET_CURRENT_AUTOREPLY_INFO_URL, null)); + } + + @Override + public String get(String url, String queryParam) throws WxErrorException { + return execute(SimpleGetRequestExecutor.create(this), url, queryParam); + } + + @Override + public String post(String url, String postData) throws WxErrorException { + return execute(SimplePostRequestExecutor.create(this), url, postData); + } + + /** + * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 + */ + public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { + int retryTimes = 0; + do { + try { + return this.executeInternal(executor, uri, data); + } catch (WxErrorException e) { + if (retryTimes + 1 > this.maxRetryTimes) { + this.log.warn("重试达到最大次数【{}】", maxRetryTimes); + //最后一次重试失败后,直接抛出异常,不再等待 + throw new RuntimeException("微信服务端异常,超出重试次数"); + } + + WxError error = e.getError(); + // -1 系统繁忙, 1000ms后重试 + if (error.getErrorCode() == -1) { + int sleepMillis = this.retrySleepMillis * (1 << retryTimes); + try { + this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); + Thread.sleep(sleepMillis); + } catch (InterruptedException e1) { + throw new RuntimeException(e1); + } + } else { + throw e; + } + } + } while (retryTimes++ < this.maxRetryTimes); + + this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); + throw new RuntimeException("微信服务端异常,超出重试次数"); + } + + public synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + if (uri.contains("access_token=")) { + throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); + } + String accessToken = getAccessToken(false); + + String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken; + + try { + T result = executor.execute(uriWithAccessToken, data); + this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); + return result; + } catch (WxErrorException e) { + WxError error = e.getError(); + /* + * 发生以下情况时尝试刷新access_token + * 40001 获取access_token时AppSecret错误,或者access_token无效 + * 42001 access_token超时 + * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 + */ + if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { + // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token + this.getWxMpConfigStorage().expireAccessToken(); + if (this.getWxMpConfigStorage().autoRefreshToken()) { + return this.execute(executor, uri, data); + } + } + + if (error.getErrorCode() != 0) { + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); + throw new WxErrorException(error, e); + } + return null; + } catch (IOException e) { + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); + throw new RuntimeException(e); + } + } + + @Override + public WxMpConfigStorage getWxMpConfigStorage() { + return this.wxMpConfigStorage; + } + + @Override + public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { + this.wxMpConfigStorage = wxConfigProvider; + this.initHttp(); + } + + @Override + public void setRetrySleepMillis(int retrySleepMillis) { + this.retrySleepMillis = retrySleepMillis; + } + + @Override + public void setMaxRetryTimes(int maxRetryTimes) { + this.maxRetryTimes = maxRetryTimes; + } + + @Override + public WxMpKefuService getKefuService() { + return this.kefuService; + } + + @Override + public WxMpMaterialService getMaterialService() { + return this.materialService; + } + + @Override + public WxMpMenuService getMenuService() { + return this.menuService; + } + + @Override + public WxMpUserService getUserService() { + return this.userService; + } + + @Override + public WxMpUserTagService getUserTagService() { + return this.tagService; + } + + @Override + public WxMpQrcodeService getQrcodeService() { + return this.qrCodeService; + } + + @Override + public WxMpCardService getCardService() { + return this.cardService; + } + + @Override + public WxMpDataCubeService getDataCubeService() { + return this.dataCubeService; + } + + @Override + public WxMpUserBlacklistService getBlackListService() { + return this.blackListService; + } + + @Override + public WxMpStoreService getStoreService() { + return this.storeService; + } + + @Override + public WxMpTemplateMsgService getTemplateMsgService() { + return this.templateMsgService; + } + + @Override + public WxMpDeviceService getDeviceService() { + return this.deviceService; + } + + @Override + public WxMpShakeService getShakeService() { + return this.shakeService; + } + + @Override + public WxMpMemberCardService getMemberCardService() { + return this.memberCardService; + } + + @Override + public RequestHttp getRequestHttp() { + return this; + } + + @Override + public WxMpMassMessageService getMassMessageService() { + return this.massMessageService; + } + + @Override + public void setKefuService(WxMpKefuService kefuService) { + this.kefuService = kefuService; + } + + @Override + public void setMaterialService(WxMpMaterialService materialService) { + this.materialService = materialService; + } + + @Override + public void setMenuService(WxMpMenuService menuService) { + this.menuService = menuService; + } + + @Override + public void setUserService(WxMpUserService userService) { + this.userService = userService; + } + + @Override + public void setTagService(WxMpUserTagService tagService) { + this.tagService = tagService; + } + + @Override + public void setQrCodeService(WxMpQrcodeService qrCodeService) { + this.qrCodeService = qrCodeService; + } + + @Override + public void setCardService(WxMpCardService cardService) { + this.cardService = cardService; + } + + @Override + public void setStoreService(WxMpStoreService storeService) { + this.storeService = storeService; + } + + @Override + public void setDataCubeService(WxMpDataCubeService dataCubeService) { + this.dataCubeService = dataCubeService; + } + + @Override + public void setBlackListService(WxMpUserBlacklistService blackListService) { + this.blackListService = blackListService; + } + + @Override + public void setTemplateMsgService(WxMpTemplateMsgService templateMsgService) { + this.templateMsgService = templateMsgService; + } + + @Override + public void setDeviceService(WxMpDeviceService deviceService) { + this.deviceService = deviceService; + } + + @Override + public void setShakeService(WxMpShakeService shakeService) { + this.shakeService = shakeService; + } + + @Override + public void setMemberCardService(WxMpMemberCardService memberCardService) { + this.memberCardService = memberCardService; + } + + @Override + public void setMassMessageService(WxMpMassMessageService massMessageService) { + this.massMessageService = massMessageService; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java index 0aa9e8eaae..b5135cebcb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java @@ -1,93 +1,93 @@ -package me.chanjar.weixin.mp.api.impl; - -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.HttpType; -import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.mp.api.WxMpService; -import okhttp3.*; - -import java.io.IOException; -import java.util.concurrent.locks.Lock; - -public class WxMpServiceOkHttpImpl extends WxMpServiceAbstractImpl { - private OkHttpClient httpClient; - private OkHttpProxyInfo httpProxy; - - @Override - public OkHttpClient getRequestHttpClient() { - return httpClient; - } - - @Override - public OkHttpProxyInfo getRequestHttpProxy() { - return httpProxy; - } - - @Override - public HttpType getRequestType() { - return HttpType.OK_HTTP; - } - - @Override - public String getAccessToken(boolean forceRefresh) throws WxErrorException { - this.log.debug("WxMpServiceOkHttpImpl is running"); - Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); - try { - lock.lock(); - - if (this.getWxMpConfigStorage().isAccessTokenExpired() || forceRefresh) { - String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL, - this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret()); - - Request request = new Request.Builder().url(url).get().build(); - Response response = getRequestHttpClient().newCall(request).execute(); - String resultContent = response.body().string(); - WxError error = WxError.fromJson(resultContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); - this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), - accessToken.getExpiresIn()); - } - } catch (IOException e) { - this.log.error(e.getMessage(), e); - } finally { - lock.unlock(); - } - return this.getWxMpConfigStorage().getAccessToken(); - } - - @Override - public void initHttp() { - this.log.debug("WxMpServiceOkHttpImpl initHttp"); - - //设置代理 - if (wxMpConfigStorage.getHttpProxyHost() != null && wxMpConfigStorage.getHttpProxyPort() > 0) { - httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(), - wxMpConfigStorage.getHttpProxyPort(), - wxMpConfigStorage.getHttpProxyUsername(), - wxMpConfigStorage.getHttpProxyPassword()); - } - - OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); - if (httpProxy != null) { - clientBuilder.proxy(getRequestHttpProxy().getProxy()); - - //设置授权 - clientBuilder.authenticator(new Authenticator() { - @Override - public Request authenticate(Route route, Response response) throws IOException { - String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword()); - return response.request().newBuilder() - .header("Authorization", credential) - .build(); - } - }); - } - httpClient = clientBuilder.build(); - } - -} +package me.chanjar.weixin.mp.api.impl; + +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.HttpType; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.mp.api.WxMpService; +import okhttp3.*; + +import java.io.IOException; +import java.util.concurrent.locks.Lock; + +public class WxMpServiceOkHttpImpl extends WxMpServiceAbstractImpl { + private OkHttpClient httpClient; + private OkHttpProxyInfo httpProxy; + + @Override + public OkHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public OkHttpProxyInfo getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpType getRequestType() { + return HttpType.OK_HTTP; + } + + @Override + public String getAccessToken(boolean forceRefresh) throws WxErrorException { + this.log.debug("WxMpServiceOkHttpImpl is running"); + Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); + try { + lock.lock(); + + if (this.getWxMpConfigStorage().isAccessTokenExpired() || forceRefresh) { + String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL, + this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret()); + + Request request = new Request.Builder().url(url).get().build(); + Response response = getRequestHttpClient().newCall(request).execute(); + String resultContent = response.body().string(); + WxError error = WxError.fromJson(resultContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); + this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), + accessToken.getExpiresIn()); + } + } catch (IOException e) { + this.log.error(e.getMessage(), e); + } finally { + lock.unlock(); + } + return this.getWxMpConfigStorage().getAccessToken(); + } + + @Override + public void initHttp() { + this.log.debug("WxMpServiceOkHttpImpl initHttp"); + + //设置代理 + if (wxMpConfigStorage.getHttpProxyHost() != null && wxMpConfigStorage.getHttpProxyPort() > 0) { + httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(), + wxMpConfigStorage.getHttpProxyPort(), + wxMpConfigStorage.getHttpProxyUsername(), + wxMpConfigStorage.getHttpProxyPassword()); + } + + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + if (httpProxy != null) { + clientBuilder.proxy(getRequestHttpProxy().getProxy()); + + //设置授权 + clientBuilder.authenticator(new Authenticator() { + @Override + public Request authenticate(Route route, Response response) throws IOException { + String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword()); + return response.request().newBuilder() + .header("Authorization", credential) + .build(); + } + }); + } + httpClient = clientBuilder.build(); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java index f211c9f35c..2c90f70e2b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java @@ -1,66 +1,66 @@ -package me.chanjar.weixin.mp.api.impl; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.WxMpShakeService; -import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; -import me.chanjar.weixin.mp.bean.WxMpShakeQuery; -import me.chanjar.weixin.mp.bean.shake.*; - -/** - * Created by rememberber on 2017/6/5. - * - * @author rememberber - */ -public class WxMpShakeServiceImpl implements WxMpShakeService { - - private WxMpService wxMpService; - - public WxMpShakeServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; - } - - /** - *
-   * 获取设备及用户信息
- * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 - * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963 - * http请求方式: POST(请使用https协议) - * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE - *
- * - * @param wxMpShakeQuery 查询参数 - */ - @Override - public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException { - String url = "https://api.weixin.qq.com/shakearound/user/getshakeinfo"; - String postData = wxMpShakeQuery.toJsonString(); - String responseContent = this.wxMpService.post(url, postData); - return WxMpShakeInfoResult.fromJson(responseContent); - } - - @Override - public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException { - String url = "https://api.weixin.qq.com/shakearound/page/add"; - String postData = shakeAroundPageAddQuery.toJsonString(); - String responseContent = this.wxMpService.post(url, postData); - return WxMpShakeAroundPageAddResult.fromJson(responseContent); - } - - @Override - public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException { - String url = "https://api.weixin.qq.com/shakearound/device/bindpage"; - String postData = shakeAroundDeviceBindPageQuery.toJsonString(); - String responseContent = this.wxMpService.post(url, postData); - return WxError.fromJson(responseContent); - } - - @Override - public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException { - String url = "https://api.weixin.qq.com/shakearound/relation/search"; - String postData = shakeAroundRelationSearchQuery.toJsonString(); - String responseContent = this.wxMpService.post(url, postData); - return WxMpShakeAroundRelationSearchResult.fromJson(responseContent); - } -} +package me.chanjar.weixin.mp.api.impl; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpShakeService; +import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; +import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; + +/** + * Created by rememberber on 2017/6/5. + * + * @author rememberber + */ +public class WxMpShakeServiceImpl implements WxMpShakeService { + + private WxMpService wxMpService; + + public WxMpShakeServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + /** + *
+   * 获取设备及用户信息
+ * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 + * 详情请见: https://mp.weixin.qq.com/wiki?action=doc&id=mp1443447963 + * http请求方式: POST(请使用https协议) + * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE + *
+ * + * @param wxMpShakeQuery 查询参数 + */ + @Override + public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/user/getshakeinfo"; + String postData = wxMpShakeQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeInfoResult.fromJson(responseContent); + } + + @Override + public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/page/add"; + String postData = shakeAroundPageAddQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundPageAddResult.fromJson(responseContent); + } + + @Override + public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/device/bindpage"; + String postData = shakeAroundDeviceBindPageQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxError.fromJson(responseContent); + } + + @Override + public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/relation/search"; + String postData = shakeAroundRelationSearchQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundRelationSearchResult.fromJson(responseContent); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java index 7c724537fb..3901c61fbc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java @@ -1,123 +1,123 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * 图文分析数据接口返回结果对象 - *

- * Created by Binary Wang on 2016/8/24. - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class WxDataCubeArticleResult extends WxDataCubeBaseResult { - private static final long serialVersionUID = -9222452497954511765L; - - /** - * ref_hour - * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 - */ - @SerializedName("ref_hour") - private Integer refHour; - - /** - * msgid - * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id) - * 和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index, - * 假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 - */ - @SerializedName("msgid") - private String msgId; - - /** - * title - * 图文消息的标题 - */ - @SerializedName("title") - private String title; - - /** - * int_page_read_user - * 图文页(点击群发图文卡片进入的页面)的阅读人数 - */ - @SerializedName("int_page_read_user") - private Integer intPageReadUser; - - /** - * int_page_read_count - * 图文页的阅读次数 - */ - @SerializedName("int_page_read_count") - private Integer intPageReadCount; - - /** - * ori_page_read_user - * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 - */ - @SerializedName("ori_page_read_user") - private Integer oriPageReadUser; - - /** - * ori_page_read_count - * 原文页的阅读次数 - */ - @SerializedName("ori_page_read_count") - private Integer oriPageReadCount; - - /** - * share_scene - * 分享的场景 1代表好友转发 2代表朋友圈 3代表腾讯微博 255代表其他 - */ - @SerializedName("share_scene") - private Integer shareScene; - - /** - * share_user - * 分享的人数 - */ - @SerializedName("share_user") - private Integer shareUser; - - /** - * share_count - * 分享的次数 - */ - @SerializedName("share_count") - private Integer shareCount; - - /** - * add_to_fav_user - * 收藏的人数 - */ - @SerializedName("add_to_fav_user") - private Integer addToFavUser; - - /** - * add_to_fav_count - * 收藏的次数 - */ - @SerializedName("add_to_fav_count") - private Integer addToFavCount; - - /** - * user_source - * 在获取图文阅读分时数据时才有该字段,代表用户从哪里进入来阅读该图文。0:会话;1.好友;2.朋友圈;3.腾讯微博;4.历史消息页;5.其他 - */ - @SerializedName("user_source") - private Integer userSource; - - public static List fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson( - JSON_PARSER.parse(json).getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * 图文分析数据接口返回结果对象 + *

+ * Created by Binary Wang on 2016/8/24. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxDataCubeArticleResult extends WxDataCubeBaseResult { + private static final long serialVersionUID = -9222452497954511765L; + + /** + * ref_hour + * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 + */ + @SerializedName("ref_hour") + private Integer refHour; + + /** + * msgid + * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id) + * 和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index, + * 假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 + */ + @SerializedName("msgid") + private String msgId; + + /** + * title + * 图文消息的标题 + */ + @SerializedName("title") + private String title; + + /** + * int_page_read_user + * 图文页(点击群发图文卡片进入的页面)的阅读人数 + */ + @SerializedName("int_page_read_user") + private Integer intPageReadUser; + + /** + * int_page_read_count + * 图文页的阅读次数 + */ + @SerializedName("int_page_read_count") + private Integer intPageReadCount; + + /** + * ori_page_read_user + * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 + */ + @SerializedName("ori_page_read_user") + private Integer oriPageReadUser; + + /** + * ori_page_read_count + * 原文页的阅读次数 + */ + @SerializedName("ori_page_read_count") + private Integer oriPageReadCount; + + /** + * share_scene + * 分享的场景 1代表好友转发 2代表朋友圈 3代表腾讯微博 255代表其他 + */ + @SerializedName("share_scene") + private Integer shareScene; + + /** + * share_user + * 分享的人数 + */ + @SerializedName("share_user") + private Integer shareUser; + + /** + * share_count + * 分享的次数 + */ + @SerializedName("share_count") + private Integer shareCount; + + /** + * add_to_fav_user + * 收藏的人数 + */ + @SerializedName("add_to_fav_user") + private Integer addToFavUser; + + /** + * add_to_fav_count + * 收藏的次数 + */ + @SerializedName("add_to_fav_count") + private Integer addToFavCount; + + /** + * user_source + * 在获取图文阅读分时数据时才有该字段,代表用户从哪里进入来阅读该图文。0:会话;1.好友;2.朋友圈;3.腾讯微博;4.历史消息页;5.其他 + */ + @SerializedName("user_source") + private Integer userSource; + + public static List fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java index 6c63e83231..bef0e66d15 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java @@ -1,50 +1,50 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * 图文分析数据接口返回结果对象. - * Created by Binary Wang on 2016/8/24. - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class WxDataCubeArticleTotal extends WxDataCubeBaseResult { - private static final long serialVersionUID = -7634365687303052699L; - - /** - * msgid. - * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id)和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index,假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 - */ - @SerializedName("msgid") - private String msgId; - - /** - * title. - * 图文消息的标题 - */ - @SerializedName("title") - private String title; - - /** - * details. - * 详细信息 - */ - @SerializedName("details") - private List details; - - public static List fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson( - JSON_PARSER.parse(json).getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * 图文分析数据接口返回结果对象. + * Created by Binary Wang on 2016/8/24. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxDataCubeArticleTotal extends WxDataCubeBaseResult { + private static final long serialVersionUID = -7634365687303052699L; + + /** + * msgid. + * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id)和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index,假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 + */ + @SerializedName("msgid") + private String msgId; + + /** + * title. + * 图文消息的标题 + */ + @SerializedName("title") + private String title; + + /** + * details. + * 详细信息 + */ + @SerializedName("details") + private List details; + + public static List fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java index 8af64015b7..df86ab4e15 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java @@ -1,35 +1,35 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.JsonParser; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; - -/** - *

- *  统计接口的共用属性类.
- *  Created by Binary Wang on 2016/8/25.
- * 
- * - * @author Binary Wang - */ -@Data -public abstract class WxDataCubeBaseResult implements Serializable { - private static final long serialVersionUID = 8780389911053297600L; - protected static final JsonParser JSON_PARSER = new JsonParser(); - - /** - * ref_date. - * 数据的日期,需在begin_date和end_date之间 - */ - @SerializedName("ref_date") - private String refDate; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.ToStringUtils; + +import java.io.Serializable; + +/** + *
+ *  统计接口的共用属性类.
+ *  Created by Binary Wang on 2016/8/25.
+ * 
+ * + * @author Binary Wang + */ +@Data +public abstract class WxDataCubeBaseResult implements Serializable { + private static final long serialVersionUID = 8780389911053297600L; + protected static final JsonParser JSON_PARSER = new JsonParser(); + + /** + * ref_date. + * 数据的日期,需在begin_date和end_date之间 + */ + @SerializedName("ref_date") + private String refDate; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java index cf77b28575..b151c0089f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java @@ -1,65 +1,65 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * 接口分析数据接口返回结果对象 - *

- * Created by Binary Wang on 2016/8/30. - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult { - private static final long serialVersionUID = 597734329161281398L; - - /** - * ref_hour - * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 - */ - @SerializedName("ref_hour") - private Integer refHour; - - /** - * callback_count - * 通过服务器配置地址获得消息后,被动回复用户消息的次数 - */ - @SerializedName("callback_count") - private Integer callbackCount; - - /** - * fail_count - * 上述动作的失败次数 - */ - @SerializedName("fail_count") - private Integer failCount; - - /** - * total_time_cost - * 总耗时,除以callback_count即为平均耗时 - */ - @SerializedName("total_time_cost") - private Integer totalTimeCost; - - /** - * max_time_cost - * 最大耗时 - */ - @SerializedName("max_time_cost") - private Integer maxTimeCost; - - public static List fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson( - JSON_PARSER.parse(json).getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * 接口分析数据接口返回结果对象 + *

+ * Created by Binary Wang on 2016/8/30. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult { + private static final long serialVersionUID = 597734329161281398L; + + /** + * ref_hour + * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 + */ + @SerializedName("ref_hour") + private Integer refHour; + + /** + * callback_count + * 通过服务器配置地址获得消息后,被动回复用户消息的次数 + */ + @SerializedName("callback_count") + private Integer callbackCount; + + /** + * fail_count + * 上述动作的失败次数 + */ + @SerializedName("fail_count") + private Integer failCount; + + /** + * total_time_cost + * 总耗时,除以callback_count即为平均耗时 + */ + @SerializedName("total_time_cost") + private Integer totalTimeCost; + + /** + * max_time_cost + * 最大耗时 + */ + @SerializedName("max_time_cost") + private Integer maxTimeCost; + + public static List fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java index a786605c9e..1e7e1f58c2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java @@ -1,78 +1,78 @@ -package me.chanjar.weixin.mp.bean.datacube; - -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * 消息分析数据接口返回结果对象. - * Created by Binary Wang on 2016/8/29. - * - * @author Binary Wang - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class WxDataCubeMsgResult extends WxDataCubeBaseResult { - private static final long serialVersionUID = 6932121822150573659L; - - /** - * ref_hour. - * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 - */ - @SerializedName("ref_hour") - private Integer refHour; - - /** - * msg_type. - * 消息类型,代表含义如下:1代表文字 2代表图片 3代表语音 4代表视频 6代表第三方应用消息(链接消息) - */ - @SerializedName("msg_type") - private Integer msgType; - - /** - * msg_user. - * 上行发送了(向公众号发送了)消息的用户数 - */ - @SerializedName("msg_user") - private Integer msgUser; - - /** - * msg_count. - * 上行发送了消息的消息总数 - */ - @SerializedName("msg_count") - private Integer msgCount; - - /** - * count_interval. - * 当日发送消息量分布的区间,0代表 “0”,1代表“1-5”,2代表“6-10”,3代表“10次以上” - */ - @SerializedName("count_interval") - private Integer countInterval; - - /** - * int_page_read_count - * 图文页的阅读次数 - */ - @SerializedName("int_page_read_count") - private Integer intPageReadCount; - - /** - * ori_page_read_user. - * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 - */ - @SerializedName("ori_page_read_user") - private Integer oriPageReadUser; - - public static List fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson( - JSON_PARSER.parse(json).getAsJsonObject().get("list"), - new TypeToken>() { - }.getType()); - } - -} +package me.chanjar.weixin.mp.bean.datacube; + +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * 消息分析数据接口返回结果对象. + * Created by Binary Wang on 2016/8/29. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxDataCubeMsgResult extends WxDataCubeBaseResult { + private static final long serialVersionUID = 6932121822150573659L; + + /** + * ref_hour. + * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 + */ + @SerializedName("ref_hour") + private Integer refHour; + + /** + * msg_type. + * 消息类型,代表含义如下:1代表文字 2代表图片 3代表语音 4代表视频 6代表第三方应用消息(链接消息) + */ + @SerializedName("msg_type") + private Integer msgType; + + /** + * msg_user. + * 上行发送了(向公众号发送了)消息的用户数 + */ + @SerializedName("msg_user") + private Integer msgUser; + + /** + * msg_count. + * 上行发送了消息的消息总数 + */ + @SerializedName("msg_count") + private Integer msgCount; + + /** + * count_interval. + * 当日发送消息量分布的区间,0代表 “0”,1代表“1-5”,2代表“6-10”,3代表“10次以上” + */ + @SerializedName("count_interval") + private Integer countInterval; + + /** + * int_page_read_count + * 图文页的阅读次数 + */ + @SerializedName("int_page_read_count") + private Integer intPageReadCount; + + /** + * ori_page_read_user. + * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 + */ + @SerializedName("ori_page_read_user") + private Integer oriPageReadUser; + + public static List fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java index 207c1921b8..5c66b0cd60 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java @@ -1,31 +1,31 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class BaseResp extends AbstractDeviceBean { - private static final long serialVersionUID = 4252655933699659073L; - - @SerializedName("base_info") - private BaseInfo baseInfo; - @SerializedName("errcode") - private Integer errCode; - @SerializedName("errmsg") - private String errMsg; - - @Data - private class BaseInfo { - @SerializedName("device_type") - private String deviceType; - - @SerializedName("device_id") - private String deviceId; - } -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class BaseResp extends AbstractDeviceBean { + private static final long serialVersionUID = 4252655933699659073L; + + @SerializedName("base_info") + private BaseInfo baseInfo; + @SerializedName("errcode") + private Integer errCode; + @SerializedName("errmsg") + private String errMsg; + + @Data + private class BaseInfo { + @SerializedName("device_type") + private String deviceType; + + @SerializedName("device_id") + private String deviceId; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java index de9dccd429..601f848223 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java @@ -1,21 +1,21 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class RespMsg extends AbstractDeviceBean { - private static final long serialVersionUID = -4241272701707684136L; - - @SerializedName("ret_code") - private Integer retCode; - @SerializedName("error_info") - private String errorInfo; -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class RespMsg extends AbstractDeviceBean { + private static final long serialVersionUID = -4241272701707684136L; + + @SerializedName("ret_code") + private Integer retCode; + @SerializedName("error_info") + private String errorInfo; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java index 289816a782..f2b35da5ea 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java @@ -1,29 +1,29 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -/** - * - * @author keungtung. - * @date 14/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class TransMsgResp extends AbstractDeviceBean { - private static final long serialVersionUID = 5386954916622816491L; - - private Integer ret; - @SerializedName("ret_info") - private String retInfo; - @SerializedName("errcode") - private Integer errCode; - @SerializedName("errmsg") - private String errMsg; - - public static TransMsgResp fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, TransMsgResp.class); - } -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * + * @author keungtung. + * @date 14/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class TransMsgResp extends AbstractDeviceBean { + private static final long serialVersionUID = 5386954916622816491L; + + private Integer ret; + @SerializedName("ret_info") + private String retInfo; + @SerializedName("errcode") + private Integer errCode; + @SerializedName("errmsg") + private String errMsg; + + public static TransMsgResp fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, TransMsgResp.class); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java index ed02aedc70..5e00c4faea 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java @@ -1,32 +1,32 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -/** - * @author keungtung - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceAuthorize extends AbstractDeviceBean { - private static final long serialVersionUID = 8786321356569903887L; - - @SerializedName("device_num") - private String deviceNum; - @SerializedName("op_type") - private String opType; - @SerializedName("product_id") - private String productId; - @SerializedName("device_list") - private List deviceList = new LinkedList<>(); - - public void addDevice(WxDevice... devices) { - this.deviceList.addAll(Arrays.asList(devices)); - } -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * @author keungtung + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceAuthorize extends AbstractDeviceBean { + private static final long serialVersionUID = 8786321356569903887L; + + @SerializedName("device_num") + private String deviceNum; + @SerializedName("op_type") + private String opType; + @SerializedName("product_id") + private String productId; + @SerializedName("device_list") + private List deviceList = new LinkedList<>(); + + public void addDevice(WxDevice... devices) { + this.deviceList.addAll(Arrays.asList(devices)); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java index d0fe937ee7..9608452ce1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.device; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.util.List; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceAuthorizeResult extends AbstractDeviceBean { - private static final long serialVersionUID = 9105294570912249811L; - - private List resp; - - public static WxDeviceAuthorizeResult fromJson(String response) { - return WxGsonBuilder.create().fromJson(response, WxDeviceAuthorizeResult.class); - } - -} +package me.chanjar.weixin.mp.bean.device; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.util.List; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceAuthorizeResult extends AbstractDeviceBean { + private static final long serialVersionUID = 9105294570912249811L; + + private List resp; + + public static WxDeviceAuthorizeResult fromJson(String response) { + return WxGsonBuilder.create().fromJson(response, WxDeviceAuthorizeResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java index 94d3e938c0..aeb7f819ce 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceBind extends AbstractDeviceBean { - private static final long serialVersionUID = 467559769037590880L; - - private String ticket; - @SerializedName("device_id") - private String deviceId; - @SerializedName("openid") - private String openId; - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceBind extends AbstractDeviceBean { + private static final long serialVersionUID = 467559769037590880L; + + private String ticket; + @SerializedName("device_id") + private String deviceId; + @SerializedName("openid") + private String openId; + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java index 5653863a45..ec032e8617 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java @@ -1,39 +1,39 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * @author keungtung. - * @date 16/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceBindDeviceResult extends AbstractDeviceBean { - private static final long serialVersionUID = 725870295905935355L; - - @SerializedName("resp_msg") - private RespMsg respMsg; - @SerializedName("openid") - private String openId; - @SerializedName("device_list") - private List devices; - - public static WxDeviceBindDeviceResult fromJson(String json) { - return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindDeviceResult.class); - } - - @Data - private class Device { - @SerializedName("device_type") - private String deviceType; - @SerializedName("device_id") - private String deviceId; - - } - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * @author keungtung. + * @date 16/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceBindDeviceResult extends AbstractDeviceBean { + private static final long serialVersionUID = 725870295905935355L; + + @SerializedName("resp_msg") + private RespMsg respMsg; + @SerializedName("openid") + private String openId; + @SerializedName("device_list") + private List devices; + + public static WxDeviceBindDeviceResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindDeviceResult.class); + } + + @Data + private class Device { + @SerializedName("device_type") + private String deviceType; + @SerializedName("device_id") + private String deviceId; + + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java index 67a0edf654..f6c702aa29 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceBindResult extends AbstractDeviceBean { - private static final long serialVersionUID = 4687725146279339359L; - - @SerializedName("base_resp") - private BaseResp baseResp; - - public static WxDeviceBindResult fromJson(String json) { - return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindResult.class); - } - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceBindResult extends AbstractDeviceBean { + private static final long serialVersionUID = 4687725146279339359L; + + @SerializedName("base_resp") + private BaseResp baseResp; + + public static WxDeviceBindResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java index 6cab2305d9..4128a9f82b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java @@ -1,29 +1,29 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.util.ToStringUtils; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceMsg extends AbstractDeviceBean { - private static final long serialVersionUID = -5567110858455277963L; - - @SerializedName("device_type") - private String deviceType; - @SerializedName("device_id") - private String deviceId; - @SerializedName("open_id") - private String openId; - private String content; - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.util.ToStringUtils; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceMsg extends AbstractDeviceBean { + private static final long serialVersionUID = -5567110858455277963L; + + @SerializedName("device_type") + private String deviceType; + @SerializedName("device_id") + private String deviceId; + @SerializedName("open_id") + private String openId; + private String content; + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java index 5ab726c1a3..95cf2a94ff 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java @@ -1,32 +1,32 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.util.List; - -/** - * @author keungtung. - * @date 16/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceOpenIdResult extends AbstractDeviceBean { - private static final long serialVersionUID = 4980885167833836220L; - - @SerializedName("errcode") - private Integer errCode; - @SerializedName("errmsg") - private String errMsg; - @SerializedName("open_id") - private List openIds; - @SerializedName("resp_msg") - private RespMsg respMsg; - - public static WxDeviceOpenIdResult fromJson(String json) { - return WxMpGsonBuilder.create().fromJson(json, WxDeviceOpenIdResult.class); - } - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * @author keungtung. + * @date 16/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceOpenIdResult extends AbstractDeviceBean { + private static final long serialVersionUID = 4980885167833836220L; + + @SerializedName("errcode") + private Integer errCode; + @SerializedName("errmsg") + private String errMsg; + @SerializedName("open_id") + private List openIds; + @SerializedName("resp_msg") + private RespMsg respMsg; + + public static WxDeviceOpenIdResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxDeviceOpenIdResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java index c2ffb094b0..0e0d96f419 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java @@ -1,30 +1,30 @@ -package me.chanjar.weixin.mp.bean.device; - -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -/** - * @author keungtung. - * @date 10/12/2016 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class WxDeviceQrCodeResult extends AbstractDeviceBean { - private static final long serialVersionUID = -4312858303060918266L; - - @SerializedName("deviceid") - private String deviceId; - @SerializedName("qrticket") - private String qrTicket; - @SerializedName("devicelicence") - private String deviceLicence; - @SerializedName("base_resp") - private BaseResp baseResp; - - public static WxDeviceQrCodeResult fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxDeviceQrCodeResult.class); - } - -} +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * @author keungtung. + * @date 10/12/2016 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxDeviceQrCodeResult extends AbstractDeviceBean { + private static final long serialVersionUID = -4312858303060918266L; + + @SerializedName("deviceid") + private String deviceId; + @SerializedName("qrticket") + private String qrTicket; + @SerializedName("devicelicence") + private String deviceLicence; + @SerializedName("base_resp") + private BaseResp baseResp; + + public static WxDeviceQrCodeResult fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxDeviceQrCodeResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java index a913b6918c..dbb0ab90f9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutImageMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = -2684778597067990723L; - - @XStreamAlias("Image") - @XStreamConverter(value = XStreamMediaIdConverter.class) - private String mediaId; - - public WxMpXmlOutImageMessage() { - this.msgType = WxConsts.XmlMsgType.IMAGE; - } - -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutImageMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = -2684778597067990723L; + + @XStreamAlias("Image") + @XStreamConverter(value = XStreamMediaIdConverter.class) + private String mediaId; + + public WxMpXmlOutImageMessage() { + this.msgType = WxConsts.XmlMsgType.IMAGE; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java index 2b55cc241e..f7405600ef 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java @@ -1,58 +1,58 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = -4604402850905714772L; - - @XStreamAlias("Articles") - protected final List articles = new ArrayList<>(); - @XStreamAlias("ArticleCount") - protected int articleCount; - - public WxMpXmlOutNewsMessage() { - this.msgType = WxConsts.XmlMsgType.NEWS; - } - - public void addArticle(Item item) { - this.articles.add(item); - this.articleCount = this.articles.size(); - } - - @XStreamAlias("item") - @Data - public static class Item implements Serializable { - private static final long serialVersionUID = -4971456355028904754L; - - @XStreamAlias("Title") - @XStreamConverter(value = XStreamCDataConverter.class) - private String title; - - @XStreamAlias("Description") - @XStreamConverter(value = XStreamCDataConverter.class) - private String description; - - @XStreamAlias("PicUrl") - @XStreamConverter(value = XStreamCDataConverter.class) - private String picUrl; - - @XStreamAlias("Url") - @XStreamConverter(value = XStreamCDataConverter.class) - private String url; - - } - - -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = -4604402850905714772L; + + @XStreamAlias("Articles") + protected final List articles = new ArrayList<>(); + @XStreamAlias("ArticleCount") + protected int articleCount; + + public WxMpXmlOutNewsMessage() { + this.msgType = WxConsts.XmlMsgType.NEWS; + } + + public void addArticle(Item item) { + this.articles.add(item); + this.articleCount = this.articles.size(); + } + + @XStreamAlias("item") + @Data + public static class Item implements Serializable { + private static final long serialVersionUID = -4971456355028904754L; + + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @XStreamAlias("Description") + @XStreamConverter(value = XStreamCDataConverter.class) + private String description; + + @XStreamAlias("PicUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String picUrl; + + @XStreamAlias("Url") + @XStreamConverter(value = XStreamCDataConverter.class) + private String url; + + } + + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java index 6a3fd1f97c..cbaa05abc3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutTextMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = -3972786455288763361L; - - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - public WxMpXmlOutTextMessage() { - this.msgType = WxConsts.XmlMsgType.TEXT; - } - -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutTextMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = -3972786455288763361L; + + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + public WxMpXmlOutTextMessage() { + this.msgType = WxConsts.XmlMsgType.TEXT; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java index 7e047bb2a3..5b0857830e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java @@ -1,35 +1,35 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -import java.io.Serializable; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutTransferKefuMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = 1850903037285841322L; - - @XStreamAlias("TransInfo") - protected TransInfo transInfo; - - public WxMpXmlOutTransferKefuMessage() { - this.msgType = WxConsts.KefuMsgType.TRANSFER_CUSTOMER_SERVICE; - } - - @XStreamAlias("TransInfo") - @Data - public static class TransInfo implements Serializable { - private static final long serialVersionUID = -6317885617135706056L; - - @XStreamAlias("KfAccount") - @XStreamConverter(value = XStreamCDataConverter.class) - private String kfAccount; - - } -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +import java.io.Serializable; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutTransferKefuMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = 1850903037285841322L; + + @XStreamAlias("TransInfo") + protected TransInfo transInfo; + + public WxMpXmlOutTransferKefuMessage() { + this.msgType = WxConsts.KefuMsgType.TRANSFER_CUSTOMER_SERVICE; + } + + @XStreamAlias("TransInfo") + @Data + public static class TransInfo implements Serializable { + private static final long serialVersionUID = -6317885617135706056L; + + @XStreamAlias("KfAccount") + @XStreamConverter(value = XStreamCDataConverter.class) + private String kfAccount; + + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java index 690208fcea..bd91b861ee 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java @@ -1,24 +1,24 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = 240367390249860551L; - - @XStreamAlias("Voice") - @XStreamConverter(value = XStreamMediaIdConverter.class) - private String mediaId; - - public WxMpXmlOutVoiceMessage() { - this.msgType = WxConsts.XmlMsgType.VOICE; - } - -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = 240367390249860551L; + + @XStreamAlias("Voice") + @XStreamConverter(value = XStreamMediaIdConverter.class) + private String mediaId; + + public WxMpXmlOutVoiceMessage() { + this.msgType = WxConsts.XmlMsgType.VOICE; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java index ec5734e1e6..e93bf75cf9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java @@ -1,23 +1,23 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonObject; -import lombok.Data; - -import java.io.Serializable; - -@Data -public class WxMpDeviceIdentifier implements Serializable { - private Integer device_id; - private String uuid; - private Integer page_id; - private Integer major; - private Integer minor; - public JsonObject toJsonObject(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("device_id", device_id); - jsonObject.addProperty("uuid", uuid); - jsonObject.addProperty("major", major); - jsonObject.addProperty("minor", minor); - return jsonObject; - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpDeviceIdentifier implements Serializable { + private Integer device_id; + private String uuid; + private Integer page_id; + private Integer major; + private Integer minor; + public JsonObject toJsonObject(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("device_id", device_id); + jsonObject.addProperty("uuid", uuid); + jsonObject.addProperty("major", major); + jsonObject.addProperty("minor", minor); + return jsonObject; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java index d5e99c6c1a..71da0b1c65 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java @@ -1,23 +1,23 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import lombok.Data; - -import java.util.Collection; - -@Data -public class WxMpShakeAroundDeviceBindPageQuery { - private WxMpDeviceIdentifier deviceIdentifier; - private Collection pageIds; - public String toJsonString(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); - JsonArray jsonArray = new JsonArray(); - for(Integer pageid: pageIds){ - jsonArray.add(pageid); - } - jsonObject.add("page_ids", jsonArray); - return jsonObject.toString(); - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.Data; + +import java.util.Collection; + +@Data +public class WxMpShakeAroundDeviceBindPageQuery { + private WxMpDeviceIdentifier deviceIdentifier; + private Collection pageIds; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + JsonArray jsonArray = new JsonArray(); + for(Integer pageid: pageIds){ + jsonArray.add(pageid); + } + jsonObject.add("page_ids", jsonArray); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java index f72f4a1e0d..b04ced93bd 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java @@ -1,23 +1,23 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonObject; -import lombok.Data; - -import java.io.Serializable; -@Data -public class WxMpShakeAroundPageAddQuery implements Serializable { - private String title; - private String description; - private String pageUrl; - private String comment; - private String iconUrl; - public String toJsonString(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("title", title); - jsonObject.addProperty("description", description); - jsonObject.addProperty("page_url", pageUrl); - jsonObject.addProperty("comment", comment); - jsonObject.addProperty("icon_url", iconUrl); - return jsonObject.toString(); - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; +@Data +public class WxMpShakeAroundPageAddQuery implements Serializable { + private String title; + private String description; + private String pageUrl; + private String comment; + private String iconUrl; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("title", title); + jsonObject.addProperty("description", description); + jsonObject.addProperty("page_url", pageUrl); + jsonObject.addProperty("comment", comment); + jsonObject.addProperty("icon_url", iconUrl); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java index 8d9c8c2a37..632fe4f351 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java @@ -1,26 +1,26 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonObject; -import lombok.Data; -import me.chanjar.weixin.common.util.json.GsonHelper; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.io.Serializable; - -@Data -public class WxMpShakeAroundPageAddResult implements Serializable { - private Integer errorCode; - private String errorMsg; - private Integer pageId; - public static WxMpShakeAroundPageAddResult fromJson(String json) { - JsonObject jsonObject = WxMpGsonBuilder.INSTANCE.create().fromJson(json, JsonObject.class); - WxMpShakeAroundPageAddResult result = new WxMpShakeAroundPageAddResult(); - result.setErrorCode(GsonHelper.getInteger(jsonObject, "errcode")); - result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); - jsonObject = jsonObject.getAsJsonObject("data"); - if(jsonObject != null){ - result.setPageId(GsonHelper.getInteger(jsonObject, "page_id")); - } - return result; - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundPageAddResult implements Serializable { + private Integer errorCode; + private String errorMsg; + private Integer pageId; + public static WxMpShakeAroundPageAddResult fromJson(String json) { + JsonObject jsonObject = WxMpGsonBuilder.INSTANCE.create().fromJson(json, JsonObject.class); + WxMpShakeAroundPageAddResult result = new WxMpShakeAroundPageAddResult(); + result.setErrorCode(GsonHelper.getInteger(jsonObject, "errcode")); + result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); + jsonObject = jsonObject.getAsJsonObject("data"); + if(jsonObject != null){ + result.setPageId(GsonHelper.getInteger(jsonObject, "page_id")); + } + return result; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java index 0c4d7fdb80..390fe50964 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java @@ -1,32 +1,32 @@ -package me.chanjar.weixin.mp.bean.shake; - -import com.google.gson.JsonObject; -import lombok.Data; - -import java.io.Serializable; - -@Data -public class WxMpShakeAroundRelationSearchQuery implements Serializable { - private int type; - private Integer pageId; - private Integer begin; - private Integer count; - private WxMpDeviceIdentifier deviceIdentifier; - public String toJsonString(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("type", type); - switch (type){ - case 1: - jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); - break; - case 2: - jsonObject.addProperty("page_id", pageId); - jsonObject.addProperty("begin", begin); - jsonObject.addProperty("count", count); - break; - default: - throw new IllegalArgumentException("type error"); - } - return jsonObject.toString(); - } -} +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundRelationSearchQuery implements Serializable { + private int type; + private Integer pageId; + private Integer begin; + private Integer count; + private WxMpDeviceIdentifier deviceIdentifier; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("type", type); + switch (type){ + case 1: + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + break; + case 2: + jsonObject.addProperty("page_id", pageId); + jsonObject.addProperty("begin", begin); + jsonObject.addProperty("count", count); + break; + default: + throw new IllegalArgumentException("type error"); + } + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java index e4cff86973..2b7269e572 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java @@ -1,22 +1,22 @@ -package me.chanjar.weixin.mp.bean.shake; - -import lombok.Data; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.io.Serializable; -import java.util.List; - -@Data -public class WxMpShakeAroundRelationSearchResult implements Serializable { - private Integer errcode; - private String errmsg; - private WxMpShakeAcoundRelationSearch data; - public static WxMpShakeAroundRelationSearchResult fromJson(String json) { - return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); - } - @Data - public static class WxMpShakeAcoundRelationSearch implements Serializable{ - private List relations; - private Integer total_count; - } -} +package me.chanjar.weixin.mp.bean.shake; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +@Data +public class WxMpShakeAroundRelationSearchResult implements Serializable { + private Integer errcode; + private String errmsg; + private WxMpShakeAcoundRelationSearch data; + public static WxMpShakeAroundRelationSearchResult fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); + } + @Data + public static class WxMpShakeAcoundRelationSearch implements Serializable{ + private List relations; + private Integer total_count; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java index 90b0b2fe80..8a4f7462f7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java @@ -1,36 +1,36 @@ -package me.chanjar.weixin.mp.util.http; - -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialVoiceAndImageDownloadRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialVoiceAndImageDownloadRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialVoiceAndImageDownloadRequestExecutor; - -import java.io.File; -import java.io.InputStream; - -public abstract class MaterialVoiceAndImageDownloadRequestExecutor - implements RequestExecutor { - protected RequestHttp requestHttp; - protected File tmpDirFile; - - public MaterialVoiceAndImageDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { - this.requestHttp = requestHttp; - this.tmpDirFile = tmpDirFile; - } - - public static RequestExecutor create(RequestHttp requestHttp, File tmpDirFile) { - switch (requestHttp.getRequestType()) { - case APACHE_HTTP: - return new ApacheMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); - case JODD_HTTP: - return new JoddMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); - case OK_HTTP: - return new OkhttpMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); - default: - return null; - } - } - - -} +package me.chanjar.weixin.mp.util.http; + +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialVoiceAndImageDownloadRequestExecutor; +import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialVoiceAndImageDownloadRequestExecutor; +import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialVoiceAndImageDownloadRequestExecutor; + +import java.io.File; +import java.io.InputStream; + +public abstract class MaterialVoiceAndImageDownloadRequestExecutor + implements RequestExecutor { + protected RequestHttp requestHttp; + protected File tmpDirFile; + + public MaterialVoiceAndImageDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { + this.requestHttp = requestHttp; + this.tmpDirFile = tmpDirFile; + } + + public static RequestExecutor create(RequestHttp requestHttp, File tmpDirFile) { + switch (requestHttp.getRequestType()) { + case APACHE_HTTP: + return new ApacheMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + case JODD_HTTP: + return new JoddMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + case OK_HTTP: + return new OkhttpMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + default: + return null; + } + } + + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java index f3fa5eeb3c..af2e025796 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java @@ -1,39 +1,39 @@ -package me.chanjar.weixin.mp.util.http; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.apache.ApacheQrCodeRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddQrCodeRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpQrCodeRequestExecutor; - -import java.io.File; - -/** - * 获得QrCode图片 请求执行器 - * - * @author chanjarster - */ -public abstract class QrCodeRequestExecutor implements RequestExecutor { - protected RequestHttp requestHttp; - - public QrCodeRequestExecutor(RequestHttp requestHttp) { - this.requestHttp = requestHttp; - } - - public static RequestExecutor create(RequestHttp requestHttp) throws WxErrorException { - switch (requestHttp.getRequestType()) { - case APACHE_HTTP: - return new ApacheQrCodeRequestExecutor(requestHttp); - case JODD_HTTP: - return new JoddQrCodeRequestExecutor(requestHttp); - case OK_HTTP: - return new OkhttpQrCodeRequestExecutor(requestHttp); - default: - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("不支持的http框架").build()); - } - } - -} +package me.chanjar.weixin.mp.util.http; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import me.chanjar.weixin.mp.util.http.apache.ApacheQrCodeRequestExecutor; +import me.chanjar.weixin.mp.util.http.jodd.JoddQrCodeRequestExecutor; +import me.chanjar.weixin.mp.util.http.okhttp.OkhttpQrCodeRequestExecutor; + +import java.io.File; + +/** + * 获得QrCode图片 请求执行器 + * + * @author chanjarster + */ +public abstract class QrCodeRequestExecutor implements RequestExecutor { + protected RequestHttp requestHttp; + + public QrCodeRequestExecutor(RequestHttp requestHttp) { + this.requestHttp = requestHttp; + } + + public static RequestExecutor create(RequestHttp requestHttp) throws WxErrorException { + switch (requestHttp.getRequestType()) { + case APACHE_HTTP: + return new ApacheQrCodeRequestExecutor(requestHttp); + case JODD_HTTP: + return new JoddQrCodeRequestExecutor(requestHttp); + case OK_HTTP: + return new OkhttpQrCodeRequestExecutor(requestHttp); + default: + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("不支持的http框架").build()); + } + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java index 534b5aa5c1..9ddd61f9a9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java @@ -1,77 +1,77 @@ -package me.chanjar.weixin.mp.util.http.apache; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.bean.material.WxMpMaterial; -import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; -import org.apache.http.Consts; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.HttpMultipartMode; -import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.entity.mime.content.StringBody; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Map; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class ApacheMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { - public ApacheMaterialUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { - HttpPost httpPost = new HttpPost(uri); - if (requestHttp.getRequestHttpProxy() != null) { - RequestConfig response = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); - httpPost.setConfig(response); - } - - if (material == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); - } - - File file = material.getFile(); - if (file == null || !file.exists()) { - throw new FileNotFoundException(); - } - - MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); - multipartEntityBuilder - .addBinaryBody("media", file) - .setMode(HttpMultipartMode.RFC6532); - Map form = material.getForm(); - if (material.getForm() != null) { - multipartEntityBuilder.addPart("description", - new StringBody(WxGsonBuilder.create().toJson(form), ContentType.create("text/plain", Consts.UTF_8))); - } - - httpPost.setEntity(multipartEntityBuilder.build()); - httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); - - try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return WxMpMaterialUploadResult.fromJson(responseContent); - } - } finally { - httpPost.releaseConnection(); - } - } -} +package me.chanjar.weixin.mp.util.http.apache; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.bean.material.WxMpMaterial; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; +import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; +import org.apache.http.Consts; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class ApacheMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { + public ApacheMaterialUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { + HttpPost httpPost = new HttpPost(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig response = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(response); + } + + if (material == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); + } + + File file = material.getFile(); + if (file == null || !file.exists()) { + throw new FileNotFoundException(); + } + + MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); + multipartEntityBuilder + .addBinaryBody("media", file) + .setMode(HttpMultipartMode.RFC6532); + Map form = material.getForm(); + if (material.getForm() != null) { + multipartEntityBuilder.addPart("description", + new StringBody(WxGsonBuilder.create().toJson(form), ContentType.create("text/plain", Consts.UTF_8))); + } + + httpPost.setEntity(multipartEntityBuilder.build()); + httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return WxMpMaterialUploadResult.fromJson(responseContent); + } + } finally { + httpPost.releaseConnection(); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java index ddd5a56879..d001876d6d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java @@ -1,60 +1,60 @@ -package me.chanjar.weixin.mp.util.http.apache; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; -import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; -import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.HttpMultipartMode; -import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.File; -import java.io.IOException; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class ApacheMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { - public ApacheMediaImgUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { - if (data == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); - } - - HttpPost httpPost = new HttpPost(uri); - if (requestHttp.getRequestHttpProxy() != null) { - RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); - httpPost.setConfig(config); - } - - HttpEntity entity = MultipartEntityBuilder - .create() - .addBinaryBody("media", data) - .setMode(HttpMultipartMode.RFC6532) - .build(); - httpPost.setEntity(entity); - httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); - - try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { - String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - - return WxMediaImgUploadResult.fromJson(responseContent); - } - } -} +package me.chanjar.weixin.mp.util.http.apache; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; +import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.File; +import java.io.IOException; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class ApacheMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { + public ApacheMediaImgUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { + if (data == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); + } + + HttpPost httpPost = new HttpPost(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(config); + } + + HttpEntity entity = MultipartEntityBuilder + .create() + .addBinaryBody("media", data) + .setMode(HttpMultipartMode.RFC6532) + .build(); + httpPost.setEntity(entity); + httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + + return WxMediaImgUploadResult.fromJson(responseContent); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java index c5d77c4ab8..a7a5509c08 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java @@ -1,62 +1,62 @@ -package me.chanjar.weixin.mp.util.http.jodd; - -import jodd.http.HttpConnectionProvider; -import jodd.http.HttpRequest; -import jodd.http.HttpResponse; -import jodd.http.ProxyInfo; -import jodd.util.StringPool; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.bean.material.WxMpMaterial; -import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Map; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class JoddMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { - public JoddMaterialUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { - HttpRequest request = HttpRequest.post(uri); - if (requestHttp.getRequestHttpProxy() != null) { - requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); - } - request.withConnectionProvider(requestHttp.getRequestHttpClient()); - - if (material == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); - } - - File file = material.getFile(); - if (file == null || !file.exists()) { - throw new FileNotFoundException(); - } - request.form("media", file); - Map form = material.getForm(); - if (material.getForm() != null) { - request.form("description", WxGsonBuilder.create().toJson(form)); - } - - HttpResponse response = request.send(); - response.charset(StringPool.UTF_8); - String responseContent = response.bodyText(); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return WxMpMaterialUploadResult.fromJson(responseContent); - } - } -} +package me.chanjar.weixin.mp.util.http.jodd; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import jodd.util.StringPool; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.bean.material.WxMpMaterial; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; +import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class JoddMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { + public JoddMaterialUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { + HttpRequest request = HttpRequest.post(uri); + if (requestHttp.getRequestHttpProxy() != null) { + requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); + } + request.withConnectionProvider(requestHttp.getRequestHttpClient()); + + if (material == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); + } + + File file = material.getFile(); + if (file == null || !file.exists()) { + throw new FileNotFoundException(); + } + request.form("media", file); + Map form = material.getForm(); + if (material.getForm() != null) { + request.form("description", WxGsonBuilder.create().toJson(form)); + } + + HttpResponse response = request.send(); + response.charset(StringPool.UTF_8); + String responseContent = response.bodyText(); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return WxMpMaterialUploadResult.fromJson(responseContent); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java index 8379674b32..b66a793365 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java @@ -1,49 +1,49 @@ -package me.chanjar.weixin.mp.util.http.jodd; - -import jodd.http.HttpConnectionProvider; -import jodd.http.HttpRequest; -import jodd.http.HttpResponse; -import jodd.http.ProxyInfo; -import jodd.util.StringPool; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; -import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; - -import java.io.File; -import java.io.IOException; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class JoddMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { - public JoddMediaImgUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { - if (data == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); - } - - HttpRequest request = HttpRequest.post(uri); - if (requestHttp.getRequestHttpProxy() != null) { - requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); - } - request.withConnectionProvider(requestHttp.getRequestHttpClient()); - - request.form("media", data); - HttpResponse response = request.send(); - response.charset(StringPool.UTF_8); - String responseContent = response.bodyText(); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } - - return WxMediaImgUploadResult.fromJson(responseContent); - } -} +package me.chanjar.weixin.mp.util.http.jodd; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import jodd.util.StringPool; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; +import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; + +import java.io.File; +import java.io.IOException; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class JoddMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { + public JoddMediaImgUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { + if (data == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); + } + + HttpRequest request = HttpRequest.post(uri); + if (requestHttp.getRequestHttpProxy() != null) { + requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); + } + request.withConnectionProvider(requestHttp.getRequestHttpClient()); + + request.form("media", data); + HttpResponse response = request.send(); + response.charset(StringPool.UTF_8); + String responseContent = response.bodyText(); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + + return WxMediaImgUploadResult.fromJson(responseContent); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java index 4375606a38..766d239565 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java @@ -1,66 +1,66 @@ -package me.chanjar.weixin.mp.util.http.okhttp; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.bean.material.WxMpMaterial; -import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; -import okhttp3.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Map; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class OkhttpMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public OkhttpMaterialUploadRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { - logger.debug("OkhttpMaterialUploadRequestExecutor is running"); - if (material == null) { - throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); - } - File file = material.getFile(); - if (file == null || !file.exists()) { - throw new FileNotFoundException(); - } - - //得到httpClient - - OkHttpClient client = requestHttp.getRequestHttpClient(); - - MultipartBody.Builder bodyBuilder = new MultipartBody.Builder() - .setType(MediaType.parse("multipart/form-data")) - .addFormDataPart("media", - file.getName(), - RequestBody.create(MediaType.parse("application/octet-stream"), file)); - Map form = material.getForm(); - if (form != null) { - bodyBuilder.addFormDataPart("description", WxGsonBuilder.create().toJson(form)); - } - - Request request = new Request.Builder().url(uri).post(bodyBuilder.build()).build(); - Response response = client.newCall(request).execute(); - String responseContent = response.body().string(); - WxError error = WxError.fromJson(responseContent); - if (error.getErrorCode() != 0) { - throw new WxErrorException(error); - } else { - return WxMpMaterialUploadResult.fromJson(responseContent); - } - } - -} +package me.chanjar.weixin.mp.util.http.okhttp; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.bean.material.WxMpMaterial; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; +import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; +import okhttp3.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; + +/** + * Created by ecoolper on 2017/5/5. + */ +public class OkhttpMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public OkhttpMaterialUploadRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { + logger.debug("OkhttpMaterialUploadRequestExecutor is running"); + if (material == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); + } + File file = material.getFile(); + if (file == null || !file.exists()) { + throw new FileNotFoundException(); + } + + //得到httpClient + + OkHttpClient client = requestHttp.getRequestHttpClient(); + + MultipartBody.Builder bodyBuilder = new MultipartBody.Builder() + .setType(MediaType.parse("multipart/form-data")) + .addFormDataPart("media", + file.getName(), + RequestBody.create(MediaType.parse("application/octet-stream"), file)); + Map form = material.getForm(); + if (form != null) { + bodyBuilder.addFormDataPart("description", WxGsonBuilder.create().toJson(form)); + } + + Request request = new Request.Builder().url(uri).post(bodyBuilder.build()).build(); + Response response = client.newCall(request).execute(); + String responseContent = response.body().string(); + WxError error = WxError.fromJson(responseContent); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } else { + return WxMpMaterialUploadResult.fromJson(responseContent); + } + } + +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java index 7ed544d46d..e8630dbc5a 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java @@ -1,65 +1,65 @@ -package me.chanjar.weixin.mp.api; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.mp.api.impl.WxMpServiceApacheHttpClientImpl; -import org.testng.annotations.*; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -@Test -public class WxMpBusyRetryTest { - - @DataProvider(name = "getService") - public Object[][] getService() { - WxMpService service = new WxMpServiceApacheHttpClientImpl() { - - @Override - public synchronized T executeInternal( - RequestExecutor executor, String uri, E data) - throws WxErrorException { - this.log.info("Executed"); - throw new WxErrorException(WxError.builder().errorCode(-1).build()); - } - }; - - service.setMaxRetryTimes(3); - service.setRetrySleepMillis(500); - return new Object[][]{{service}}; - } - - @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) - public void testRetry(WxMpService service) throws WxErrorException { - service.execute(null, null, null); - } - - @Test(dataProvider = "getService") - public void testRetryInThreadPool(final WxMpService service) throws InterruptedException, ExecutionException { - // 当线程池中的线程复用的时候,还是能保证相同的重试次数 - ExecutorService executorService = Executors.newFixedThreadPool(1); - Runnable runnable = new Runnable() { - @Override - public void run() { - try { - System.out.println("====================="); - System.out.println(Thread.currentThread().getName() + ": testRetry"); - service.execute(null, null, null); - } catch (WxErrorException e) { - throw new RuntimeException(e); - } catch (RuntimeException e) { - // OK - } - } - }; - Future submit1 = executorService.submit(runnable); - Future submit2 = executorService.submit(runnable); - - submit1.get(); - submit2.get(); - } - -} +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.mp.api.impl.WxMpServiceApacheHttpClientImpl; +import org.testng.annotations.*; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +@Test +public class WxMpBusyRetryTest { + + @DataProvider(name = "getService") + public Object[][] getService() { + WxMpService service = new WxMpServiceApacheHttpClientImpl() { + + @Override + public synchronized T executeInternal( + RequestExecutor executor, String uri, E data) + throws WxErrorException { + this.log.info("Executed"); + throw new WxErrorException(WxError.builder().errorCode(-1).build()); + } + }; + + service.setMaxRetryTimes(3); + service.setRetrySleepMillis(500); + return new Object[][]{{service}}; + } + + @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) + public void testRetry(WxMpService service) throws WxErrorException { + service.execute(null, null, null); + } + + @Test(dataProvider = "getService") + public void testRetryInThreadPool(final WxMpService service) throws InterruptedException, ExecutionException { + // 当线程池中的线程复用的时候,还是能保证相同的重试次数 + ExecutorService executorService = Executors.newFixedThreadPool(1); + Runnable runnable = new Runnable() { + @Override + public void run() { + try { + System.out.println("====================="); + System.out.println(Thread.currentThread().getName() + ": testRetry"); + service.execute(null, null, null); + } catch (WxErrorException e) { + throw new RuntimeException(e); + } catch (RuntimeException e) { + // OK + } + } + }; + Future submit1 = executorService.submit(runnable); + Future submit2 = executorService.submit(runnable); + + submit1.get(); + submit2.get(); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index 40e698a514..c3c402c5af 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -1,83 +1,83 @@ -package me.chanjar.weixin.open.api; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; -import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; -import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; -import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; - -/** - * @author 007 - */ -public interface WxOpenComponentService { - - String API_COMPONENT_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; - String API_CREATE_PREAUTHCODE_URL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode"; - String API_QUERY_AUTH_URL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth"; - String API_AUTHORIZER_TOKEN_URL = "https://api.weixin.qq.com /cgi-bin/component/api_authorizer_token"; - String API_GET_AUTHORIZER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info"; - String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option"; - String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/ api_set_authorizer_option"; - - - String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; - String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; - - /** - * 用code换取oauth2的access token - */ - String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s"; - /** - * 刷新oauth2的access token - */ - String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid==%s"; - - WxMpService getWxMpServiceByAppid(String appid); - - WxOpenConfigStorage getWxOpenConfigStorage(); - - boolean checkSignature(String timestamp, String nonce, String signature); - - String getComponentAccessToken(boolean forceRefresh) throws WxErrorException; - - /** - * 获取用户授权页URL(来路URL和成功跳转URL 的域名都需要为三方平台设置的 登录授权的发起页域名) - */ - String getPreAuthUrl(String redirectURI) throws WxErrorException; - - String route(WxOpenXmlMessage wxMessage) throws WxErrorException; - - /** - * 使用授权码换取公众号或小程序的接口调用凭据和授权信息 - */ - WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException; - - /** - * 获取授权方的帐号基本信息 - */ - WxOpenAuthorizerInfoResult getAuthorizerInfo(String authorizerAppid) throws WxErrorException; - - /** - * 获取授权方的选项设置信息 - */ - WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException; - - /** - * 设置授权方的选项信息 - */ - WxError setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException; - - String getAuthorizerAccessToken(String appid, boolean forceRefresh) throws WxErrorException; - - WxMpOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException; - - boolean checkSignature(String appId, String timestamp, String nonce, String signature); - - WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; - - String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state); - -} +package me.chanjar.weixin.open.api; + +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; + +/** + * @author 007 + */ +public interface WxOpenComponentService { + + String API_COMPONENT_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; + String API_CREATE_PREAUTHCODE_URL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode"; + String API_QUERY_AUTH_URL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth"; + String API_AUTHORIZER_TOKEN_URL = "https://api.weixin.qq.com /cgi-bin/component/api_authorizer_token"; + String API_GET_AUTHORIZER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info"; + String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option"; + String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/ api_set_authorizer_option"; + + + String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; + String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; + + /** + * 用code换取oauth2的access token + */ + String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s"; + /** + * 刷新oauth2的access token + */ + String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid==%s"; + + WxMpService getWxMpServiceByAppid(String appid); + + WxOpenConfigStorage getWxOpenConfigStorage(); + + boolean checkSignature(String timestamp, String nonce, String signature); + + String getComponentAccessToken(boolean forceRefresh) throws WxErrorException; + + /** + * 获取用户授权页URL(来路URL和成功跳转URL 的域名都需要为三方平台设置的 登录授权的发起页域名) + */ + String getPreAuthUrl(String redirectURI) throws WxErrorException; + + String route(WxOpenXmlMessage wxMessage) throws WxErrorException; + + /** + * 使用授权码换取公众号或小程序的接口调用凭据和授权信息 + */ + WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException; + + /** + * 获取授权方的帐号基本信息 + */ + WxOpenAuthorizerInfoResult getAuthorizerInfo(String authorizerAppid) throws WxErrorException; + + /** + * 获取授权方的选项设置信息 + */ + WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException; + + /** + * 设置授权方的选项信息 + */ + WxError setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException; + + String getAuthorizerAccessToken(String appid, boolean forceRefresh) throws WxErrorException; + + WxMpOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException; + + boolean checkSignature(String appId, String timestamp, String nonce, String signature); + + WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; + + String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state); + +} diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 075633f716..47b3f4da16 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -1,55 +1,55 @@ - - - - weixin-java-parent - com.github.binarywang - 2.8.8.BETA - - 4.0.0 - - weixin-java-pay - WeiXin Java Tools - PAY - 微信支付 Java SDK - - - - com.github.binarywang - weixin-java-common - ${project.version} - - - com.github.binarywang - qrcode-utils - - - - org.jodd - jodd-http - provided - - - - org.apache.commons - commons-lang3 - - - - ch.qos.logback - logback-classic - test - - - org.testng - testng - test - - - com.google.inject - guice - test - - - - + + + + weixin-java-parent + com.github.binarywang + 2.8.8.BETA + + 4.0.0 + + weixin-java-pay + WeiXin Java Tools - PAY + 微信支付 Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + com.github.binarywang + qrcode-utils + + + + org.jodd + jodd-http + provided + + + + org.apache.commons + commons-lang3 + + + + ch.qos.logback + logback-classic + test + + + org.testng + testng + test + + + com.google.inject + guice + test + + + + From fb9a026d243ab6652b880d7c33570c98f8241078 Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Tue, 21 Nov 2017 11:22:32 +0800 Subject: [PATCH 11/13] =?UTF-8?q?fix=20=E4=B8=89=E6=96=B9=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/open/api/WxOpenComponentService.java | 4 ++-- .../me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java | 1 + .../me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index c3c402c5af..966a89835e 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -17,10 +17,10 @@ public interface WxOpenComponentService { String API_COMPONENT_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; String API_CREATE_PREAUTHCODE_URL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode"; String API_QUERY_AUTH_URL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth"; - String API_AUTHORIZER_TOKEN_URL = "https://api.weixin.qq.com /cgi-bin/component/api_authorizer_token"; + String API_AUTHORIZER_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token"; String API_GET_AUTHORIZER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info"; String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option"; - String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/ api_set_authorizer_option"; + String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option"; String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java index 1f4a465f3a..0123e389c6 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java @@ -18,6 +18,7 @@ public WxOpenMpServiceImpl(WxOpenComponentService wxOpenComponentService, String this.wxOpenComponentService = wxOpenComponentService; this.appId = appId; this.wxMpConfigStorage = wxMpConfigStorage; + initHttp(); } @Override diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java index 6b2e04fde7..26c1791cda 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java @@ -46,7 +46,6 @@ public class WxOpenXmlMessage implements Serializable { private String authorizationCode; @XStreamAlias("AuthorizationCodeExpiredTime") - @XStreamConverter(value = XStreamCDataConverter.class) private Long authorizationCodeExpiredTime; @XStreamAlias("PreAuthCode") From 150df0edec60c740cf44a8e0ccc7ea2271a7519e Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Tue, 21 Nov 2017 18:29:42 +0800 Subject: [PATCH 12/13] =?UTF-8?q?fix=20URL=20=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/open/api/WxOpenComponentService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index 966a89835e..9dc5a6d3d1 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -29,11 +29,11 @@ public interface WxOpenComponentService { /** * 用code换取oauth2的access token */ - String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s"; + String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s"; /** * 刷新oauth2的access token */ - String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid==%s"; + String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/component/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid==%s"; WxMpService getWxMpServiceByAppid(String appid); From a8c3fcf7561970fbcec1bb268eb93347005d8fcf Mon Sep 17 00:00:00 2001 From: 007 <007gzs@gmail.com> Date: Tue, 21 Nov 2017 20:24:38 +0800 Subject: [PATCH 13/13] =?UTF-8?q?WxOpenMpServiceImpl=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E5=8C=85=E5=8F=AF=E8=A7=81=EF=BC=8C=E9=98=B2=E6=AD=A2?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=B7=B7=E6=B7=86=20WxOpenXmlMessage=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E5=8A=A0=E5=AF=86=20WxMpXmlOutMessage?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=20MpConfigStorage=20=E8=BF=94=E5=9B=9Eaeskey?= =?UTF-8?q?=E5=92=8Ctoken=20MpService=E5=8F=AF=E4=BB=A5=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加 全网发布用例 --- weixin-java-open/README.md | 28 ++++++++++++++++++- .../api/impl/WxOpenInMemoryConfigStorage.java | 4 +-- .../open/api/impl/WxOpenMpServiceImpl.java | 2 +- .../open/bean/message/WxOpenXmlMessage.java | 7 +++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/weixin-java-open/README.md b/weixin-java-open/README.md index d99b770673..1f935a9713 100644 --- a/weixin-java-open/README.md +++ b/weixin-java-open/README.md @@ -1,4 +1,6 @@ 消息机制未实现,下面为通知回调中设置的代码部分 + +以下代码可通过腾讯全网发布测试用例 ``` @RestController @RequestMapping("notify") @@ -55,7 +57,31 @@ public class NotifyController extends WechatThridBaseController { // aes加密的消息 WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); - //wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId); + // 全网发布测试用例 + if (StringUtils.equalsAnyIgnoreCase(appId, "wxd101a85aa106f53e", "wx570bc396a51b8ff8")) { + try { + if (StringUtils.equals(inMessage.getMsgType(), "text")) { + if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) { + out = new WxOpenCryptUtil(wxOpenService.getWxOpenConfigStorage()).encrypt( + WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback") + .fromUser(inMessage.getToUser()) + .toUser(inMessage.getFromUser()) + .build() + .toXml() + ); + } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) { + String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api"; + WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build(); + wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); + } + } else if (StringUtils.equals(inMessage.getMsgType(), "event")) { + WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build(); + wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); + } + } catch (WxErrorException e) { + logger.error("callback", e); + } + } return out; } } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java index 687a57d774..50cf8b6e74 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java @@ -329,7 +329,7 @@ public String getSecret() { @Override public String getToken() { - return null; + return wxOpenConfigStorage.getComponentToken(); } @Override @@ -340,7 +340,7 @@ public long getExpiresTime() { @Override public String getAesKey() { - return null; + return wxOpenConfigStorage.getComponentAesKey(); } @Override diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java index 0123e389c6..9c537bc93e 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java @@ -9,7 +9,7 @@ /** * @author 007 */ -public class WxOpenMpServiceImpl extends WxMpServiceImpl { +/* package */ class WxOpenMpServiceImpl extends WxMpServiceImpl { private WxOpenComponentService wxOpenComponentService; private WxMpConfigStorage wxMpConfigStorage; private String appId; diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java index 26c1791cda..8cb245ba3e 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java @@ -5,6 +5,7 @@ import lombok.Data; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; import me.chanjar.weixin.open.api.WxOpenConfigStorage; import me.chanjar.weixin.open.util.WxOpenCryptUtil; import me.chanjar.weixin.open.util.xml.XStreamTransformer; @@ -52,6 +53,12 @@ public class WxOpenXmlMessage implements Serializable { @XStreamConverter(value = XStreamCDataConverter.class) private String preAuthCode; + public static String wxMpOutXmlMessageToEncryptedXml(WxMpXmlOutMessage message, WxOpenConfigStorage wxOpenConfigStorage){ + String plainXml = message.toXml(); + WxOpenCryptUtil pc = new WxOpenCryptUtil(wxOpenConfigStorage); + return pc.encrypt(plainXml); + } + public static WxOpenXmlMessage fromXml(String xml) { //修改微信变态的消息内容格式,方便解析 xml = xml.replace("", "");