From 64f7adcc29bb0912947e2c6749a0072d29e4a1ba Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 30 Aug 2020 10:41:38 +0800 Subject: [PATCH 1/4] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../cp/config/impl/WxCpDefaultConfigImpl.java | 13 +++++++++---- .../bean/request/WxPaySendRedpackRequest.zip | Bin 2180 -> 0 bytes 3 files changed, 10 insertions(+), 4 deletions(-) delete mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip diff --git a/.gitignore b/.gitignore index db0804163..2a629437b 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ sonar-project.properties # STS .factorypath +*.zip diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java index a9b449530..80aca779d 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java @@ -24,7 +24,7 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable { private volatile String token; protected volatile String accessToken; - protected Lock accessTokenLock = new ReentrantLock(); + protected transient Lock accessTokenLock = new ReentrantLock(); private volatile String aesKey; protected volatile Integer agentId; private volatile long expiresTime; @@ -37,16 +37,16 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable { private volatile String httpProxyPassword; private volatile String jsapiTicket; - protected Lock jsapiTicketLock = new ReentrantLock(); + protected transient Lock jsapiTicketLock = new ReentrantLock(); private volatile long jsapiTicketExpiresTime; private volatile String agentJsapiTicket; - protected Lock agentJsapiTicketLock = new ReentrantLock(); + protected transient Lock agentJsapiTicketLock = new ReentrantLock(); private volatile long agentJsapiTicketExpiresTime; private volatile File tmpDirFile; - private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; + private transient volatile ApacheHttpClientBuilder apacheHttpClientBuilder; private volatile String baseApiUrl; @@ -297,4 +297,9 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable { public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { this.apacheHttpClientBuilder = apacheHttpClientBuilder; } + + public WxCpDefaultConfigImpl setWebhookKey(String webhookKey) { + this.webhookKey = webhookKey; + return this; + } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip deleted file mode 100644 index b02696333a4441acee91f7a592a0401b49654d93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2180 zcmaKuXE+;*8pk83d1@4;9II%Z2!fzAMpPO*Xd63C6)}UfW={k;4VS1r$~9wCqngm_ zp+;$`B4(_jwW>;u5=Y(B^W3lZzVGw={{Ii}^M3xJtT?&E003TIz~|a*>plwP(rX?7 zAXfwckO2Sy=m-=x($OpEu7lUzV63OVgICCXFTy=_KWrGb9_{KlGa*4-MdKp$&C(}c z>oQs`&TxJiW0GkKF9#!ccq4iIhkMiRYBJZ8`5?JT5MOyEE>UDBwDOe-MJyrkLq|aw z_>J9>fRBZ%F1?AsvONKedVI%&>z{??dL!0Fu0a&PN@BB6cc&nO{4F{VTY-xyJGk7! zV8M$n!N@gJt~YPbgTZQY63V^lDEOVbO0?vp(W=daxBnvJ=1m3Ss)qSN{LRaK3ZDo2 znp*xccTPWdgbf)Bk-B$90~1uD?x?@tDwaRC+pq(l?f=#HtL)O4S)iBPs*&VZx^)T> zRaPtyy=uDe{KMXu6rXt+wH1cW*{xyDEdq=(p5>&FFrxRV6>!n#F)yLC%h>79_gFiz z%R{@8uJ{}4FIH%H62FhtS3vzR_$9_DVYp!PTpWfOT7?lT)qS|qT7s0c7`tzornu%{ zg~yOT#UcHqRZj5=jj}SdNG`Q{;04BdeW$@?Hcg~WE|tR>AyS_0A=l@wUyG=(hrT7q zOQ#4D)XX3<;DIrr5yQP6VbQp7drd*9cB^!=k}4oYYyA2^|B~uCqF+f>V^0dl!^{8` zO39Yll*~sUDl@HTboM(kUBP$Zh^KSsy}SCORln=ejM^77%=z(=k>#CPGTA;eON&3a zLP}ZQB=@6DG^Udv)t)&PGsmzk*k-7wH*=8*TW5nCKX49P4{lg*TbktY&Zr=N&-9kf z@xV(?JDw=j!cIs@s_^}}cB$6S(lUp30aAV1<<-`{;PU!a<8BbsWeMq;`)V2rz9qkO zn8RKA%WrnBMt=~XMU=Q>C%568g+*pv6ulh0I@YCK+S?zrK7I3QMxWKAnmPFjsvfH0 zeZU_+A?^FFj$E6h3yPhf@1z?^fbJ$F3K%ejh=e7s(zkb$jgu$8?;r-lZpT<+hHy!S z`uhk>G}qb5r#jo^rO(r}$!kKBQ3SABi8S34)hHs%9ibw2JDx7xVGML?=_S)4=C}K* z%TBGDJ>$C1`>;28U`6WMPSwt^8+JqT23>Bf2n*rY(X}oI;WJ>L-UdX-LQk*bnq4t^!b?xMt>1$fjpVcIjT%MR3zz zQ!8Q+lSh(!&l8V!`?6sn+PZz9UYJtbXW_X))5++WvCxhmK0dg0DjkiqSE^;L@PPB` zwS~lMz}Ao9JHJ-B6%cvFYc#f`DIug^Dnla-EG#*7pz*6$dl18bXF>__cbIVbM3Ru) zow@J<8ybr+IPPY+=}8 z8>@l!)qV+AE(y1!Wm$fmwH#hR956n;mBF7cUk!b zRA_!?#lB+GHylZPD`~u&SvPNCc!agTC6;~NL-gr^QgvZnJ{7y)*uwU(l9@WOAlsdf z9AAdwO4z2R8tq#1l_j$_6Vs8}lioQlof@{m2Pkm+h~6dR24VRbZ}y}oBI=vvCuzP? zNVaJ}>bGw?W@%ET%7qu2^ab5J<8|}`39tKY&_dOaW@FU8`tqiK#CXiW`cuBZllotG zW@W@0qY5YwpL|`3rCt+iF2gOcCEuB+h8%QFxeTu)p@h5zhX?C25_%M3V*`_`YTD^p zrY~fvKjP&*jk1CrkV)*GgP^w~?FDji6OJ z>NmL#jI58R=vigh6?^(o)?Hk3(6E`yu!UX?kL=Mz7Z=9)qRkCMsV^t%+_f+d*i+ol z-ZeV>SRggW)SujHUW@P7QtP-0s-8Q3k9MeO-hCCwxpBmt@iTWdJ2q)=ZTKyCXA!8Q zf#51$k- From 7cfabab628fe99afcd66c99114a694d39fdb7709 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 30 Aug 2020 10:50:25 +0800 Subject: [PATCH 2/4] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=B9=B6=E7=BB=9F=E4=B8=80=E5=85=AC=E4=BC=97=E5=8F=B7?= =?UTF-8?q?=E5=92=8C=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=9A=84spring=20boot=20st?= =?UTF-8?q?arter=E9=83=A8=E5=88=86=E9=85=8D=E7=BD=AE=E7=B1=BB=E5=92=8C?= =?UTF-8?q?=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../miniapp/config/WxMaAutoConfiguration.java | 24 +++--- .../miniapp/properties/RedisProperties.java | 43 +++++++++++ .../miniapp/properties/WxMaProperties.java | 33 -------- .../wx-java-mp-spring-boot-starter/README.md | 4 +- .../config/WxMpServiceAutoConfiguration.java | 25 ++++--- .../config/WxMpStorageAutoConfiguration.java | 29 ++++--- .../wxjava/mp/enums/HttpClientType.java | 22 ++++++ .../starter/wxjava/mp/enums/StorageType.java | 22 ++++++ .../wxjava/mp/properties/RedisProperties.java | 46 ++++++++++++ .../wxjava/mp/properties/WxMpProperties.java | 75 +------------------ 10 files changed, 186 insertions(+), 137 deletions(-) create mode 100644 spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/RedisProperties.java create mode 100644 spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/enums/HttpClientType.java create mode 100644 spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/enums/StorageType.java create mode 100644 spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/RedisProperties.java diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaAutoConfiguration.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaAutoConfiguration.java index 7c727c968..a07e8008b 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaAutoConfiguration.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaAutoConfiguration.java @@ -9,6 +9,7 @@ import cn.binarywang.wx.miniapp.config.WxMaConfig; import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl; import com.binarywang.spring.starter.wxjava.miniapp.enums.HttpClientType; +import com.binarywang.spring.starter.wxjava.miniapp.properties.RedisProperties; import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties; import lombok.AllArgsConstructor; import me.chanjar.weixin.common.redis.JedisWxRedisOps; @@ -52,14 +53,19 @@ public class WxMaAutoConfiguration { public WxMaService service(WxMaConfig wxMaConfig) { HttpClientType httpClientType = wxMaProperties.getConfigStorage().getHttpClientType(); WxMaService wxMaService; - if (httpClientType == HttpClientType.OkHttp) { - wxMaService = new WxMaServiceOkHttpImpl(); - } else if (httpClientType == HttpClientType.JoddHttp) { - wxMaService = new WxMaServiceJoddHttpImpl(); - } else if (httpClientType == HttpClientType.HttpClient) { - wxMaService = new WxMaServiceHttpClientImpl(); - } else { - wxMaService = new WxMaServiceImpl(); + switch (httpClientType) { + case OkHttp: + wxMaService = new WxMaServiceOkHttpImpl(); + break; + case JoddHttp: + wxMaService = new WxMaServiceJoddHttpImpl(); + break; + case HttpClient: + wxMaService = new WxMaServiceHttpClientImpl(); + break; + default: + wxMaService = new WxMaServiceImpl(); + break; } wxMaService.setWxMaConfig(wxMaConfig); return wxMaService; @@ -102,7 +108,7 @@ public class WxMaAutoConfiguration { } private WxMaDefaultConfigImpl wxMaJedisConfigStorage() { - WxMaProperties.RedisProperties redisProperties = wxMaProperties.getConfigStorage().getRedis(); + RedisProperties redisProperties = wxMaProperties.getConfigStorage().getRedis(); JedisPool jedisPool; if (StringUtils.isNotEmpty(redisProperties.getHost())) { JedisPoolConfig config = new JedisPoolConfig(); diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/RedisProperties.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/RedisProperties.java new file mode 100644 index 000000000..9cfaf80e8 --- /dev/null +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/RedisProperties.java @@ -0,0 +1,43 @@ +package com.binarywang.spring.starter.wxjava.miniapp.properties; + +import lombok.Data; + +/** + * redis 配置. + * + * @author Binary Wang + * @date 2020-08-30 + */ +@Data +public class RedisProperties { + + /** + * 主机地址.不填则从spring容器内获取JedisPool + */ + private String host; + + /** + * 端口号. + */ + private int port = 6379; + + /** + * 密码. + */ + private String password; + + /** + * 超时. + */ + private int timeout = 2000; + + /** + * 数据库. + */ + private int database = 0; + + private Integer maxActive; + private Integer maxIdle; + private Integer maxWaitMillis; + private Integer minIdle; +} diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java index 0139215ea..25a004776 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java @@ -88,37 +88,4 @@ public class WxMaProperties { private String httpProxyPassword; } - @Data - public static class RedisProperties { - - /** - * 主机地址.不填则从spring容器内获取JedisPool - */ - private String host; - - /** - * 端口号. - */ - private int port = 6379; - - /** - * 密码. - */ - private String password; - - /** - * 超时. - */ - private int timeout = 2000; - - /** - * 数据库. - */ - private int database = 0; - - private Integer maxActive; - private Integer maxIdle; - private Integer maxWaitMillis; - private Integer minIdle; - } } diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md b/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md index 65cc5bbbf..5059a59f5 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md @@ -16,12 +16,12 @@ wx.mp.token = @token wx.mp.aesKey = @aesKey # 存储配置redis(可选) - wx.mp.config-storage.type = redis # 配置类型: memory(默认), redis, jedis, redistemplate + wx.mp.config-storage.type = Jedis # 配置类型: Memory(默认), Jedis, RedisTemplate wx.mp.config-storage.key-prefix = wx # 相关redis前缀配置: wx(默认) wx.mp.config-storage.redis.host = 127.0.0.1 wx.mp.config-storage.redis.port = 6379 # http客户端配置 - wx.mp.config-storage.http-client-type=httpclient # http客户端类型: httpclient(默认), okhttp, joddhttp + wx.mp.config-storage.http-client-type=httpclient # http客户端类型: HttpClient(默认), OkHttp, JoddHttp wx.mp.config-storage.http-proxy-host= wx.mp.config-storage.http-proxy-port= wx.mp.config-storage.http-proxy-username= diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpServiceAutoConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpServiceAutoConfiguration.java index 1c942bbfa..3f1195a4c 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpServiceAutoConfiguration.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpServiceAutoConfiguration.java @@ -1,7 +1,7 @@ package com.binarywang.spring.starter.wxjava.mp.config; +import com.binarywang.spring.starter.wxjava.mp.enums.HttpClientType; import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; -import me.chanjar.weixin.common.api.WxOcrService; import me.chanjar.weixin.mp.api.*; import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; @@ -23,16 +23,21 @@ public class WxMpServiceAutoConfiguration { @Bean @ConditionalOnMissingBean public WxMpService wxMpService(WxMpConfigStorage configStorage, WxMpProperties wxMpProperties) { - WxMpProperties.HttpClientType httpClientType = wxMpProperties.getConfigStorage().getHttpClientType(); + HttpClientType httpClientType = wxMpProperties.getConfigStorage().getHttpClientType(); WxMpService wxMpService; - if (httpClientType == WxMpProperties.HttpClientType.okhttp) { - wxMpService = newWxMpServiceOkHttpImpl(); - } else if (httpClientType == WxMpProperties.HttpClientType.joddhttp) { - wxMpService = newWxMpServiceJoddHttpImpl(); - } else if (httpClientType == WxMpProperties.HttpClientType.httpclient) { - wxMpService = newWxMpServiceHttpClientImpl(); - } else { - wxMpService = newWxMpServiceImpl(); + switch (httpClientType) { + case OkHttp: + wxMpService = newWxMpServiceOkHttpImpl(); + break; + case JoddHttp: + wxMpService = newWxMpServiceJoddHttpImpl(); + break; + case HttpClient: + wxMpService = newWxMpServiceHttpClientImpl(); + break; + default: + wxMpService = newWxMpServiceImpl(); + break; } wxMpService.setWxMpConfigStorage(configStorage); diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java index fc15e7605..ad4fb31e4 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java @@ -1,5 +1,7 @@ package com.binarywang.spring.starter.wxjava.mp.config; +import com.binarywang.spring.starter.wxjava.mp.properties.RedisProperties; +import com.binarywang.spring.starter.wxjava.mp.enums.StorageType; import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; import lombok.RequiredArgsConstructor; import me.chanjar.weixin.common.redis.JedisWxRedisOps; @@ -26,7 +28,6 @@ import redis.clients.jedis.JedisPoolConfig; @Configuration @RequiredArgsConstructor public class WxMpStorageAutoConfiguration { - private final ApplicationContext applicationContext; private final WxMpProperties wxMpProperties; @@ -40,25 +41,29 @@ public class WxMpStorageAutoConfiguration { @Bean @ConditionalOnMissingBean(WxMpConfigStorage.class) public WxMpConfigStorage wxMpConfigStorage() { - WxMpProperties.StorageType type = wxMpProperties.getConfigStorage().getType(); + StorageType type = wxMpProperties.getConfigStorage().getType(); WxMpConfigStorage config; - if (type == WxMpProperties.StorageType.redis || type == WxMpProperties.StorageType.jedis) { - config = wxMpInJedisConfigStorage(); - } else if (type == WxMpProperties.StorageType.redistemplate) { - config = wxMpInRedisTemplateConfigStorage(); - } else { - config = wxMpInMemoryConfigStorage(); + switch (type) { + case Jedis: + config = jedisConfigStorage(); + break; + case RedisTemplate: + config = redisTemplateConfigStorage(); + break; + default: + config = defaultConfigStorage(); + break; } return config; } - private WxMpConfigStorage wxMpInMemoryConfigStorage() { + private WxMpConfigStorage defaultConfigStorage() { WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); setWxMpInfo(config); return config; } - private WxMpConfigStorage wxMpInJedisConfigStorage() { + private WxMpConfigStorage jedisConfigStorage() { JedisPool jedisPool; if (StringUtils.isNotEmpty(redisHost) || StringUtils.isNotEmpty(redisHost2)) { jedisPool = getJedisPool(); @@ -71,7 +76,7 @@ public class WxMpStorageAutoConfiguration { return wxMpRedisConfig; } - private WxMpConfigStorage wxMpInRedisTemplateConfigStorage() { + private WxMpConfigStorage redisTemplateConfigStorage() { StringRedisTemplate redisTemplate = applicationContext.getBean(StringRedisTemplate.class); WxRedisOps redisOps = new RedisTemplateWxRedisOps(redisTemplate); WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisOps, wxMpProperties.getConfigStorage().getKeyPrefix()); @@ -97,7 +102,7 @@ public class WxMpStorageAutoConfiguration { private JedisPool getJedisPool() { WxMpProperties.ConfigStorage storage = wxMpProperties.getConfigStorage(); - WxMpProperties.RedisProperties redis = storage.getRedis(); + RedisProperties redis = storage.getRedis(); JedisPoolConfig config = new JedisPoolConfig(); if (redis.getMaxActive() != null) { diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/enums/HttpClientType.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/enums/HttpClientType.java new file mode 100644 index 000000000..1fa235e4a --- /dev/null +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/enums/HttpClientType.java @@ -0,0 +1,22 @@ +package com.binarywang.spring.starter.wxjava.mp.enums; + +/** + * httpclient类型. + * + * @author Binary Wang + * @date 2020-08-30 + */ +public enum HttpClientType { + /** + * HttpClient. + */ + HttpClient, + /** + * OkHttp. + */ + OkHttp, + /** + * JoddHttp. + */ + JoddHttp, +} diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/enums/StorageType.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/enums/StorageType.java new file mode 100644 index 000000000..7dcb5a115 --- /dev/null +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/enums/StorageType.java @@ -0,0 +1,22 @@ +package com.binarywang.spring.starter.wxjava.mp.enums; + +/** + * storage类型. + * + * @author Binary Wang + * @date 2020-08-30 + */ +public enum StorageType { + /** + * 内存. + */ + Memory, + /** + * redis(JedisClient). + */ + Jedis, + /** + * redis(RedisTemplate). + */ + RedisTemplate +} diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/RedisProperties.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/RedisProperties.java new file mode 100644 index 000000000..c8c3307fe --- /dev/null +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/RedisProperties.java @@ -0,0 +1,46 @@ +package com.binarywang.spring.starter.wxjava.mp.properties; + +import lombok.Data; + +import java.io.Serializable; + +/** + * redis 配置属性. + * + * @author Binary Wang + * @date 2020-08-30 + */ +@Data +public class RedisProperties implements Serializable { + private static final long serialVersionUID = -5924815351660074401L; + + /** + * 主机地址. + */ + private String host = "127.0.0.1"; + + /** + * 端口号. + */ + private int port = 6379; + + /** + * 密码. + */ + private String password; + + /** + * 超时. + */ + private int timeout = 2000; + + /** + * 数据库. + */ + private int database = 0; + + private Integer maxActive; + private Integer maxIdle; + private Integer maxWaitMillis; + private Integer minIdle; +} diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java index 60b39d9cd..af21cd9da 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java @@ -1,12 +1,14 @@ package com.binarywang.spring.starter.wxjava.mp.properties; +import com.binarywang.spring.starter.wxjava.mp.enums.HttpClientType; +import com.binarywang.spring.starter.wxjava.mp.enums.StorageType; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import java.io.Serializable; import static com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties.PREFIX; -import static com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties.StorageType.memory; +import static com.binarywang.spring.starter.wxjava.mp.enums.StorageType.Memory; /** @@ -51,7 +53,7 @@ public class WxMpProperties { /** * 存储类型. */ - private StorageType type = memory; + private StorageType type = Memory; /** * 指定key前缀. @@ -90,73 +92,4 @@ public class WxMpProperties { } - public enum StorageType { - /** - * 内存. - */ - memory, - /** - * jedis. - */ - redis, - /** - * redis(JedisClient). - */ - jedis, - /** - * redis(RedisTemplate). - */ - redistemplate - } - - public enum HttpClientType { - /** - * HttpClient. - */ - httpclient, - /** - * OkHttp. - */ - okhttp, - /** - * JoddHttp. - */ - joddhttp - } - - @Data - public static class RedisProperties implements Serializable { - private static final long serialVersionUID = -5924815351660074401L; - - /** - * 主机地址. - */ - private String host = "127.0.0.1"; - - /** - * 端口号. - */ - private int port = 6379; - - /** - * 密码. - */ - private String password; - - /** - * 超时. - */ - private int timeout = 2000; - - /** - * 数据库. - */ - private int database = 0; - - private Integer maxActive; - private Integer maxIdle; - private Integer maxWaitMillis; - private Integer minIdle; - } - } From c01347cac6dedb5dab8dcac7d4941602a6059c2d Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 30 Aug 2020 17:41:56 +0800 Subject: [PATCH 3/4] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E4=BC=81?= =?UTF-8?q?=E4=B8=9A=E5=BE=AE=E4=BF=A1=E6=B6=88=E6=81=AF=E5=8F=91=E9=80=81?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=BC=95=E5=85=A5?= =?UTF-8?q?moco=E6=A8=A1=E6=8B=9F=E6=B5=8B=E8=AF=95=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E6=96=B9=E4=BE=BF=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 8 +- .../wxjava/mp/properties/WxMpProperties.java | 4 +- weixin-java-cp/pom.xml | 5 + .../weixin/cp/api/WxCpMessageService.java | 25 ++++ .../me/chanjar/weixin/cp/api/WxCpService.java | 138 ++++++++++++++---- .../cp/api/impl/BaseWxCpServiceImpl.java | 18 +-- .../cp/api/impl/WxCpMessageServiceImpl.java | 31 ++++ .../weixin/cp/constant/WxCpApiPathConsts.java | 17 ++- .../chanjar/weixin/cp/api/ApiTestModule.java | 68 ++------- .../cp/api/ApiTestModuleWithMockServer.java | 19 +++ .../WxCpMessageServiceImplTest.java} | 62 +++++--- .../api/impl/WxCpTaskCardServiceImplTest.java | 2 +- .../src/test/resources/moco/message.json | 18 +++ 13 files changed, 297 insertions(+), 118 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModuleWithMockServer.java rename weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/{WxCpMessageAPITest.java => impl/WxCpMessageServiceImplTest.java} (65%) create mode 100644 weixin-java-cp/src/test/resources/moco/message.json diff --git a/pom.xml b/pom.xml index 5b23cb58c..379f5cf45 100644 --- a/pom.xml +++ b/pom.xml @@ -182,7 +182,7 @@ com.google.guava guava - 29.0-android + 29.0-jre com.google.code.gson @@ -239,6 +239,12 @@ 3.0.0 test + + com.github.dreamhead + moco-runner + 1.1.0 + test + redis.clients diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java index af21cd9da..14a61b574 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java @@ -7,8 +7,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import java.io.Serializable; -import static com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties.PREFIX; import static com.binarywang.spring.starter.wxjava.mp.enums.StorageType.Memory; +import static com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties.PREFIX; /** @@ -68,7 +68,7 @@ public class WxMpProperties { /** * http客户端类型. */ - private HttpClientType httpClientType = HttpClientType.httpclient; + private HttpClientType httpClientType = HttpClientType.HttpClient; /** * http代理主机. diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 5d9fdae34..86d6feab3 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -83,6 +83,11 @@ assertj-guava test + + com.github.dreamhead + moco-runner + test + diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java new file mode 100644 index 000000000..d8a6cc2a7 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java @@ -0,0 +1,25 @@ +package me.chanjar.weixin.cp.api; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; + +/** + * 消息推送接口. + * + * @author Binary Wang + * @date 2020 -08-30 + */ +public interface WxCpMessageService { + /** + *
+   * 发送消息
+   * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E
+   * 
+ * + * @param message 要发送的消息对象 + * @return the wx cp message send result + * @throws WxErrorException the wx error exception + */ + WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 036265815..7c1d4857b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -29,13 +29,16 @@ public interface WxCpService { * @param timestamp 时间戳 * @param nonce 随机数 * @param data 微信传输过来的数据,有可能是echoStr,有可能是xml消息 + * @return the boolean */ boolean checkSignature(String msgSignature, String timestamp, String nonce, String data); /** * 获取access_token, 不强制刷新access_token * - * @see #getAccessToken(boolean) + * @return the access token + * @throws WxErrorException the wx error exception + * @see #getAccessToken(boolean) #getAccessToken(boolean) */ String getAccessToken() throws WxErrorException; @@ -49,13 +52,17 @@ public interface WxCpService { * * * @param forceRefresh 强制刷新 + * @return the access token + * @throws WxErrorException the wx error exception */ String getAccessToken(boolean forceRefresh) throws WxErrorException; /** * 获得jsapi_ticket,不强制刷新jsapi_ticket * - * @see #getJsapiTicket(boolean) + * @return the jsapi ticket + * @throws WxErrorException the wx error exception + * @see #getJsapiTicket(boolean) #getJsapiTicket(boolean) */ String getJsapiTicket() throws WxErrorException; @@ -68,6 +75,8 @@ public interface WxCpService { * * * @param forceRefresh 强制刷新 + * @return the jsapi ticket + * @throws WxErrorException the wx error exception */ String getJsapiTicket(boolean forceRefresh) throws WxErrorException; @@ -78,7 +87,9 @@ public interface WxCpService { * 签名的jsapi_ticket必须使用以下接口获取。且必须用wx.agentConfig中的agentid对应的应用secret去获取access_token。 * 签名用的noncestr和timestamp必须与wx.agentConfig中的nonceStr和timestamp相同。 * - * @see #getJsapiTicket(boolean) + * @return the agent jsapi ticket + * @throws WxErrorException the wx error exception + * @see #getJsapiTicket(boolean) #getJsapiTicket(boolean) */ String getAgentJsapiTicket() throws WxErrorException; @@ -96,6 +107,8 @@ public interface WxCpService { * * * @param forceRefresh 强制刷新 + * @return the agent jsapi ticket + * @throws WxErrorException the wx error exception */ String getAgentJsapiTicket(boolean forceRefresh) throws WxErrorException; @@ -107,23 +120,18 @@ public interface WxCpService { * * * @param url url + * @return the wx jsapi signature + * @throws WxErrorException the wx error exception */ WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; - /** - *
-   * 发送消息
-   * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E
-   * 
- * - * @param message 要发送的消息对象 - */ - WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException; /** * 小程序登录凭证校验 * * @param jsCode 登录时获取的 code + * @return the wx cp ma js code 2 session result + * @throws WxErrorException the wx error exception */ WxCpMaJsCode2SessionResult jsCode2Session(String jsCode) throws WxErrorException; @@ -134,6 +142,7 @@ public interface WxCpService { * * * @return { "ip_list": ["101.226.103.*", "101.226.62.*"] } + * @throws WxErrorException the wx error exception */ String[] getCallbackIp() throws WxErrorException; @@ -147,12 +156,7 @@ public interface WxCpService { * * @param corpId 服务商的corpid * @param providerSecret 服务商的secret,在服务商管理后台可见 - * @return { - * "errcode":0 , - * "errmsg":"ok" , - * "provider_access_token":"enLSZ5xxxxxxJRL", - * "expires_in":7200 - * } + * @return { "errcode":0 , "errmsg":"ok" , "provider_access_token":"enLSZ5xxxxxxJRL", "expires_in":7200 } * @throws WxErrorException . */ WxCpProviderToken getProviderToken(String corpId, String providerSecret) throws WxErrorException; @@ -162,6 +166,8 @@ public interface WxCpService { * * @param url 接口地址 * @param queryParam 请求参数 + * @return the string + * @throws WxErrorException the wx error exception */ String get(String url, String queryParam) throws WxErrorException; @@ -170,6 +176,8 @@ public interface WxCpService { * * @param url 接口地址 * @param postData 请求body字符串 + * @return the string + * @throws WxErrorException the wx error exception */ String post(String url, String postData) throws WxErrorException; @@ -178,6 +186,8 @@ public interface WxCpService { * * @param url 接口地址 * @param postData 请求body字符串 + * @return the string + * @throws WxErrorException the wx error exception */ String postWithoutToken(String url, String postData) throws WxErrorException; @@ -188,11 +198,13 @@ public interface WxCpService { * 可以参考,{@link MediaUploadRequestExecutor}的实现方法 * * + * @param 请求值类型 + * @param 返回值类型 * @param executor 执行器 * @param uri 请求地址 * @param data 参数 - * @param 请求值类型 - * @param 返回值类型 + * @return the t + * @throws WxErrorException the wx error exception */ T execute(RequestExecutor executor, String uri, E data) throws WxErrorException; @@ -220,6 +232,7 @@ public interface WxCpService { * 获取某个sessionId对应的session,如果sessionId没有对应的session,则新建一个并返回。 * * @param id id可以为任意字符串,建议使用FromUserName作为id + * @return the session */ WxSession getSession(String id); @@ -228,13 +241,14 @@ public interface WxCpService { * * @param id id可以为任意字符串,建议使用FromUserName作为id * @param create 是否新建 + * @return the session */ WxSession getSession(String id, boolean create); /** * 获取WxSessionManager 对象 * - * @return WxSessionManager + * @return WxSessionManager session manager */ WxSessionManager getSessionManager(); @@ -252,6 +266,8 @@ public interface WxCpService { * 上传部门列表覆盖企业号上的部门信息 * * @param mediaId 媒体id + * @return the string + * @throws WxErrorException the wx error exception */ String replaceParty(String mediaId) throws WxErrorException; @@ -259,11 +275,17 @@ public interface WxCpService { * 上传用户列表覆盖企业号上的用户信息 * * @param mediaId 媒体id + * @return the string + * @throws WxErrorException the wx error exception */ String replaceUser(String mediaId) throws WxErrorException; /** * 获取异步任务结果 + * + * @param joinId the join id + * @return the task result + * @throws WxErrorException the wx error exception */ String getTaskResult(String joinId) throws WxErrorException; @@ -275,7 +297,7 @@ public interface WxCpService { /** * 获取WxMpConfigStorage 对象 * - * @return WxMpConfigStorage + * @return WxMpConfigStorage wx cp config storage */ WxCpConfigStorage getWxCpConfigStorage(); @@ -288,75 +310,141 @@ public interface WxCpService { /** * 获取部门相关接口的服务类对象 + * + * @return the department service */ WxCpDepartmentService getDepartmentService(); /** * 获取媒体相关接口的服务类对象 + * + * @return the media service */ WxCpMediaService getMediaService(); /** * 获取菜单相关接口的服务类对象 + * + * @return the menu service */ WxCpMenuService getMenuService(); /** * 获取Oauth2相关接口的服务类对象 + * + * @return the oauth 2 service */ WxCpOAuth2Service getOauth2Service(); /** * 获取标签相关接口的服务类对象 + * + * @return the tag service */ WxCpTagService getTagService(); /** * 获取用户相关接口的服务类对象 + * + * @return the user service */ WxCpUserService getUserService(); + /** + * Gets external contact service. + * + * @return the external contact service + */ WxCpExternalContactService getExternalContactService(); /** * 获取群聊服务 * - * @return 群聊服务 + * @return 群聊服务 chat service */ WxCpChatService getChatService(); /** * 获取任务卡片服务 * - * @return 任务卡片服务 + * @return 任务卡片服务 task card service */ WxCpTaskCardService getTaskCardService(); + /** + * Gets agent service. + * + * @return the agent service + */ WxCpAgentService getAgentService(); + /** + * Gets message service. + * + * @return the message service + */ + WxCpMessageService getMessageService(); + + /** + * Gets oa service. + * + * @return the oa service + */ WxCpOaService getOAService(); /** * 获取群机器人消息推送服务 * - * @return 群机器人消息推送服务 + * @return 群机器人消息推送服务 group robot service */ WxCpGroupRobotService getGroupRobotService(); /** * http请求对象 + * + * @return the request http */ RequestHttp getRequestHttp(); + /** + * Sets user service. + * + * @param userService the user service + */ void setUserService(WxCpUserService userService); + /** + * Sets department service. + * + * @param departmentService the department service + */ void setDepartmentService(WxCpDepartmentService departmentService); + /** + * Sets media service. + * + * @param mediaService the media service + */ void setMediaService(WxCpMediaService mediaService); + /** + * Sets menu service. + * + * @param menuService the menu service + */ void setMenuService(WxCpMenuService menuService); + /** + * Sets oauth 2 service. + * + * @param oauth2Service the oauth 2 service + */ void setOauth2Service(WxCpOAuth2Service oauth2Service); + /** + * Sets tag service. + * + * @param tagService the tag service + */ void setTagService(WxCpTagService tagService); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java index 52d88e456..97faa4c96 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java @@ -22,8 +22,6 @@ import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; import me.chanjar.weixin.common.util.json.GsonParser; import me.chanjar.weixin.cp.api.*; import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult; -import me.chanjar.weixin.cp.bean.WxCpMessage; -import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; import me.chanjar.weixin.cp.bean.WxCpProviderToken; import me.chanjar.weixin.cp.config.WxCpConfigStorage; @@ -53,6 +51,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH private WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this); private WxCpExternalContactService externalContactService = new WxCpExternalContactServiceImpl(this); private WxCpGroupRobotService groupRobotService = new WxCpGroupRobotServiceImpl(this); + private WxCpMessageService messageService = new WxCpMessageServiceImpl(this); /** * 全局的是否正在刷新access token的锁. @@ -169,16 +168,6 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH return jsapiSignature; } - @Override - public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException { - Integer agentId = message.getAgentId(); - if (null == agentId) { - message.setAgentId(this.getWxCpConfigStorage().getAgentId()); - } - - return WxCpMessageSendResult.fromJson(this.post(this.configStorage.getApiUrl(MESSAGE_SEND), message.toJson())); - } - @Override public WxCpMaJsCode2SessionResult jsCode2Session(String jsCode) throws WxErrorException { Map params = new HashMap<>(2); @@ -486,6 +475,11 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH return agentService; } + @Override + public WxCpMessageService getMessageService() { + return this.messageService; + } + public void setAgentService(WxCpAgentService agentService) { this.agentService = agentService; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java new file mode 100644 index 000000000..533f954bf --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java @@ -0,0 +1,31 @@ +package me.chanjar.weixin.cp.api.impl; + +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.WxCpMessageService; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; +import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; + +/** + * 消息推送接口实现类. + * + * @author Binary Wang + * @date 2020-08-30 + */ +@RequiredArgsConstructor +public class WxCpMessageServiceImpl implements WxCpMessageService { + private final WxCpService cpService; + + @Override + public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException { + Integer agentId = message.getAgentId(); + if (null == agentId) { + message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId()); + } + + return WxCpMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage() + .getApiUrl(WxCpApiPathConsts.Message.MESSAGE_SEND), message.toJson())); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index 00e7616d1..1f435303c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java @@ -14,7 +14,6 @@ public final class WxCpApiPathConsts { public static final String GET_JSAPI_TICKET = "/cgi-bin/get_jsapi_ticket"; public static final String GET_AGENT_CONFIG_TICKET = "/cgi-bin/ticket/get?&type=agent_config"; - public static final String MESSAGE_SEND = "/cgi-bin/message/send"; public static final String GET_CALLBACK_IP = "/cgi-bin/getcallbackip"; public static final String BATCH_REPLACE_PARTY = "/cgi-bin/batch/replaceparty"; public static final String BATCH_REPLACE_USER = "/cgi-bin/batch/replaceuser"; @@ -23,6 +22,22 @@ public final class WxCpApiPathConsts { public static final String GET_TOKEN = "/cgi-bin/gettoken?corpid=%s&corpsecret=%s"; public static final String WEBHOOK_SEND = "/cgi-bin/webhook/send?key="; + /** + * 消息推送相关接口 + * https://work.weixin.qq.com/api/doc/90000/90135/90235 + */ + public static class Message { + /** + * 发送应用消息 + */ + public static final String MESSAGE_SEND = "/cgi-bin/message/send"; + + /** + * 互联企业发送应用消息 + */ + public static final String LINKEDCORP_MESSAGE_SEND = "/cgi-bin/linkedcorp/message/send"; + } + public static class Agent { public static final String AGENT_GET = "/cgi-bin/agent/get?agentid=%d"; public static final String AGENT_SET = "/cgi-bin/agent/set"; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java index c15e3af4d..e5aa15193 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java @@ -1,22 +1,23 @@ package me.chanjar.weixin.cp.api; -import java.io.IOException; -import java.io.InputStream; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.google.inject.Binder; import com.google.inject.Module; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.util.xml.XStreamInitializer; import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; +import java.io.IOException; +import java.io.InputStream; + +@Slf4j public class ApiTestModule implements Module { - private final Logger log = LoggerFactory.getLogger(this.getClass()); private static final String TEST_CONFIG_XML = "test-config.xml"; + protected WxXmlCpInMemoryConfigStorage config; private static T fromXml(Class clazz, InputStream is) { XStream xstream = XStreamInitializer.getInstance(); @@ -32,70 +33,27 @@ public class ApiTestModule implements Module { throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成"); } - WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, inputStream); + config = fromXml(WxXmlCpInMemoryConfigStorage.class, inputStream); WxCpService wxService = new WxCpServiceImpl(); wxService.setWxCpConfigStorage(config); binder.bind(WxCpService.class).toInstance(wxService); binder.bind(WxXmlCpInMemoryConfigStorage.class).toInstance(config); } catch (IOException e) { - this.log.error(e.getMessage(), e); + log.error(e.getMessage(), e); } } + @Data + @EqualsAndHashCode(callSuper = true) @XStreamAlias("xml") public static class WxXmlCpInMemoryConfigStorage extends WxCpDefaultConfigImpl { + private static final long serialVersionUID = -4521839921547374822L; protected String userId; - protected String departmentId; - protected String tagId; - protected String externalUserId; - - public String getUserId() { - return this.userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public String getDepartmentId() { - return this.departmentId; - } - - public void setDepartmentId(String departmentId) { - this.departmentId = departmentId; - } - - public String getTagId() { - return this.tagId; - } - - public void setTagId(String tagId) { - this.tagId = tagId; - } - - public String getExternalUserId() { - return externalUserId; - } - - public void setExternalUserId(String externalUserId) { - this.externalUserId = externalUserId; - } - - @Override - public String toString() { - return super.toString() + " > WxXmlCpConfigStorage{" + - "userId='" + this.userId + '\'' + - ", departmentId='" + this.departmentId + '\'' + - ", tagId='" + this.tagId + '\'' + - ", externalUserId='" + this.externalUserId + '\'' + - - '}'; - } } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModuleWithMockServer.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModuleWithMockServer.java new file mode 100644 index 000000000..83f38612d --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModuleWithMockServer.java @@ -0,0 +1,19 @@ +package me.chanjar.weixin.cp.api; + +import com.google.inject.Binder; + +/** + * 带mock server 的test module. + * + * @author Binary Wang + * @date 2020-08-30 + */ +public class ApiTestModuleWithMockServer extends ApiTestModule { + public static final int mockServerPort = 8080; + + @Override + public void configure(Binder binder) { + super.configure(binder); + super.config.setBaseApiUrl("http://localhost:" + mockServerPort); + } +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImplTest.java similarity index 65% rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImplTest.java index d0984565a..5b273bda9 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImplTest.java @@ -1,33 +1,53 @@ -package me.chanjar.weixin.cp.api; +package me.chanjar.weixin.cp.api.impl; +import com.github.dreamhead.moco.HttpServer; +import com.github.dreamhead.moco.Runner; import com.google.common.collect.ImmutableMap; -import org.testng.annotations.*; - import com.google.inject.Inject; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.ApiTestModule; +import me.chanjar.weixin.cp.api.ApiTestModuleWithMockServer; +import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.bean.WxCpMessage; import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static com.github.dreamhead.moco.Moco.file; +import static com.github.dreamhead.moco.MocoJsonRunner.jsonHttpServer; +import static me.chanjar.weixin.cp.api.ApiTestModuleWithMockServer.mockServerPort; +import static org.testng.Assert.assertNotNull; -/*** - * 测试发送消息 - * @author Daniel Qian +/** + * 测试类. * + * @author Binary Wang + * @date 2020-08-30 */ @Test -@Guice(modules = ApiTestModule.class) -public class WxCpMessageAPITest { - +@Guice(modules = ApiTestModuleWithMockServer.class) +//@Guice(modules = ApiTestModule.class) +public class WxCpMessageServiceImplTest { @Inject protected WxCpService wxService; + private Runner mockRunner; private ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage; @BeforeTest public void setup() { - configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) this.wxService.getWxCpConfigStorage(); + HttpServer mockServer = jsonHttpServer(mockServerPort, file("src/test/resources/moco/message.json")); + this.mockRunner = Runner.runner(mockServer); + this.mockRunner.start(); + this.configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) this.wxService.getWxCpConfigStorage(); + } + + @AfterTest + public void stopMockServer() { + this.mockRunner.stop(); } public void testSendMessage() throws WxErrorException { @@ -37,7 +57,7 @@ public class WxCpMessageAPITest { message.setToUser(configStorage.getUserId()); message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); - WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message); + WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); assertNotNull(messageSendResult); System.out.println(messageSendResult); System.out.println(messageSendResult.getInvalidPartyList()); @@ -54,7 +74,7 @@ public class WxCpMessageAPITest { .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World") .build(); - WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message); + WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); assertNotNull(messageSendResult); System.out.println(messageSendResult); System.out.println(messageSendResult.getInvalidPartyList()); @@ -82,7 +102,7 @@ public class WxCpMessageAPITest { " >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)") .build(); - WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message); + WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); assertNotNull(messageSendResult); System.out.println(messageSendResult); System.out.println(messageSendResult.getInvalidPartyList()); @@ -96,12 +116,12 @@ public class WxCpMessageAPITest { .TEXTCARD() .toUser(configStorage.getUserId()) .btnTxt("更多") - .description( "
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
") + .description("
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
") .url("URL") .title("领奖通知") .build(); - WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message); + WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); assertNotNull(messageSendResult); System.out.println(messageSendResult); System.out.println(messageSendResult.getInvalidPartyList()); @@ -110,7 +130,7 @@ public class WxCpMessageAPITest { } @Test - public void testSendMessage_miniprogram_notice() throws WxErrorException { + public void testSendMessage_miniProgram_notice() throws WxErrorException { WxCpMessage message = WxCpMessage .newMiniProgramNoticeBuilder() .toUser(configStorage.getUserId()) @@ -119,12 +139,12 @@ public class WxCpMessageAPITest { .title("会议室预订成功通知") .description("4月27日 16:16") .emphasisFirstItem(true) - .contentItems(ImmutableMap.of("会议室","402", - "会议地点","广州TIT-402会议室", - "会议时间","2018年8月1日 09:00-09:30")) + .contentItems(ImmutableMap.of("会议室", "402", + "会议地点", "广州TIT-402会议室", + "会议时间", "2018年8月1日 09:00-09:30")) .build(); - WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message); + WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); assertNotNull(messageSendResult); System.out.println(messageSendResult); System.out.println(messageSendResult.getInvalidPartyList()); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java index be387548b..4cfa51300 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java @@ -49,7 +49,7 @@ public class WxCpTaskCardServiceImplTest { .buttons(Arrays.asList(btn1, btn2)) .build(); - WxCpMessageSendResult messageSendResult = this.wxCpService.messageSend(message); + WxCpMessageSendResult messageSendResult = this.wxCpService.getMessageService().messageSend(message); assertNotNull(messageSendResult); System.out.println(messageSendResult); System.out.println(messageSendResult.getInvalidPartyList()); diff --git a/weixin-java-cp/src/test/resources/moco/message.json b/weixin-java-cp/src/test/resources/moco/message.json new file mode 100644 index 000000000..3714ad5db --- /dev/null +++ b/weixin-java-cp/src/test/resources/moco/message.json @@ -0,0 +1,18 @@ +[ + { + "request": { + "uri": "/cgi-bin/gettoken" + }, + "response": { + "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"access_token\":\"oG1MrhLSzGBl4YxM1W2EHJlL_5vAotNwQ6KBp98sP2fO8XGPPRUlWS9w98CKjxSgPx4YnTy0DU_DvmNXAwt3mSDJ1Uhg_WCFrxX8GWbbCRlzrj2csK-1Y3tzI6dBCMa2YmblBo2sX7qkkzc9pnjP38GzO7Yuo_Bbpyi4doilNWZme0z9ovwiBCkAtV7DXYuh14EsnNrODG454kstOxsqWA\",\"expires_in\":7200}" + } + }, + { + "request": { + "uri": "/cgi-bin/message/send" + }, + "response": { + "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}" + } + } +] From 53ad42e6ac1f52bccbe568d04b614528bc5b8e52 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 30 Aug 2020 18:00:53 +0800 Subject: [PATCH 4/4] =?UTF-8?q?:art:=20#1722=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=A2=9E=E5=8A=A0=E4=BA=92=E8=81=94=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=8F=91=E9=80=81=E5=BA=94=E7=94=A8=E6=B6=88=E6=81=AF=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=B9=B6=E9=87=8D=E6=9E=84=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E7=9B=B8=E5=85=B3=E7=B1=BB=E7=9A=84=E5=8C=85=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/common/api/WxConsts.java | 25 -- .../weixin/cp/api/WxCpChatService.java | 2 +- .../weixin/cp/api/WxCpMessageService.java | 23 +- .../me/chanjar/weixin/cp/api/WxCpService.java | 2 - .../cp/api/impl/WxCpChatServiceImpl.java | 2 +- .../api/impl/WxCpGroupRobotServiceImpl.java | 14 +- .../cp/api/impl/WxCpMessageServiceImpl.java | 18 +- .../weixin/cp/bean/article/NewArticle.java | 4 + .../{ => message}/WxCpAppChatMessage.java | 2 +- .../{ => message}/WxCpGroupRobotMessage.java | 4 +- .../bean/message/WxCpLinkedCorpMessage.java | 244 ++++++++++++ .../cp/bean/{ => message}/WxCpMessage.java | 2 +- .../{ => message}/WxCpMessageSendResult.java | 2 +- .../bean/{ => message}/WxCpTpXmlMessage.java | 2 +- .../cp/bean/{ => message}/WxCpXmlMessage.java | 2 +- .../{ => message}/WxCpXmlOutImageMessage.java | 2 +- .../bean/{ => message}/WxCpXmlOutMessage.java | 2 +- .../{ => message}/WxCpXmlOutNewsMessage.java | 2 +- .../{ => message}/WxCpXmlOutTextMessage.java | 2 +- .../{ => message}/WxCpXmlOutVideoMessage.java | 2 +- .../{ => message}/WxCpXmlOutVoiceMessage.java | 2 +- .../cp/bean/messagebuilder/BaseBuilder.java | 2 +- .../cp/bean/messagebuilder/FileBuilder.java | 2 +- .../cp/bean/messagebuilder/ImageBuilder.java | 2 +- .../messagebuilder/MarkdownMsgBuilder.java | 2 +- .../MiniProgramNoticeMsgBuilder.java | 2 +- .../cp/bean/messagebuilder/MpnewsBuilder.java | 2 +- .../cp/bean/messagebuilder/NewsBuilder.java | 2 +- .../bean/messagebuilder/TaskCardBuilder.java | 2 +- .../cp/bean/messagebuilder/TextBuilder.java | 2 +- .../bean/messagebuilder/TextCardBuilder.java | 2 +- .../cp/bean/messagebuilder/VideoBuilder.java | 2 +- .../cp/bean/messagebuilder/VoiceBuilder.java | 2 +- .../cp/bean/outxmlbuilder/BaseBuilder.java | 2 +- .../cp/bean/outxmlbuilder/ImageBuilder.java | 2 +- .../cp/bean/outxmlbuilder/NewsBuilder.java | 4 +- .../cp/bean/outxmlbuilder/TextBuilder.java | 2 +- .../cp/bean/outxmlbuilder/VideoBuilder.java | 2 +- .../cp/bean/outxmlbuilder/VoiceBuilder.java | 2 +- .../weixin/cp/constant/WxCpConsts.java | 69 ++++ .../weixin/cp/message/WxCpMessageHandler.java | 4 +- .../cp/message/WxCpMessageInterceptor.java | 2 +- .../weixin/cp/message/WxCpMessageMatcher.java | 2 +- .../weixin/cp/message/WxCpMessageRouter.java | 4 +- .../cp/message/WxCpMessageRouterRule.java | 4 +- .../cp/util/xml/XStreamTransformer.java | 270 ++++++------- .../weixin/cp/api/WxCpMessageRouterTest.java | 4 +- .../cp/api/impl/WxCpChatServiceImplTest.java | 2 +- .../impl/WxCpGroupRobotServiceImplTest.java | 5 +- .../api/impl/WxCpMessageServiceImplTest.java | 24 +- .../api/impl/WxCpTaskCardServiceImplTest.java | 6 +- .../message/WxCpLinkedCorpMessageTest.java | 374 ++++++++++++++++++ .../bean/{ => message}/WxCpMessageTest.java | 3 +- .../{ => message}/WxCpXmlMessageTest.java | 3 +- .../WxCpXmlOutImageMessageTest.java | 4 +- .../WxCpXmlOutNewsMessageTest.java | 4 +- .../WxCpXmlOutTextMessageTest.java | 4 +- .../WxCpXmlOutVideoMessageTest.java | 4 +- .../WxCpXmlOutVoiceMessageTest.java | 4 +- .../weixin/cp/demo/WxCpDemoServer.java | 6 +- .../weixin/cp/demo/WxCpEndpointServlet.java | 4 +- .../src/test/resources/moco/message.json | 8 + weixin-java-cp/src/test/resources/testng.xml | 14 +- 63 files changed, 974 insertions(+), 252 deletions(-) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpAppChatMessage.java (99%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpGroupRobotMessage.java (96%) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpMessage.java (99%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpMessageSendResult.java (97%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpTpXmlMessage.java (97%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlMessage.java (99%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutImageMessage.java (94%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutMessage.java (98%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutNewsMessage.java (97%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutTextMessage.java (94%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutVideoMessage.java (97%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutVoiceMessage.java (94%) create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessageTest.java rename weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpMessageTest.java (98%) rename weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlMessageTest.java (99%) rename weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutImageMessageTest.java (89%) rename weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutNewsMessageTest.java (95%) rename weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutTextMessageTest.java (89%) rename weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutVideoMessageTest.java (91%) rename weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/{ => message}/WxCpXmlOutVoiceMessageTest.java (89%) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java index 99acd4f86..1e953d080 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java @@ -121,31 +121,6 @@ public class WxConsts { public static final String MINIPROGRAM_NOTICE = "miniprogram_notice"; } - /** - * 群机器人的消息类型. - */ - public static class GroupRobotMsgType { - /** - * 文本消息. - */ - public static final String TEXT = "text"; - - /** - * 图片消息. - */ - public static final String IMAGE = "image"; - - /** - * markdown消息. - */ - public static final String MARKDOWN = "markdown"; - - /** - * 图文消息(点击跳转到外链). - */ - public static final String NEWS = "news"; - } - /** * 表示是否是保密消息,0表示否,1表示是,默认0. */ diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java index 462ec7507..9c825d891 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.api; import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.cp.bean.WxCpAppChatMessage; +import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage; import me.chanjar.weixin.cp.bean.WxCpChat; import java.util.List; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java index d8a6cc2a7..2c5d82f59 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageService.java @@ -1,8 +1,9 @@ package me.chanjar.weixin.cp.api; import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.cp.bean.WxCpMessage; -import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; +import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage; +import me.chanjar.weixin.cp.bean.message.WxCpMessage; +import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult; /** * 消息推送接口. @@ -14,12 +15,26 @@ public interface WxCpMessageService { /** *
    * 发送消息
-   * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E
+   * 详情请见: https://work.weixin.qq.com/api/doc/90000/90135/90236
    * 
* * @param message 要发送的消息对象 * @return the wx cp message send result * @throws WxErrorException the wx error exception */ - WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException; + WxCpMessageSendResult send(WxCpMessage message) throws WxErrorException; + + /** + *
+   * 互联企业的应用支持推送文本、图片、视频、文件、图文等类型。
+   *
+   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/linkedcorp/message/send?access_token=ACCESS_TOKEN
+   * 文章地址:https://work.weixin.qq.com/api/doc/90000/90135/90250
+   * 
+ * + * @param message 要发送的消息对象 + * @return the wx cp message send result + * @throws WxErrorException the wx error exception + */ + WxCpMessageSendResult sendLinkedCorpMessage(WxCpLinkedCorpMessage message) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 7c1d4857b..3378f8862 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -8,8 +8,6 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult; -import me.chanjar.weixin.cp.bean.WxCpMessage; -import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; import me.chanjar.weixin.cp.bean.WxCpProviderToken; import me.chanjar.weixin.cp.config.WxCpConfigStorage; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java index 10af36afe..7783422af 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java @@ -6,7 +6,7 @@ import me.chanjar.weixin.common.util.json.GsonParser; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.cp.api.WxCpChatService; import me.chanjar.weixin.cp.api.WxCpService; -import me.chanjar.weixin.cp.bean.WxCpAppChatMessage; +import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage; import me.chanjar.weixin.cp.bean.WxCpChat; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; import org.apache.commons.lang3.StringUtils; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImpl.java index ed4d8a108..c5e71f5f2 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImpl.java @@ -1,17 +1,19 @@ package me.chanjar.weixin.cp.api.impl; import lombok.RequiredArgsConstructor; -import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpGroupRobotService; import me.chanjar.weixin.cp.api.WxCpService; -import me.chanjar.weixin.cp.bean.WxCpGroupRobotMessage; import me.chanjar.weixin.cp.bean.article.NewArticle; +import me.chanjar.weixin.cp.bean.message.WxCpGroupRobotMessage; import me.chanjar.weixin.cp.config.WxCpConfigStorage; import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; import java.util.List; +import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType; +import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType.*; + /** * 微信群机器人消息发送api 实现 * @@ -30,7 +32,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService { @Override public void sendText(String content, List mentionedList, List mobileList) throws WxErrorException { WxCpGroupRobotMessage message = new WxCpGroupRobotMessage() - .setMsgType(WxConsts.GroupRobotMsgType.TEXT) + .setMsgType(TEXT) .setContent(content) .setMentionedList(mentionedList) .setMentionedMobileList(mobileList); @@ -40,7 +42,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService { @Override public void sendMarkDown(String content) throws WxErrorException { WxCpGroupRobotMessage message = new WxCpGroupRobotMessage() - .setMsgType(WxConsts.GroupRobotMsgType.MARKDOWN) + .setMsgType(MARKDOWN) .setContent(content); cpService.postWithoutToken(this.getApiUrl(), message.toJson()); } @@ -48,7 +50,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService { @Override public void sendImage(String base64, String md5) throws WxErrorException { WxCpGroupRobotMessage message = new WxCpGroupRobotMessage() - .setMsgType(WxConsts.GroupRobotMsgType.IMAGE) + .setMsgType(GroupRobotMsgType.IMAGE) .setBase64(base64) .setMd5(md5); cpService.postWithoutToken(this.getApiUrl(), message.toJson()); @@ -57,7 +59,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService { @Override public void sendNews(List articleList) throws WxErrorException { WxCpGroupRobotMessage message = new WxCpGroupRobotMessage() - .setMsgType(WxConsts.GroupRobotMsgType.NEWS) + .setMsgType(GroupRobotMsgType.NEWS) .setArticles(articleList); cpService.postWithoutToken(this.getApiUrl(), message.toJson()); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java index 533f954bf..308d89920 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java @@ -4,8 +4,9 @@ import lombok.RequiredArgsConstructor; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpMessageService; import me.chanjar.weixin.cp.api.WxCpService; -import me.chanjar.weixin.cp.bean.WxCpMessage; -import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; +import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage; +import me.chanjar.weixin.cp.bean.message.WxCpMessage; +import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult; import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; /** @@ -19,7 +20,7 @@ public class WxCpMessageServiceImpl implements WxCpMessageService { private final WxCpService cpService; @Override - public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException { + public WxCpMessageSendResult send(WxCpMessage message) throws WxErrorException { Integer agentId = message.getAgentId(); if (null == agentId) { message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId()); @@ -28,4 +29,15 @@ public class WxCpMessageServiceImpl implements WxCpMessageService { return WxCpMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage() .getApiUrl(WxCpApiPathConsts.Message.MESSAGE_SEND), message.toJson())); } + + @Override + public WxCpMessageSendResult sendLinkedCorpMessage(WxCpLinkedCorpMessage message) throws WxErrorException { + Integer agentId = message.getAgentId(); + if (null == agentId) { + message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId()); + } + + return WxCpMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage() + .getApiUrl(WxCpApiPathConsts.Message.LINKEDCORP_MESSAGE_SEND), message.toJson())); + } } 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 5eede5fa5..854c0ca89 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 @@ -37,4 +37,8 @@ public class NewArticle implements Serializable { */ private String picUrl; + /** + * 按钮文字,仅在图文数为1条时才生效。 默认为“阅读全文”, 不超过4个文字,超过自动截断。该设置只在企业微信上生效,微工作台(原企业号)上不生效。 + */ + private String btnText; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpAppChatMessage.java similarity index 99% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpAppChatMessage.java index 9aa2a2fc4..10dd3c1b2 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpAppChatMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.google.gson.JsonArray; import com.google.gson.JsonObject; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpGroupRobotMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpGroupRobotMessage.java similarity index 96% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpGroupRobotMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpGroupRobotMessage.java index 937a88cb0..c97e5eb16 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpGroupRobotMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpGroupRobotMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -10,7 +10,7 @@ import me.chanjar.weixin.cp.bean.article.NewArticle; import java.util.List; -import static me.chanjar.weixin.common.api.WxConsts.GroupRobotMsgType.*; +import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType.*; /** * 微信群机器人消息 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java new file mode 100644 index 000000000..0e3f67087 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java @@ -0,0 +1,244 @@ +package me.chanjar.weixin.cp.bean.message; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.cp.bean.article.MpnewsArticle; +import me.chanjar.weixin.cp.bean.article.NewArticle; +import org.apache.commons.lang3.ArrayUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType.*; + +/** + * 互联企业消息. + * + * @author Binary Wang + * @date 2020-08-30 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpLinkedCorpMessage implements Serializable { + private static final long serialVersionUID = 8833792280163704238L; + + /** + * 1表示发送给应用可见范围内的所有人(包括互联企业的成员),默认为0 + */ + private Boolean isToAll; + + /** + * 成员ID列表(消息接收者,最多支持1000个)。每个元素的格式为: corpid/userid,其中,corpid为该互联成员所属的企业,userid为该互联成员所属企业中的帐号。如果是本企业的成员,则直接传userid即可 + */ + private String[] toUsers; + /** + * 部门ID列表,最多支持100个。partyid在互联圈子内唯一。每个元素都是字符串类型,格式为:linked_id/party_id,其中linked_id是互联id,party_id是在互联圈子中的部门id。如果是本企业的部门,则直接传party_id即可。 + */ + private String[] toParties; + /** + * 本企业的标签ID列表,最多支持100个。 + */ + private String[] toTags; + + /** + * 企业应用的id,整型。可在应用的设置页面查看 + */ + private Integer agentId; + private String msgType; + /** + * 消息内容,最长不超过2048个字节 + */ + private String content; + + /** + * 图片媒体文件id,可以调用上传临时素材接口获取 + */ + private String mediaId; + private String thumbMediaId; + private String title; + private String description; + /** + * 表示是否是保密消息,0表示否,1表示是,默认0 + */ + private Boolean isSafe; + private String url; + private String btnTxt; + private List articles = new ArrayList<>(); + private List mpNewsArticles = new ArrayList<>(); + private String appId; + private String page; + private Boolean emphasisFirstItem; + private Map contentItems; + + /** + *
+   * 请使用.
+   * {@link LinkedCorpMsgType#TEXT}
+   * {@link LinkedCorpMsgType#IMAGE}
+   * {@link LinkedCorpMsgType#VIDEO}
+   * {@link LinkedCorpMsgType#NEWS}
+   * {@link LinkedCorpMsgType#MPNEWS}
+   * {@link LinkedCorpMsgType#MARKDOWN}
+   * {@link LinkedCorpMsgType#MINIPROGRAM_NOTICE}
+   * 
+ * + * @param msgType 消息类型 + */ + public void setMsgType(String msgType) { + this.msgType = msgType; + } + + public String toJson() { + JsonObject messageJson = new JsonObject(); + + if (ArrayUtils.isNotEmpty(this.getToUsers())) { + messageJson.add("touser", WxGsonBuilder.create().toJsonTree(this.getToUsers())); + } + + if (ArrayUtils.isNotEmpty(this.getToParties())) { + messageJson.add("toparty", WxGsonBuilder.create().toJsonTree(this.getToParties())); + } + + if (ArrayUtils.isNotEmpty(this.getToTags())) { + messageJson.add("totag", WxGsonBuilder.create().toJsonTree(this.getToTags())); + } + + if (this.getIsToAll() != null) { + messageJson.addProperty("toall", this.getIsToAll() ? 1 : 0); + } + messageJson.addProperty("msgtype", this.getMsgType()); + + if (this.getAgentId() != null) { + messageJson.addProperty("agentid", this.getAgentId()); + } + + this.handleMsgType(messageJson); + + if (this.getIsSafe() != null) { + messageJson.addProperty("safe", this.getIsSafe() ? 1 : 0); + } + + return messageJson.toString(); + } + + private void handleMsgType(JsonObject messageJson) { + switch (this.getMsgType()) { + case TEXT: { + JsonObject text = new JsonObject(); + text.addProperty("content", this.getContent()); + messageJson.add("text", text); + break; + } + case MARKDOWN: { + JsonObject text = new JsonObject(); + text.addProperty("content", this.getContent()); + messageJson.add("markdown", text); + break; + } + case TEXTCARD: { + JsonObject text = new JsonObject(); + text.addProperty("title", this.getTitle()); + text.addProperty("description", this.getDescription()); + text.addProperty("url", this.getUrl()); + text.addProperty("btntxt", this.getBtnTxt()); + messageJson.add("textcard", text); + break; + } + case IMAGE: { + JsonObject image = new JsonObject(); + image.addProperty("media_id", this.getMediaId()); + messageJson.add("image", image); + break; + } + case FILE: { + JsonObject image = new JsonObject(); + image.addProperty("media_id", this.getMediaId()); + messageJson.add("file", image); + break; + } + case VIDEO: { + JsonObject video = new JsonObject(); + video.addProperty("media_id", this.getMediaId()); + video.addProperty("title", this.getTitle()); + video.addProperty("description", this.getDescription()); + messageJson.add("video", video); + break; + } + case NEWS: { + JsonObject newsJsonObject = new JsonObject(); + JsonArray articleJsonArray = new JsonArray(); + for (NewArticle article : this.getArticles()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("title", article.getTitle()); + articleJson.addProperty("description", article.getDescription()); + articleJson.addProperty("url", article.getUrl()); + articleJson.addProperty("picurl", article.getPicUrl()); + articleJson.addProperty("btntxt", article.getBtnText()); + articleJsonArray.add(articleJson); + } + newsJsonObject.add("articles", articleJsonArray); + messageJson.add("news", newsJsonObject); + break; + } + case MPNEWS: { + JsonObject newsJsonObject = new JsonObject(); + if (this.getMediaId() != null) { + newsJsonObject.addProperty("media_id", this.getMediaId()); + } else { + JsonArray articleJsonArray = new JsonArray(); + for (MpnewsArticle article : this.getMpNewsArticles()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("title", article.getTitle()); + articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); + articleJson.addProperty("author", article.getAuthor()); + articleJson.addProperty("content_source_url", article.getContentSourceUrl()); + articleJson.addProperty("content", article.getContent()); + articleJson.addProperty("digest", article.getDigest()); + if (article.getShowCoverPic() != null) { + articleJson.addProperty("show_cover_pic", article.getShowCoverPic()); + } + articleJsonArray.add(articleJson); + } + + newsJsonObject.add("articles", articleJsonArray); + } + messageJson.add("mpnews", newsJsonObject); + break; + } + case MINIPROGRAM_NOTICE: { + JsonObject notice = new JsonObject(); + notice.addProperty("appid", this.getAppId()); + notice.addProperty("page", this.getPage()); + notice.addProperty("title", this.getTitle()); + notice.addProperty("description", this.getDescription()); + notice.addProperty("emphasis_first_item", this.getEmphasisFirstItem()); + JsonArray content = new JsonArray(); + for (Map.Entry item : this.getContentItems().entrySet()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("key", item.getKey()); + articleJson.addProperty("value", item.getValue()); + content.add(articleJson); + } + notice.add("content_item", content); + + messageJson.add("miniprogram_notice", notice); + break; + } + default: { + // do nothing + } + } + } + +} 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/message/WxCpMessage.java similarity index 99% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java index b39c2229e..9c579fd0d 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/message/WxCpMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.google.gson.JsonArray; import com.google.gson.JsonObject; 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/message/WxCpMessageSendResult.java similarity index 97% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessageSendResult.java index d850adebc..fa1db1065 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/message/WxCpMessageSendResult.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import java.io.Serializable; import java.util.Collections; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlMessage.java similarity index 97% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlMessage.java index f39b062c0..6ee139538 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import java.io.Serializable; import java.util.Map; 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/message/WxCpXmlMessage.java similarity index 99% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java index 85c6d9913..a035f1d54 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/message/WxCpXmlMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; 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/message/WxCpXmlOutImageMessage.java similarity index 94% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutImageMessage.java index cbef3f876..99792a2bf 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/message/WxCpXmlOutImageMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; 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/message/WxCpXmlOutMessage.java similarity index 98% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutMessage.java index a053a5460..96991a540 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/message/WxCpXmlOutMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import java.io.Serializable; 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/message/WxCpXmlOutNewsMessage.java similarity index 97% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutNewsMessage.java index c8149cabf..87b0ca9de 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/message/WxCpXmlOutNewsMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; 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/message/WxCpXmlOutTextMessage.java similarity index 94% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutTextMessage.java index 6589b0b3b..dfae8fef4 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/message/WxCpXmlOutTextMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; 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/message/WxCpXmlOutVideoMessage.java similarity index 97% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVideoMessage.java index f4aabd182..c16d682a3 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/message/WxCpXmlOutVideoMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; 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/message/WxCpXmlOutVoiceMessage.java similarity index 94% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVoiceMessage.java index efe4a86fc..7a2e0e49c 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/message/WxCpXmlOutVoiceMessage.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java index 1064f0052..ec312c6fb 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.bean.messagebuilder; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.message.WxCpMessage; import org.apache.commons.lang3.StringUtils; public class BaseBuilder { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java index f67cf6e50..6b36cf6cf 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.bean.messagebuilder; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.message.WxCpMessage; /** * 获得消息builder diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java index ddf3b7373..6735385c9 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.bean.messagebuilder; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.message.WxCpMessage; /** * 获得消息builder diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java index 6e0a4a330..6b6af40ac 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.bean.messagebuilder; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.message.WxCpMessage; /** *
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java
index cf44c0f0f..928ea3863 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.messagebuilder;
 
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
 
 import java.util.Map;
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java
index 75739803f..bc1467e14 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.messagebuilder;
 
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
 import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
 
 import java.util.ArrayList;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java
index 9d0d2f603..ef661e6ed 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.messagebuilder;
 
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
 import me.chanjar.weixin.cp.bean.article.NewArticle;
 
 import java.util.ArrayList;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java
index 3c2d77924..57a77503b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.messagebuilder;
 
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
 import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
 
 import java.util.List;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java
index 5079b5f84..e072b9a79 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.messagebuilder;
 
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
 
 /**
  * 文本消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java
index 6cae763d1..306187ee4 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.messagebuilder;
 
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
 
 /**
  * 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java
index 8d4739940..2c7fab5c8 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.messagebuilder;
 
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
 
 /**
  * 视频消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java
index 33c36abcb..0e0b9f828 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.messagebuilder;
 
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
 
 /**
  * 语音消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java
index 303ed3c46..90495a463 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java
@@ -1,6 +1,6 @@
 package me.chanjar.weixin.cp.bean.outxmlbuilder;
 
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
 
 public abstract class BaseBuilder {
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java
index f8cd25f44..ded7e157e 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java
@@ -1,6 +1,6 @@
 package me.chanjar.weixin.cp.bean.outxmlbuilder;
 
-import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
 
 /**
  * 图片消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
index 5a67056ab..190ab1c97 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
@@ -1,7 +1,7 @@
 package me.chanjar.weixin.cp.bean.outxmlbuilder;
 
-import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage.Item;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage.Item;
 
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java
index dcdb58ca4..6a7086845 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java
@@ -1,6 +1,6 @@
 package me.chanjar.weixin.cp.bean.outxmlbuilder;
 
-import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
 
 /**
  * 文本消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java
index 7eb38ec1a..e823da746 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java
@@ -1,6 +1,6 @@
 package me.chanjar.weixin.cp.bean.outxmlbuilder;
 
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage;
 
 /**
  * 视频消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java
index 8bc13d9fe..2d1466124 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java
@@ -1,6 +1,6 @@
 package me.chanjar.weixin.cp.bean.outxmlbuilder;
 
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage;
 
 /**
  * 语音消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
index a69b8ea2e..5e536efa9 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
@@ -166,6 +166,75 @@ public class WxCpConsts {
 
   }
 
+  /**
+   * 互联企业发送应用消息的消息类型.
+   */
+  public static class LinkedCorpMsgType {
+    /**
+     * 文本消息.
+     */
+    public static final String TEXT = "text";
+    /**
+     * 图片消息.
+     */
+    public static final String IMAGE = "image";
+    /**
+     * 视频消息.
+     */
+    public static final String VIDEO = "video";
+    /**
+     * 图文消息(点击跳转到外链).
+     */
+    public static final String NEWS = "news";
+    /**
+     * 图文消息(点击跳转到图文消息页面).
+     */
+    public static final String MPNEWS = "mpnews";
+    /**
+     * markdown消息.
+     * (目前仅支持markdown语法的子集,微工作台(原企业号)不支持展示markdown消息)
+     */
+    public static final String MARKDOWN = "markdown";
+    /**
+     * 发送文件.
+     */
+    public static final String FILE = "file";
+    /**
+     * 文本卡片消息.
+     */
+    public static final String TEXTCARD = "textcard";
+
+    /**
+     * 小程序通知消息.
+     */
+    public static final String MINIPROGRAM_NOTICE = "miniprogram_notice";
+  }
+
+  /**
+   * 群机器人的消息类型.
+   */
+  public static class GroupRobotMsgType {
+    /**
+     * 文本消息.
+     */
+    public static final String TEXT = "text";
+
+    /**
+     * 图片消息.
+     */
+    public static final String IMAGE = "image";
+
+    /**
+     * markdown消息.
+     */
+    public static final String MARKDOWN = "markdown";
+
+    /**
+     * 图文消息(点击跳转到外链).
+     */
+    public static final String NEWS = "news";
+  }
+
   /**
    * 应用推送消息的消息类型.
    */
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java
index 22074d6e7..68e38d3bb 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java
@@ -3,8 +3,8 @@ package me.chanjar.weixin.cp.message;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.session.WxSessionManager;
 import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
 
 import java.util.Map;
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java
index ab4c658e4..5bcca55ee 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java
@@ -3,7 +3,7 @@ package me.chanjar.weixin.cp.message;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.session.WxSessionManager;
 import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
 
 import java.util.Map;
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageMatcher.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageMatcher.java
index 1bf36705b..42db8f5dd 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageMatcher.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageMatcher.java
@@ -1,6 +1,6 @@
 package me.chanjar.weixin.cp.message;
 
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
 
 /**
  * 消息匹配器,用在消息路由的时候
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
index b5424be03..bf1ad6e5f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
@@ -18,8 +18,8 @@ import me.chanjar.weixin.common.session.InternalSessionManager;
 import me.chanjar.weixin.common.session.WxSessionManager;
 import me.chanjar.weixin.common.util.LogExceptionHandler;
 import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
 
 /**
  * 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java
index 8f3766a16..3c7b5c66f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java
@@ -4,8 +4,8 @@ import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.session.WxSessionManager;
 import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.ArrayList;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
index 3c6174c9d..ea9023111 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
@@ -1,135 +1,135 @@
-package me.chanjar.weixin.cp.util.xml;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.thoughtworks.xstream.XStream;
-import me.chanjar.weixin.common.util.xml.XStreamInitializer;
-import me.chanjar.weixin.cp.bean.WxCpTpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage;
-
-public class XStreamTransformer {
-
-  protected static final Map CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
-
-  /**
-   * 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;
-  }
-
-  /**
-   * 注册扩展消息的解析器.
-   *
-   * @param clz     类型
-   * @param xStream xml解析器
-   */
-  public static void register(Class clz, XStream xStream) {
-    CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
-  }
-
-  /**
-   * pojo -> xml.
-   */
-  public static  String toXml(Class clazz, T object) {
-    return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
-  }
-
-  private static Map configXStreamInstance() {
-    Map map = new HashMap<>();
-    map.put(WxCpXmlMessage.class, configWxCpXmlMessage());
-    map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage());
-    map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage());
-    map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage());
-    map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage());
-    map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage());
-    map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage());
-    map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage());
-    return map;
-  }
-
-  private static XStream configWxCpXmlMessage() {
-    XStream xstream = XStreamInitializer.getInstance();
-
-    xstream.processAnnotations(WxCpXmlMessage.class);
-    xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
-    xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
-    xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
-    xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
-    return xstream;
-  }
-
-  private static XStream configWxCpXmlOutImageMessage() {
-    XStream xstream = XStreamInitializer.getInstance();
-
-    xstream.processAnnotations(WxCpXmlOutMessage.class);
-    xstream.processAnnotations(WxCpXmlOutImageMessage.class);
-    return xstream;
-  }
-
-  private static XStream configWxCpXmlOutNewsMessage() {
-    XStream xstream = XStreamInitializer.getInstance();
-
-    xstream.processAnnotations(WxCpXmlOutMessage.class);
-    xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
-    xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
-    return xstream;
-  }
-
-  private static XStream configWxCpXmlOutTextMessage() {
-    XStream xstream = XStreamInitializer.getInstance();
-
-    xstream.processAnnotations(WxCpXmlOutMessage.class);
-    xstream.processAnnotations(WxCpXmlOutTextMessage.class);
-    return xstream;
-  }
-
-  private static XStream configWxCpXmlOutVideoMessage() {
-    XStream xstream = XStreamInitializer.getInstance();
-
-    xstream.processAnnotations(WxCpXmlOutMessage.class);
-    xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
-    xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
-    return xstream;
-  }
-
-  private static XStream configWxCpXmlOutVoiceMessage() {
-    XStream xstream = XStreamInitializer.getInstance();
-
-    xstream.processAnnotations(WxCpXmlOutMessage.class);
-    xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
-    return xstream;
-  }
-  
-  private static XStream configWxCpTpXmlPackage() {
-    XStream xstream = XStreamInitializer.getInstance();
-    xstream.processAnnotations(WxCpTpXmlPackage.class);
-    
-    return xstream;
-  }
-  
-  private static XStream configWxCpTpXmlMessage() {
-    XStream xstream = XStreamInitializer.getInstance();
-    xstream.processAnnotations(WxCpTpXmlMessage.class);
-    
-    return xstream;
-  }
-
-}
+package me.chanjar.weixin.cp.util.xml;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.thoughtworks.xstream.XStream;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage;
+import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage;
+
+public class XStreamTransformer {
+
+  protected static final Map CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
+
+  /**
+   * 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;
+  }
+
+  /**
+   * 注册扩展消息的解析器.
+   *
+   * @param clz     类型
+   * @param xStream xml解析器
+   */
+  public static void register(Class clz, XStream xStream) {
+    CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
+  }
+
+  /**
+   * pojo -> xml.
+   */
+  public static  String toXml(Class clazz, T object) {
+    return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
+  }
+
+  private static Map configXStreamInstance() {
+    Map map = new HashMap<>();
+    map.put(WxCpXmlMessage.class, configWxCpXmlMessage());
+    map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage());
+    map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage());
+    map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage());
+    map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage());
+    map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage());
+    map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage());
+    map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage());
+    return map;
+  }
+
+  private static XStream configWxCpXmlMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+
+    xstream.processAnnotations(WxCpXmlMessage.class);
+    xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
+    xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
+    xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
+    xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
+    return xstream;
+  }
+
+  private static XStream configWxCpXmlOutImageMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutImageMessage.class);
+    return xstream;
+  }
+
+  private static XStream configWxCpXmlOutNewsMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
+    xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
+    return xstream;
+  }
+
+  private static XStream configWxCpXmlOutTextMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutTextMessage.class);
+    return xstream;
+  }
+
+  private static XStream configWxCpXmlOutVideoMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
+    xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
+    return xstream;
+  }
+
+  private static XStream configWxCpXmlOutVoiceMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
+    return xstream;
+  }
+
+  private static XStream configWxCpTpXmlPackage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpTpXmlPackage.class);
+
+    return xstream;
+  }
+
+  private static XStream configWxCpTpXmlMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpTpXmlMessage.class);
+
+    return xstream;
+  }
+
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
index a21348895..112e9f8c3 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
@@ -6,8 +6,8 @@ import me.chanjar.weixin.common.session.WxSessionManager;
 import me.chanjar.weixin.cp.message.WxCpMessageHandler;
 import me.chanjar.weixin.cp.message.WxCpMessageMatcher;
 import me.chanjar.weixin.cp.message.WxCpMessageRouter;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
index 0056b88f7..56df47e36 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
@@ -11,7 +11,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.cp.constant.WxCpConsts.AppChatMsgType;
 import me.chanjar.weixin.cp.api.ApiTestModule;
 import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage;
 import me.chanjar.weixin.cp.bean.WxCpChat;
 import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
 import me.chanjar.weixin.cp.bean.article.NewArticle;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImplTest.java
index b697efd53..40597fa24 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImplTest.java
@@ -16,8 +16,6 @@ import java.io.InputStream;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import static org.testng.Assert.*;
-
 /**
  * 微信群机器人消息发送api 单元测试
  *
@@ -62,7 +60,8 @@ public class WxCpGroupRobotServiceImplTest {
 
   @Test
   public void testSendNews() throws WxErrorException {
-    NewArticle article = new NewArticle("图文消息测试","hello world","http://www.baidu.com","http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png");
+    NewArticle article = new NewArticle("图文消息测试", "hello world", "http://www.baidu.com",
+      "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png", null);
     robotService.sendNews(Stream.of(article).collect(Collectors.toList()));
   }
 }
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImplTest.java
index 5b273bda9..8f02df1fc 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImplTest.java
@@ -9,8 +9,9 @@ import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.cp.api.ApiTestModule;
 import me.chanjar.weixin.cp.api.ApiTestModuleWithMockServer;
 import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
-import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
+import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
 import org.testng.annotations.AfterTest;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Guice;
@@ -57,7 +58,7 @@ public class WxCpMessageServiceImplTest {
     message.setToUser(configStorage.getUserId());
     message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World");
 
-    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message);
+    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
     assertNotNull(messageSendResult);
     System.out.println(messageSendResult);
     System.out.println(messageSendResult.getInvalidPartyList());
@@ -74,7 +75,7 @@ public class WxCpMessageServiceImplTest {
       .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World")
       .build();
 
-    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message);
+    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
     assertNotNull(messageSendResult);
     System.out.println(messageSendResult);
     System.out.println(messageSendResult.getInvalidPartyList());
@@ -102,7 +103,7 @@ public class WxCpMessageServiceImplTest {
         "                >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)")
       .build();
 
-    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message);
+    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
     assertNotNull(messageSendResult);
     System.out.println(messageSendResult);
     System.out.println(messageSendResult.getInvalidPartyList());
@@ -121,7 +122,7 @@ public class WxCpMessageServiceImplTest {
       .title("领奖通知")
       .build();
 
-    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message);
+    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
     assertNotNull(messageSendResult);
     System.out.println(messageSendResult);
     System.out.println(messageSendResult.getInvalidPartyList());
@@ -144,11 +145,20 @@ public class WxCpMessageServiceImplTest {
         "会议时间", "2018年8月1日 09:00-09:30"))
       .build();
 
-    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message);
+    WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
     assertNotNull(messageSendResult);
     System.out.println(messageSendResult);
     System.out.println(messageSendResult.getInvalidPartyList());
     System.out.println(messageSendResult.getInvalidUserList());
     System.out.println(messageSendResult.getInvalidTagList());
   }
+
+  @Test
+  public void testLinkedCorpMessageSend() throws WxErrorException {
+    this.wxService.getMessageService().sendLinkedCorpMessage(WxCpLinkedCorpMessage.builder()
+      .msgType(WxConsts.KefuMsgType.TEXT)
+      .toUsers(new String[]{configStorage.getUserId()})
+      .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World")
+      .build());
+  }
 }
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java
index 4cfa51300..1bdcb9e24 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java
@@ -4,8 +4,8 @@ import com.google.inject.Inject;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.cp.api.ApiTestModule;
 import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
-import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
 import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
@@ -49,7 +49,7 @@ public class WxCpTaskCardServiceImplTest {
       .buttons(Arrays.asList(btn1, btn2))
       .build();
 
-    WxCpMessageSendResult messageSendResult = this.wxCpService.getMessageService().messageSend(message);
+    WxCpMessageSendResult messageSendResult = this.wxCpService.getMessageService().send(message);
     assertNotNull(messageSendResult);
     System.out.println(messageSendResult);
     System.out.println(messageSendResult.getInvalidPartyList());
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessageTest.java
new file mode 100644
index 000000000..d692d0fc9
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessageTest.java
@@ -0,0 +1,374 @@
+package me.chanjar.weixin.cp.bean.message;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.util.json.GsonParser;
+import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
+import me.chanjar.weixin.cp.bean.article.NewArticle;
+import org.testng.annotations.Test;
+
+import static me.chanjar.weixin.common.api.WxConsts.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * 测试用例中的json参考 https://work.weixin.qq.com/api/doc/90000/90135/90250
+ *
+ * @author Binary Wang
+ * @date 2020-08-30
+ */
+public class WxCpLinkedCorpMessageTest {
+
+  @Test
+  public void testToJson_text() {
+    WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+      .msgType(KefuMsgType.TEXT)
+      .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+      .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+      .toTags(new String[]{"tagid1", "tagid2"})
+      .agentId(1)
+      .isToAll(false)
+      .isSafe(false)
+      .content("你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看邮件中心视频实况,聪明避开排队。")
+      .build();
+
+    final String json = message.toJson();
+    String expectedJson = "{\n" +
+      "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+      "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+      "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+      "    \"toall\" : 0,\n" +
+      "    \"msgtype\" : \"text\",\n" +
+      "   \"agentid\" : 1,\n" +
+      "   \"text\" : {\n" +
+      "       \"content\" : \"你的快递已到,请携带工卡前往邮件中心领取。\\n出发前可查看邮件中心视频实况,聪明避开排队。\"\n" +
+      "   },\n" +
+      "   \"safe\":0\n" +
+      "}";
+
+    assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+  }
+
+  @Test
+  public void testToJson_image() {
+    WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+      .msgType(KefuMsgType.IMAGE)
+      .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+      .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+      .toTags(new String[]{"tagid1", "tagid2"})
+      .agentId(1)
+      .isToAll(false)
+      .isSafe(false)
+      .mediaId("MEDIA_ID")
+      .build();
+
+    final String json = message.toJson();
+    String expectedJson = "{\n" +
+      "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+      "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+      "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+      "    \"toall\" : 0,\n" +
+      "   \"msgtype\" : \"image\",\n" +
+      "   \"agentid\" : 1,\n" +
+      "   \"image\" : {\n" +
+      "        \"media_id\" : \"MEDIA_ID\"\n" +
+      "   },\n" +
+      "   \"safe\":0\n" +
+      "}";
+
+    assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+  }
+
+  @Test
+  public void testToJson_video() {
+    WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+      .msgType(KefuMsgType.VIDEO)
+      .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+      .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+      .toTags(new String[]{"tagid1", "tagid2"})
+      .agentId(1)
+      .isToAll(false)
+      .isSafe(false)
+      .mediaId("MEDIA_ID")
+      .title("Title")
+      .description("Description")
+      .build();
+
+    final String json = message.toJson();
+    String expectedJson = "{\n" +
+      "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+      "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+      "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+      "    \"toall\" : 0,\n" +
+      "   \"msgtype\" : \"video\",\n" +
+      "   \"agentid\" : 1,\n" +
+      "   \"video\" : {\n" +
+      "        \"media_id\" : \"MEDIA_ID\",\n" +
+      "        \"title\" : \"Title\",\n" +
+      "       \"description\" : \"Description\"\n" +
+      "   },\n" +
+      "   \"safe\":0\n" +
+      "}\n";
+
+    assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+  }
+
+  @Test
+  public void testToJson_file() {
+    WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+      .msgType(KefuMsgType.FILE)
+      .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+      .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+      .toTags(new String[]{"tagid1", "tagid2"})
+      .agentId(1)
+      .isToAll(false)
+      .isSafe(false)
+      .mediaId("1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o")
+      .build();
+
+    final String json = message.toJson();
+    String expectedJson = "{\n" +
+      "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+      "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+      "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+      "    \"toall\" : 0,\n" +
+      "   \"msgtype\" : \"file\",\n" +
+      "   \"agentid\" : 1,\n" +
+      "   \"file\" : {\n" +
+      "        \"media_id\" : \"1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o\"\n" +
+      "   },\n" +
+      "   \"safe\":0\n" +
+      "}\n";
+
+    assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+  }
+
+  @Test
+  public void testToJson_textCard() {
+    WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+      .msgType(KefuMsgType.TEXTCARD)
+      .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+      .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+      .toTags(new String[]{"tagid1", "tagid2"})
+      .agentId(1)
+      .isToAll(false)
+      .title("领奖通知")
+      .description("
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
") + .url("URL") + .btnTxt("更多") + .build(); + + final String json = message.toJson(); + String expectedJson = "{\n" + + " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + + " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + + " \"totag\" : [\"tagid1\",\"tagid2\"],\n" + + " \"toall\" : 0,\n" + + " \"msgtype\" : \"textcard\",\n" + + " \"agentid\" : 1,\n" + + " \"textcard\" : {\n" + + " \"title\" : \"领奖通知\",\n" + + " \"description\" : \"
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
\",\n" + + " \"url\" : \"URL\",\n" + + " \"btntxt\":\"更多\"\n" + + " }\n" + + "}\n"; + + assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); + } + + @Test + public void testToJson_news() { + WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() + .msgType(KefuMsgType.NEWS) + .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) + .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) + .toTags(new String[]{"tagid1", "tagid2"}) + .agentId(1) + .isToAll(false) + .articles(Lists.newArrayList(NewArticle.builder() + .title("中秋节礼品领取") + .description("今年中秋节公司有豪礼相送") + .url("URL") + .picUrl("http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png") + .btnText("更多") + .build())) + .build(); + + final String json = message.toJson(); + String expectedJson = "{\n" + + " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + + " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + + " \"totag\" : [\"tagid1\",\"tagid2\"],\n" + + " \"toall\" : 0,\n" + + " \"msgtype\" : \"news\",\n" + + " \"agentid\" : 1,\n" + + " \"news\" : {\n" + + " \"articles\" : [\n" + + " {\n" + + " \"title\" : \"中秋节礼品领取\",\n" + + " \"description\" : \"今年中秋节公司有豪礼相送\",\n" + + " \"url\" : \"URL\",\n" + + " \"picurl\" : \"http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png\",\n" + + " \"btntxt\":\"更多\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "}\n"; + + assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); + } + + + @Test + public void testToJson_mpnews() { + WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() + .msgType(KefuMsgType.MPNEWS) + .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) + .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) + .toTags(new String[]{"tagid1", "tagid2"}) + .agentId(1) + .isToAll(false) + .isSafe(false) + .mpNewsArticles(Lists.newArrayList(MpnewsArticle.newBuilder() + .title("Title") + .thumbMediaId("MEDIA_ID") + .author("Author") + .contentSourceUrl("URL") + .content("Content") + .digest("Digest description") + .build())) + .build(); + + final String json = message.toJson(); + String expectedJson = "{\n" + + " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + + " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + + " \"totag\" : [\"tagid1\",\"tagid2\"],\n" + + " \"toall\" : 0,\n" + + " \"msgtype\" : \"mpnews\",\n" + + " \"agentid\" : 1,\n" + + " \"mpnews\" : {\n" + + " \"articles\":[\n" + + " {\n" + + " \"title\": \"Title\", \n" + + " \"thumb_media_id\": \"MEDIA_ID\",\n" + + " \"author\": \"Author\",\n" + + " \"content_source_url\": \"URL\",\n" + + " \"content\": \"Content\",\n" + + " \"digest\": \"Digest description\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"safe\":0\n" + + "}\n"; + + assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); + } + + @Test + public void testToJson_markdown() { + WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() + .msgType(KefuMsgType.MARKDOWN) + .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) + .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) + .toTags(new String[]{"tagid1", "tagid2"}) + .agentId(1) + .isToAll(false) + .content("您的会议室已经预定,稍后会同步到`邮箱`\n" + + " >**事项详情**\n" + + " >事 项:开会\n" + + " >组织者:@miglioguan\n" + + " >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" + + " >\n" + + " >会议室:广州TIT 1楼 301\n" + + " >日 期:2018年5月18日\n" + + " >时 间:上午9:00-11:00\n" + + " >\n" + + " >请准时参加会议。\n" + + " >\n" + + " >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)") + .build(); + + final String json = message.toJson(); + String expectedJson = "{\n" + + " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + + " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + + " \"totag\" : [\"tagid1\",\"tagid2\"],\n" + + " \"toall\" : 0,\n" + + " \"msgtype\" : \"markdown\",\n" + + " \"agentid\" : 1,\n" + + " \"markdown\": {\n" + + " \"content\": \"您的会议室已经预定,稍后会同步到`邮箱`\n" + + " >**事项详情**\n" + + " >事 项:开会\n" + + " >组织者:@miglioguan\n" + + " >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" + + " >\n" + + " >会议室:广州TIT 1楼 301\n" + + " >日 期:2018年5月18日\n" + + " >时 间:上午9:00-11:00\n" + + " >\n" + + " >请准时参加会议。\n" + + " >\n" + + " >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)\"\n" + + " }\n" + + "}\n"; + + assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); + } + + @Test + public void testToJson_miniProgramNotice() { + WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() + .msgType(KefuMsgType.MINIPROGRAM_NOTICE) + .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) + .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) + .toTags(new String[]{"tagid1", "tagid2"}) + .emphasisFirstItem(true) + .description("4月27日 16:16") + .title("会议室预订成功通知") + .appId("wx123123123123123") + .page("pages/index?userid=zhangsan&orderid=123123123") + .contentItems(ImmutableMap.of("会议室","402", + "会议地点","广州TIT-402会议室", + "会议时间","2018年8月1日 09:00-09:30", + "参与人员","周剑轩")) + .build(); + + final String json = message.toJson(); + String expectedJson = "{\n" + + " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + + " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + + " \"totag\" : [\"tagid1\",\"tagid2\"],\n" + + " \"msgtype\" : \"miniprogram_notice\",\n" + + " \"miniprogram_notice\" : {\n" + + " \"appid\": \"wx123123123123123\",\n" + + " \"page\": \"pages/index?userid=zhangsan&orderid=123123123\",\n" + + " \"title\": \"会议室预订成功通知\",\n" + + " \"description\": \"4月27日 16:16\",\n" + + " \"emphasis_first_item\": true,\n" + + " \"content_item\": [\n" + + " {\n" + + " \"key\": \"会议室\",\n" + + " \"value\": \"402\"\n" + + " },\n" + + " {\n" + + " \"key\": \"会议地点\",\n" + + " \"value\": \"广州TIT-402会议室\"\n" + + " },\n" + + " {\n" + + " \"key\": \"会议时间\",\n" + + " \"value\": \"2018年8月1日 09:00-09:30\"\n" + + " },\n" + + " {\n" + + " \"key\": \"参与人员\",\n" + + " \"value\": \"周剑轩\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "}\n"; + + assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); + } +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java similarity index 98% rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java index c54211758..3f7859116 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java @@ -1,7 +1,8 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; +import me.chanjar.weixin.cp.bean.message.WxCpMessage; import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; import org.testng.annotations.Test; 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/message/WxCpXmlMessageTest.java similarity index 99% rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessageTest.java index 0a9f17a62..044e364b6 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/message/WxCpXmlMessageTest.java @@ -1,6 +1,7 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; import me.chanjar.weixin.cp.constant.WxCpConsts; import me.chanjar.weixin.cp.util.xml.XStreamTransformer; import org.testng.annotations.Test; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutImageMessageTest.java similarity index 89% rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutImageMessageTest.java index 87c9454c9..0ecbec67d 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutImageMessageTest.java @@ -1,5 +1,7 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import org.testng.Assert; import org.testng.annotations.Test; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutNewsMessageTest.java similarity index 95% rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutNewsMessageTest.java index 128bc9a4c..b0d3efabd 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutNewsMessageTest.java @@ -1,5 +1,7 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage; import org.testng.Assert; import org.testng.annotations.Test; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutTextMessageTest.java similarity index 89% rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutTextMessageTest.java index fd09ed6b9..68945f826 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutTextMessageTest.java @@ -1,5 +1,7 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage; import org.testng.Assert; import org.testng.annotations.Test; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVideoMessageTest.java similarity index 91% rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVideoMessageTest.java index c5551dec0..7077ceeed 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVideoMessageTest.java @@ -1,5 +1,7 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage; import org.testng.Assert; import org.testng.annotations.Test; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVoiceMessageTest.java similarity index 89% rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVoiceMessageTest.java index a3c9688c4..9c0348600 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVoiceMessageTest.java @@ -1,5 +1,7 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.message; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage; import org.testng.Assert; import org.testng.annotations.Test; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java index df656a68a..2067e03eb 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java @@ -13,9 +13,9 @@ import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.constant.WxCpConsts; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; -import me.chanjar.weixin.cp.bean.WxCpXmlMessage; -import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; -import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage; import me.chanjar.weixin.cp.config.WxCpConfigStorage; import me.chanjar.weixin.cp.message.WxCpMessageHandler; import me.chanjar.weixin.cp.message.WxCpMessageRouter; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java index 291cef403..3f48c3213 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java @@ -3,8 +3,8 @@ package me.chanjar.weixin.cp.demo; import me.chanjar.weixin.cp.config.WxCpConfigStorage; import me.chanjar.weixin.cp.message.WxCpMessageRouter; import me.chanjar.weixin.cp.api.WxCpService; -import me.chanjar.weixin.cp.bean.WxCpXmlMessage; -import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; import org.apache.commons.lang3.StringUtils; diff --git a/weixin-java-cp/src/test/resources/moco/message.json b/weixin-java-cp/src/test/resources/moco/message.json index 3714ad5db..b6b333c11 100644 --- a/weixin-java-cp/src/test/resources/moco/message.json +++ b/weixin-java-cp/src/test/resources/moco/message.json @@ -14,5 +14,13 @@ "response": { "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}" } + }, + { + "request": { + "uri": "/cgi-bin/linkedcorp/message/send" + }, + "response": { + "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}" + } } ] diff --git a/weixin-java-cp/src/test/resources/testng.xml b/weixin-java-cp/src/test/resources/testng.xml index 563928bdf..cfccea89b 100644 --- a/weixin-java-cp/src/test/resources/testng.xml +++ b/weixin-java-cp/src/test/resources/testng.xml @@ -12,13 +12,13 @@ - - - - - - - + + + + + + +