@@ -0,0 +1,14 @@ | |||
# EditorConfig: http://editorconfig.org/ | |||
root = true | |||
[*] | |||
indent_style = space | |||
indent_size = 2 | |||
end_of_line = lf | |||
charset = utf-8 | |||
trim_trailing_whitespace = true | |||
insert_final_newline = true | |||
[*.md] | |||
trim_trailing_whitespace = false |
@@ -1,19 +1,21 @@ | |||
# Weixin Java Tools 微信公众号/企业号开发Java SDK | |||
## [](http://shang.qq.com/wpa/qunwpa?idkey=078f7a153d243853e24cf2b542e7a6ccbf2a592bc138080f84d11297f736ec46) [](https://github.com/ellerbrock/open-source-badge/)  [](https://travis-ci.org/binarywang/weixin-java-tools) | |||
## [](https://github.com/ellerbrock/open-source-badge/)  [](https://travis-ci.org/binarywang/weixin-java-tools) | |||
### 声明:本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。 | |||
### 最新更新:2.1.0版发布!!! on 2016-08-31 | |||
#### 自2.0.0版本以来,接口调整比较大,主要是公众号的调整,企业号无过多调整,主要是为了解决主接口类过于庞大不方便管理的问题,将接口实现代码按模块进行拆分。所以如果习惯于1.X.X版本的同学不想做过多更改的话,请慎重考虑升级到2.X.X版本。 | |||
#### ***自2.0.0版本以来,接口调整比较大,主要是公众号的调整,企业号无过多调整,主要是为了解决主接口类过于庞大不方便管理的问题,将接口实现代码按模块进行拆分。所以如果习惯于1.X.X版本的同学不想做过多更改的话,请慎重考虑升级到2.X.X版本.*** | |||
--- | |||
### 详细开发文档请看 [wiki](https://github.com/chanjarster/weixin-java-tools/wiki)。 | |||
=========== | |||
## 开发交流工具: | |||
* QQ群:343954419 [](http://shang.qq.com/wpa/qunwpa?idkey=078f7a153d243853e24cf2b542e7a6ccbf2a592bc138080f84d11297f736ec46) | |||
* 注意:为保证入群成员质量,请申请入群时认真输入Github帐号ID,即你的github主页地址https://github.com/XXXX 中最后的部分XXXX的内容,谢谢~ | |||
* 微信群: 因二维码有时间限制,如有想加入微信群的,请入QQ群后咨询获取最新入群二维码。 | |||
* QQ群:343954419 [](http://shang.qq.com/wpa/qunwpa?idkey=078f7a153d243853e24cf2b542e7a6ccbf2a592bc138080f84d11297f736ec46) | |||
* ***注意:为保证入群成员质量,请申请入群前,先Star本项目,然后在申请入群时,输入您的Github帐号ID,以便管理员核对,ID即你的github主页地址https://github.com/XXXX 中最后的部分XXXX的内容,或者在github网页右上角点击头像查看,如下图Signed in as下方黄色标识内容即是:*** | |||
*  | |||
=========== | |||
@@ -5,7 +5,7 @@ | |||
<modelVersion>4.0.0</modelVersion> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-parent</artifactId> | |||
<version>2.1.0</version> | |||
<version>2.1.2</version> | |||
<packaging>pom</packaging> | |||
<name>WeiXin Java Tools - Parent</name> | |||
<description>微信公众号、企业号上级POM</description> | |||
@@ -49,7 +49,6 @@ | |||
<slf4j.version>1.7.10</slf4j.version> | |||
<logback.version>1.1.2</logback.version> | |||
<jodd-http.version>3.6.7</jodd-http.version> | |||
<jackson.version>2.8.0</jackson.version> | |||
<jedis.version>2.9.0</jedis.version> | |||
<gson.version>2.7</gson.version> | |||
<commons-lang3.version>3.4</commons-lang3.version> | |||
@@ -106,15 +105,11 @@ | |||
<artifactId>commons-lang3</artifactId> | |||
<version>${commons-lang3.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.fasterxml.jackson.core</groupId> | |||
<artifactId>jackson-databind</artifactId> | |||
<version>${jackson.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>redis.clients</groupId> | |||
<artifactId>jedis</artifactId> | |||
<version>${jedis.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
</dependencies> | |||
@@ -6,7 +6,7 @@ | |||
<parent> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-parent</artifactId> | |||
<version>2.1.0</version> | |||
<version>2.1.2</version> | |||
</parent> | |||
<artifactId>weixin-java-common</artifactId> | |||
@@ -164,6 +164,12 @@ public class WxConsts { | |||
* 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 | |||
*/ | |||
public static final String OAUTH2_SCOPE_USER_INFO = "snsapi_userinfo"; | |||
/** | |||
* 网页应用登录授权作用域 snsapi_login | |||
*/ | |||
public static final String QRCONNECT_SCOPE_SNSAPI_LOGIN = "snsapi_login"; | |||
/////////////////////// | |||
// 永久素材类型 | |||
/////////////////////// | |||
@@ -1,10 +1,9 @@ | |||
package me.chanjar.weixin.common.util.crypto; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.util.Arrays; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
/** | |||
* Created by Daniel Qian on 14/10/19. | |||
*/ | |||
@@ -13,7 +12,7 @@ public class SHA1 { | |||
/** | |||
* 串接arr参数,生成sha1 digest | |||
*/ | |||
public static String gen(String... arr) throws NoSuchAlgorithmException { | |||
public static String gen(String... arr) { | |||
Arrays.sort(arr); | |||
StringBuilder sb = new StringBuilder(); | |||
for (String a : arr) { | |||
@@ -25,7 +24,7 @@ public class SHA1 { | |||
/** | |||
* 用&串接arr参数,生成sha1 digest | |||
*/ | |||
public static String genWithAmple(String... arr) throws NoSuchAlgorithmException { | |||
public static String genWithAmple(String... arr) { | |||
Arrays.sort(arr); | |||
StringBuilder sb = new StringBuilder(); | |||
for (int i = 0; i < arr.length; i++) { | |||
@@ -17,11 +17,16 @@ | |||
*/ | |||
package me.chanjar.weixin.common.util.crypto; | |||
import org.apache.commons.codec.binary.Base64; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.xml.sax.InputSource; | |||
import java.io.StringReader; | |||
import java.nio.charset.Charset; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Random; | |||
import java.util.SortedMap; | |||
import java.util.TreeMap; | |||
import javax.crypto.Cipher; | |||
import javax.crypto.spec.IvParameterSpec; | |||
@@ -29,10 +34,12 @@ import javax.crypto.spec.SecretKeySpec; | |||
import javax.xml.parsers.DocumentBuilder; | |||
import javax.xml.parsers.DocumentBuilderFactory; | |||
import javax.xml.parsers.ParserConfigurationException; | |||
import java.io.StringReader; | |||
import java.nio.charset.Charset; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.util.*; | |||
import org.apache.commons.codec.binary.Base64; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.xml.sax.InputSource; | |||
public class WxCryptUtil { | |||
@@ -130,13 +137,9 @@ public class WxCryptUtil { | |||
String timeStamp = Long.toString(System.currentTimeMillis() / 1000l); | |||
String nonce = genRandomStr(); | |||
try { | |||
String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedXml); | |||
String result = generateXml(encryptedXml, signature, timeStamp, nonce); | |||
return result; | |||
} catch (NoSuchAlgorithmException e) { | |||
throw new RuntimeException(e); | |||
} | |||
String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedXml); | |||
String result = generateXml(encryptedXml, signature, timeStamp, nonce); | |||
return result; | |||
} | |||
/** | |||
@@ -205,14 +208,10 @@ public class WxCryptUtil { | |||
// 提取密文 | |||
String cipherText = extractEncryptPart(encryptedXml); | |||
try { | |||
// 验证安全签名 | |||
String signature = SHA1.gen(this.token, timeStamp, nonce, cipherText); | |||
if (!signature.equals(msgSignature)) { | |||
throw new RuntimeException("加密消息签名校验失败"); | |||
} | |||
} catch (NoSuchAlgorithmException e) { | |||
throw new RuntimeException(e); | |||
// 验证安全签名 | |||
String signature = SHA1.gen(this.token, timeStamp, nonce, cipherText); | |||
if (!signature.equals(msgSignature)) { | |||
throw new RuntimeException("加密消息签名校验失败"); | |||
} | |||
// 解密 | |||
@@ -277,7 +276,7 @@ public class WxCryptUtil { | |||
* | |||
* @param number | |||
*/ | |||
private byte[] number2BytesInNetworkOrder(int number) { | |||
private static byte[] number2BytesInNetworkOrder(int number) { | |||
byte[] orderBytes = new byte[4]; | |||
orderBytes[3] = (byte) (number & 0xFF); | |||
orderBytes[2] = (byte) (number >> 8 & 0xFF); | |||
@@ -291,7 +290,7 @@ public class WxCryptUtil { | |||
* | |||
* @param bytesInNetworkOrder | |||
*/ | |||
private int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) { | |||
private static int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) { | |||
int sourceNumber = 0; | |||
for (int i = 0; i < 4; i++) { | |||
sourceNumber <<= 8; | |||
@@ -303,7 +302,7 @@ public class WxCryptUtil { | |||
/** | |||
* 随机生成16位字符串 | |||
*/ | |||
private String genRandomStr() { | |||
private static String genRandomStr() { | |||
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | |||
Random random = new Random(); | |||
StringBuffer sb = new StringBuffer(); | |||
@@ -323,8 +322,8 @@ public class WxCryptUtil { | |||
* @param nonce 随机字符串 | |||
* @return 生成的xml字符串 | |||
*/ | |||
private String generateXml(String encrypt, String signature, String timestamp, | |||
String nonce) { | |||
private static String generateXml(String encrypt, String signature, | |||
String timestamp, String nonce) { | |||
String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n" | |||
+ "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n" | |||
+ "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n" | |||
@@ -17,37 +17,25 @@ public class FileUtils { | |||
* @param tmpDirFile 临时文件夹目录 | |||
*/ | |||
public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException { | |||
FileOutputStream fos = null; | |||
try { | |||
File tmpFile; | |||
if (tmpDirFile == null) { | |||
tmpFile = File.createTempFile(name, '.' + ext); | |||
} else { | |||
tmpFile = File.createTempFile(name, '.' + ext, tmpDirFile); | |||
} | |||
tmpFile.deleteOnExit(); | |||
fos = new FileOutputStream(tmpFile); | |||
File tmpFile; | |||
if (tmpDirFile == null) { | |||
tmpFile = File.createTempFile(name, '.' + ext); | |||
} else { | |||
tmpFile = File.createTempFile(name, '.' + ext, tmpDirFile); | |||
} | |||
tmpFile.deleteOnExit(); | |||
try (FileOutputStream fos = new FileOutputStream(tmpFile)) { | |||
int read = 0; | |||
byte[] bytes = new byte[1024 * 100]; | |||
while ((read = inputStream.read(bytes)) != -1) { | |||
fos.write(bytes, 0, read); | |||
} | |||
fos.flush(); | |||
return tmpFile; | |||
} finally { | |||
if (inputStream != null) { | |||
try { | |||
inputStream.close(); | |||
} catch (IOException e) { | |||
} | |||
} | |||
if (fos != null) { | |||
try { | |||
fos.close(); | |||
} catch (IOException e) { | |||
} | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
@@ -103,43 +103,45 @@ public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder { | |||
private void prepare() { | |||
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() | |||
.register("http", this.plainConnectionSocketFactory) | |||
.register("https", this.sslConnectionSocketFactory) | |||
.build(); | |||
.register("http", this.plainConnectionSocketFactory) | |||
.register("https", this.sslConnectionSocketFactory) | |||
.build(); | |||
@SuppressWarnings("resource") | |||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); | |||
connectionManager.setMaxTotal(this.maxTotalConn); | |||
connectionManager.setDefaultMaxPerRoute(this.maxConnPerHost); | |||
connectionManager.setDefaultSocketConfig( | |||
SocketConfig.copy(SocketConfig.DEFAULT) | |||
.setSoTimeout(this.soTimeout) | |||
.build() | |||
SocketConfig.copy(SocketConfig.DEFAULT) | |||
.setSoTimeout(this.soTimeout) | |||
.build() | |||
); | |||
this.idleConnectionMonitorThread = new IdleConnectionMonitorThread( | |||
connectionManager, this.idleConnTimeout, this.checkWaitTime); | |||
connectionManager, this.idleConnTimeout, this.checkWaitTime); | |||
this.idleConnectionMonitorThread.setDaemon(true); | |||
this.idleConnectionMonitorThread.start(); | |||
this.httpClientBuilder = HttpClients.custom() | |||
.setConnectionManager(connectionManager) | |||
.setDefaultRequestConfig( | |||
RequestConfig.custom() | |||
.setSocketTimeout(this.soTimeout) | |||
.setConnectTimeout(this.connectionTimeout) | |||
.setConnectionRequestTimeout(this.connectionRequestTimeout) | |||
.build() | |||
) | |||
.setRetryHandler(this.httpRequestRetryHandler); | |||
.setConnectionManager(connectionManager) | |||
.setConnectionManagerShared(true) | |||
.setDefaultRequestConfig( | |||
RequestConfig.custom() | |||
.setSocketTimeout(this.soTimeout) | |||
.setConnectTimeout(this.connectionTimeout) | |||
.setConnectionRequestTimeout(this.connectionRequestTimeout) | |||
.build() | |||
) | |||
.setRetryHandler(this.httpRequestRetryHandler); | |||
if (StringUtils.isNotBlank(this.httpProxyHost) | |||
&& StringUtils.isNotBlank(this.httpProxyUsername)) { | |||
&& StringUtils.isNotBlank(this.httpProxyUsername)) { | |||
// 使用代理服务器 需要用户认证的代理服务器 | |||
CredentialsProvider provider = new BasicCredentialsProvider(); | |||
provider.setCredentials( | |||
new AuthScope(this.httpProxyHost, this.httpProxyPort), | |||
new UsernamePasswordCredentials(this.httpProxyUsername, | |||
this.httpProxyPassword)); | |||
new AuthScope(this.httpProxyHost, this.httpProxyPort), | |||
new UsernamePasswordCredentials(this.httpProxyUsername, | |||
this.httpProxyPassword)); | |||
this.httpClientBuilder.setDefaultCredentialsProvider(provider); | |||
} | |||
@@ -180,7 +182,7 @@ public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder { | |||
wait(this.checkWaitTime); | |||
this.connMgr.closeExpiredConnections(); | |||
this.connMgr.closeIdleConnections(this.idleConnTimeout, | |||
TimeUnit.MILLISECONDS); | |||
TimeUnit.MILLISECONDS); | |||
} | |||
} | |||
} catch (InterruptedException ignore) { | |||
@@ -1,15 +1,14 @@ | |||
package me.chanjar.weixin.common.util.http; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import jodd.http.HttpRequest; | |||
import jodd.http.HttpResponse; | |||
import jodd.http.ProxyInfo; | |||
import jodd.http.net.SocketHttpConnectionProvider; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import java.io.IOException; | |||
/** | |||
* 简单的GET请求执行器,请求的参数是String, 返回的结果也是String | |||
@@ -20,7 +19,7 @@ public class JoddGetRequestExecutor implements RequestExecutor<String, String> { | |||
@Override | |||
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, | |||
String queryParam) throws WxErrorException, IOException { | |||
String queryParam) throws WxErrorException { | |||
if (queryParam != null) { | |||
if (uri.indexOf('?') == -1) { | |||
uri += '?'; | |||
@@ -1,15 +1,14 @@ | |||
package me.chanjar.weixin.common.util.http; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import jodd.http.HttpRequest; | |||
import jodd.http.HttpResponse; | |||
import jodd.http.ProxyInfo; | |||
import jodd.http.net.SocketHttpConnectionProvider; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import java.io.IOException; | |||
/** | |||
* 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | |||
@@ -20,7 +19,7 @@ public class JoddPostRequestExecutor implements RequestExecutor<String, String> | |||
@Override | |||
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, | |||
String postEntity) throws WxErrorException, IOException { | |||
String postEntity) throws WxErrorException { | |||
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider(); | |||
if (httpProxy != null) { | |||
@@ -1,9 +1,11 @@ | |||
package me.chanjar.weixin.common.util.http; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.StringUtils; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.regex.Matcher; | |||
import java.util.regex.Pattern; | |||
import org.apache.http.Header; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.client.config.RequestConfig; | |||
@@ -12,11 +14,10 @@ import org.apache.http.client.methods.HttpGet; | |||
import org.apache.http.entity.ContentType; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.regex.Matcher; | |||
import java.util.regex.Pattern; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.StringUtils; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
/** | |||
* 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File | |||
@@ -52,7 +53,9 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||
httpGet.setConfig(config); | |||
} | |||
try (CloseableHttpResponse response = httpclient.execute(httpGet)) { | |||
try (CloseableHttpResponse response = httpclient.execute(httpGet); | |||
InputStream inputStream = InputStreamResponseHandler.INSTANCE | |||
.handleResponse(response)) { | |||
Header[] contentTypeHeader = response.getHeaders("Content-Type"); | |||
if (contentTypeHeader != null && contentTypeHeader.length > 0) { | |||
@@ -62,8 +65,6 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||
throw new WxErrorException(WxError.fromJson(responseContent)); | |||
} | |||
} | |||
InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response); | |||
// 视频文件不支持下载 | |||
String fileName = getFileName(response); | |||
if (StringUtils.isBlank(fileName)) { | |||
@@ -106,7 +106,7 @@ public class SessionTest { | |||
} | |||
@Test(dataProvider = "getSessionManager") | |||
public void testMaxActive(WxSessionManager sessionManager) throws InterruptedException { | |||
public void testMaxActive(WxSessionManager sessionManager) { | |||
InternalSessionManager ism = (InternalSessionManager) sessionManager; | |||
ism.setMaxActiveSessions(2); | |||
@@ -118,7 +118,7 @@ public class SessionTest { | |||
} | |||
@Test(dataProvider = "getSessionManager", expectedExceptions = TooManyActiveSessionsException.class) | |||
public void testMaxActive2(WxSessionManager sessionManager) throws InterruptedException { | |||
public void testMaxActive2(WxSessionManager sessionManager) { | |||
InternalSessionManager ism = (InternalSessionManager) sessionManager; | |||
ism.setMaxActiveSessions(2); | |||
@@ -6,7 +6,7 @@ | |||
<parent> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-parent</artifactId> | |||
<version>2.1.0</version> | |||
<version>2.1.2</version> | |||
</parent> | |||
<artifactId>weixin-java-cp</artifactId> | |||
@@ -55,13 +55,13 @@ public interface WxCpConfigStorage { | |||
String getOauth2redirectUri(); | |||
String getHttp_proxy_host(); | |||
String getHttpProxyHost(); | |||
int getHttp_proxy_port(); | |||
int getHttpProxyPort(); | |||
String getHttp_proxy_username(); | |||
String getHttpProxyUsername(); | |||
String getHttp_proxy_password(); | |||
String getHttpProxyPassword(); | |||
File getTmpDirFile(); | |||
@@ -1,10 +1,13 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import java.io.File; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | |||
import java.io.File; | |||
/** | |||
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | |||
* | |||
@@ -23,10 +26,10 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
protected volatile String oauth2redirectUri; | |||
protected volatile String http_proxy_host; | |||
protected volatile int http_proxy_port; | |||
protected volatile String http_proxy_username; | |||
protected volatile String http_proxy_password; | |||
protected volatile String httpProxyHost; | |||
protected volatile int httpProxyPort; | |||
protected volatile String httpProxyUsername; | |||
protected volatile String httpProxyPassword; | |||
protected volatile String jsapiTicket; | |||
protected volatile long jsapiTicketExpiresTime; | |||
@@ -35,6 +38,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
@Override | |||
public String getAccessToken() { | |||
return this.accessToken; | |||
} | |||
@@ -43,18 +47,22 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
this.accessToken = accessToken; | |||
} | |||
@Override | |||
public boolean isAccessTokenExpired() { | |||
return System.currentTimeMillis() > this.expiresTime; | |||
} | |||
@Override | |||
public void expireAccessToken() { | |||
this.expiresTime = 0; | |||
} | |||
@Override | |||
public synchronized void updateAccessToken(WxAccessToken accessToken) { | |||
updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
} | |||
@Override | |||
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { | |||
this.accessToken = accessToken; | |||
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l; | |||
@@ -62,7 +70,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
@Override | |||
public String getJsapiTicket() { | |||
return jsapiTicket; | |||
return this.jsapiTicket; | |||
} | |||
public void setJsapiTicket(String jsapiTicket) { | |||
@@ -70,27 +78,31 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
} | |||
public long getJsapiTicketExpiresTime() { | |||
return jsapiTicketExpiresTime; | |||
return this.jsapiTicketExpiresTime; | |||
} | |||
public void setJsapiTicketExpiresTime(long jsapiTicketExpiresTime) { | |||
this.jsapiTicketExpiresTime = jsapiTicketExpiresTime; | |||
} | |||
@Override | |||
public boolean isJsapiTicketExpired() { | |||
return System.currentTimeMillis() > this.jsapiTicketExpiresTime; | |||
} | |||
@Override | |||
public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { | |||
this.jsapiTicket = jsapiTicket; | |||
// 预留200秒的时间 | |||
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l; | |||
} | |||
@Override | |||
public void expireJsapiTicket() { | |||
this.jsapiTicketExpiresTime = 0; | |||
} | |||
@Override | |||
public String getCorpId() { | |||
return this.corpId; | |||
} | |||
@@ -99,6 +111,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
this.corpId = corpId; | |||
} | |||
@Override | |||
public String getCorpSecret() { | |||
return this.corpSecret; | |||
} | |||
@@ -107,6 +120,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
this.corpSecret = corpSecret; | |||
} | |||
@Override | |||
public String getToken() { | |||
return this.token; | |||
} | |||
@@ -115,6 +129,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
this.token = token; | |||
} | |||
@Override | |||
public long getExpiresTime() { | |||
return this.expiresTime; | |||
} | |||
@@ -123,16 +138,18 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
this.expiresTime = expiresTime; | |||
} | |||
@Override | |||
public String getAesKey() { | |||
return aesKey; | |||
return this.aesKey; | |||
} | |||
public void setAesKey(String aesKey) { | |||
this.aesKey = aesKey; | |||
} | |||
@Override | |||
public String getAgentId() { | |||
return agentId; | |||
return this.agentId; | |||
} | |||
public void setAgentId(String agentId) { | |||
@@ -148,60 +165,50 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
this.oauth2redirectUri = oauth2redirectUri; | |||
} | |||
public String getHttp_proxy_host() { | |||
return http_proxy_host; | |||
@Override | |||
public String getHttpProxyHost() { | |||
return this.httpProxyHost; | |||
} | |||
public void setHttp_proxy_host(String http_proxy_host) { | |||
this.http_proxy_host = http_proxy_host; | |||
public void setHttpProxyHost(String httpProxyHost) { | |||
this.httpProxyHost = httpProxyHost; | |||
} | |||
public int getHttp_proxy_port() { | |||
return http_proxy_port; | |||
@Override | |||
public int getHttpProxyPort() { | |||
return this.httpProxyPort; | |||
} | |||
public void setHttp_proxy_port(int http_proxy_port) { | |||
this.http_proxy_port = http_proxy_port; | |||
public void setHttpProxyPort(int httpProxyPort) { | |||
this.httpProxyPort = httpProxyPort; | |||
} | |||
public String getHttp_proxy_username() { | |||
return http_proxy_username; | |||
@Override | |||
public String getHttpProxyUsername() { | |||
return this.httpProxyUsername; | |||
} | |||
public void setHttp_proxy_username(String http_proxy_username) { | |||
this.http_proxy_username = http_proxy_username; | |||
public void setHttpProxyUsername(String httpProxyUsername) { | |||
this.httpProxyUsername = httpProxyUsername; | |||
} | |||
public String getHttp_proxy_password() { | |||
return http_proxy_password; | |||
@Override | |||
public String getHttpProxyPassword() { | |||
return this.httpProxyPassword; | |||
} | |||
public void setHttp_proxy_password(String http_proxy_password) { | |||
this.http_proxy_password = http_proxy_password; | |||
public void setHttpProxyPassword(String httpProxyPassword) { | |||
this.httpProxyPassword = httpProxyPassword; | |||
} | |||
@Override | |||
public String toString() { | |||
return "WxCpInMemoryConfigStorage{" + | |||
"corpId='" + corpId + '\'' + | |||
", corpSecret='" + corpSecret + '\'' + | |||
", token='" + token + '\'' + | |||
", accessToken='" + accessToken + '\'' + | |||
", aesKey='" + aesKey + '\'' + | |||
", agentId='" + agentId + '\'' + | |||
", expiresTime=" + expiresTime + | |||
", http_proxy_host='" + http_proxy_host + '\'' + | |||
", http_proxy_port=" + http_proxy_port + | |||
", http_proxy_username='" + http_proxy_username + '\'' + | |||
", http_proxy_password='" + http_proxy_password + '\'' + | |||
", jsapiTicket='" + jsapiTicket + '\'' + | |||
", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' + | |||
", tmpDirFile='" + tmpDirFile + '\'' + | |||
'}'; | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
@Override | |||
public File getTmpDirFile() { | |||
return tmpDirFile; | |||
return this.tmpDirFile; | |||
} | |||
public void setTmpDirFile(File tmpDirFile) { | |||
@@ -29,10 +29,10 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage { | |||
private volatile String oauth2redirectUri; | |||
private volatile String http_proxy_host; | |||
private volatile int http_proxy_port; | |||
private volatile String http_proxy_username; | |||
private volatile String http_proxy_password; | |||
private volatile String httpProxyHost; | |||
private volatile int httpProxyPort; | |||
private volatile String httpProxyUsername; | |||
private volatile String httpProxyPassword; | |||
private volatile File tmpDirFile; | |||
@@ -185,23 +185,23 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage { | |||
} | |||
@Override | |||
public String getHttp_proxy_host() { | |||
return this.http_proxy_host; | |||
public String getHttpProxyHost() { | |||
return this.httpProxyHost; | |||
} | |||
@Override | |||
public int getHttp_proxy_port() { | |||
return this.http_proxy_port; | |||
public int getHttpProxyPort() { | |||
return this.httpProxyPort; | |||
} | |||
@Override | |||
public String getHttp_proxy_username() { | |||
return this.http_proxy_username; | |||
public String getHttpProxyUsername() { | |||
return this.httpProxyUsername; | |||
} | |||
@Override | |||
public String getHttp_proxy_password() { | |||
return this.http_proxy_password; | |||
public String getHttpProxyPassword() { | |||
return this.httpProxyPassword; | |||
} | |||
@Override | |||
@@ -240,20 +240,20 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage { | |||
this.oauth2redirectUri = oauth2redirectUri; | |||
} | |||
public void setHttp_proxy_host(String http_proxy_host) { | |||
this.http_proxy_host = http_proxy_host; | |||
public void setHttpProxyHost(String httpProxyHost) { | |||
this.httpProxyHost = httpProxyHost; | |||
} | |||
public void setHttp_proxy_port(int http_proxy_port) { | |||
this.http_proxy_port = http_proxy_port; | |||
public void setHttpProxyPort(int httpProxyPort) { | |||
this.httpProxyPort = httpProxyPort; | |||
} | |||
public void setHttp_proxy_username(String http_proxy_username) { | |||
this.http_proxy_username = http_proxy_username; | |||
public void setHttpProxyUsername(String httpProxyUsername) { | |||
this.httpProxyUsername = httpProxyUsername; | |||
} | |||
public void setHttp_proxy_password(String http_proxy_password) { | |||
this.http_proxy_password = http_proxy_password; | |||
public void setHttpProxyPassword(String httpProxyPassword) { | |||
this.httpProxyPassword = httpProxyPassword; | |||
} | |||
public void setTmpDirFile(File tmpDirFile) { | |||
@@ -52,7 +52,7 @@ public class WxCpMessageRouter { | |||
private static final int DEFAULT_THREAD_POOL_SIZE = 100; | |||
protected final Logger log = LoggerFactory.getLogger(WxCpMessageRouter.class); | |||
private final List<WxCpMessageRouterRule> rules = new ArrayList<WxCpMessageRouterRule>(); | |||
private final List<WxCpMessageRouterRule> rules = new ArrayList<>(); | |||
private final WxCpService wxCpService; | |||
@@ -142,9 +142,9 @@ public class WxCpMessageRouter { | |||
return null; | |||
} | |||
final List<WxCpMessageRouterRule> matchRules = new ArrayList<WxCpMessageRouterRule>(); | |||
final List<WxCpMessageRouterRule> matchRules = new ArrayList<>(); | |||
// 收集匹配的规则 | |||
for (final WxCpMessageRouterRule rule : rules) { | |||
for (final WxCpMessageRouterRule rule : this.rules) { | |||
if (rule.test(wxMessage)) { | |||
matchRules.add(rule); | |||
if (!rule.isReEnter()) { | |||
@@ -158,39 +158,40 @@ public class WxCpMessageRouter { | |||
} | |||
WxCpXmlOutMessage res = null; | |||
final List<Future> futures = new ArrayList<Future>(); | |||
final List<Future> futures = new ArrayList<>(); | |||
for (final WxCpMessageRouterRule rule : matchRules) { | |||
// 返回最后一个非异步的rule的执行结果 | |||
if (rule.isAsync()) { | |||
futures.add( | |||
executorService.submit(new Runnable() { | |||
this.executorService.submit(new Runnable() { | |||
@Override | |||
public void run() { | |||
rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||
rule.service(wxMessage, WxCpMessageRouter.this.wxCpService, WxCpMessageRouter.this.sessionManager, WxCpMessageRouter.this.exceptionHandler); | |||
} | |||
}) | |||
); | |||
} else { | |||
res = rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||
res = rule.service(wxMessage, this.wxCpService, this.sessionManager, this.exceptionHandler); | |||
// 在同步操作结束,session访问结束 | |||
log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); | |||
this.log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); | |||
sessionEndAccess(wxMessage); | |||
} | |||
} | |||
if (futures.size() > 0) { | |||
executorService.submit(new Runnable() { | |||
this.executorService.submit(new Runnable() { | |||
@Override | |||
public void run() { | |||
for (Future future : futures) { | |||
try { | |||
future.get(); | |||
log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUserName()); | |||
WxCpMessageRouter.this.log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUserName()); | |||
// 异步操作结束,session访问结束 | |||
sessionEndAccess(wxMessage); | |||
} catch (InterruptedException e) { | |||
log.error("Error happened when wait task finish", e); | |||
WxCpMessageRouter.this.log.error("Error happened when wait task finish", e); | |||
} catch (ExecutionException e) { | |||
log.error("Error happened when wait task finish", e); | |||
WxCpMessageRouter.this.log.error("Error happened when wait task finish", e); | |||
} | |||
} | |||
} | |||
@@ -213,7 +214,7 @@ public class WxCpMessageRouter { | |||
messageId = String.valueOf(wxMessage.getMsgId()); | |||
} | |||
return messageDuplicateChecker.isDuplicate(messageId); | |||
return this.messageDuplicateChecker.isDuplicate(messageId); | |||
} | |||
@@ -224,7 +225,7 @@ public class WxCpMessageRouter { | |||
*/ | |||
protected void sessionEndAccess(WxCpXmlMessage wxMessage) { | |||
InternalSession session = ((InternalSessionManager) sessionManager).findSession(wxMessage.getFromUserName()); | |||
InternalSession session = ((InternalSessionManager) this.sessionManager).findSession(wxMessage.getFromUserName()); | |||
if (session != null) { | |||
session.endAccess(); | |||
} | |||
@@ -36,9 +36,9 @@ public class WxCpMessageRouterRule { | |||
private Integer agentId; | |||
private List<WxCpMessageHandler> handlers = new ArrayList<WxCpMessageHandler>(); | |||
private List<WxCpMessageHandler> handlers = new ArrayList<>(); | |||
private List<WxCpMessageInterceptor> interceptors = new ArrayList<WxCpMessageInterceptor>(); | |||
private List<WxCpMessageInterceptor> interceptors = new ArrayList<>(); | |||
protected WxCpMessageRouterRule(WxCpMessageRouter routerBuilder) { | |||
this.routerBuilder = routerBuilder; | |||
@@ -235,7 +235,7 @@ public class WxCpMessageRouterRule { | |||
try { | |||
Map<String, Object> context = new HashMap<String, Object>(); | |||
Map<String, Object> context = new HashMap<>(); | |||
// 如果拦截器不通过 | |||
for (WxCpMessageInterceptor interceptor : this.interceptors) { | |||
if (!interceptor.intercept(wxMessage, context, wxCpService, sessionManager)) { | |||
@@ -300,7 +300,7 @@ public class WxCpMessageRouterRule { | |||
} | |||
public boolean isAsync() { | |||
return async; | |||
return this.async; | |||
} | |||
public void setAsync(boolean async) { | |||
@@ -308,7 +308,7 @@ public class WxCpMessageRouterRule { | |||
} | |||
public boolean isReEnter() { | |||
return reEnter; | |||
return this.reEnter; | |||
} | |||
public void setReEnter(boolean reEnter) { | |||
@@ -1,12 +1,28 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.List; | |||
import java.util.UUID; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.client.ClientProtocolException; | |||
import org.apache.http.client.config.RequestConfig; | |||
import org.apache.http.client.methods.CloseableHttpResponse; | |||
import org.apache.http.client.methods.HttpGet; | |||
import org.apache.http.impl.client.BasicResponseHandler; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.google.gson.JsonArray; | |||
import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.JsonPrimitive; | |||
import com.google.gson.internal.Streams; | |||
import com.google.gson.reflect.TypeToken; | |||
import com.google.gson.stream.JsonReader; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.bean.menu.WxMenu; | |||
@@ -20,30 +36,20 @@ import me.chanjar.weixin.common.util.RandomUtils; | |||
import me.chanjar.weixin.common.util.StringUtils; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import me.chanjar.weixin.common.util.http.*; | |||
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.DefaultApacheHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.URIUtil; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.cp.bean.WxCpDepart; | |||
import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpTag; | |||
import me.chanjar.weixin.cp.bean.WxCpUser; | |||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.client.ClientProtocolException; | |||
import org.apache.http.client.config.RequestConfig; | |||
import org.apache.http.client.methods.CloseableHttpResponse; | |||
import org.apache.http.client.methods.HttpGet; | |||
import org.apache.http.impl.client.BasicResponseHandler; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.StringReader; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.util.List; | |||
import java.util.UUID; | |||
public class WxCpServiceImpl implements WxCpService { | |||
@@ -59,7 +65,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
*/ | |||
protected final Object globalJsapiTicketRefreshLock = new Object(); | |||
protected WxCpConfigStorage wxCpConfigStorage; | |||
protected WxCpConfigStorage configStorage; | |||
protected CloseableHttpClient httpClient; | |||
@@ -72,42 +78,48 @@ public class WxCpServiceImpl implements WxCpService { | |||
private int retrySleepMillis = 1000; | |||
private int maxRetryTimes = 5; | |||
@Override | |||
public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { | |||
try { | |||
return SHA1.gen(wxCpConfigStorage.getToken(), timestamp, nonce, data).equals(msgSignature); | |||
return SHA1.gen(this.configStorage.getToken(), timestamp, nonce, data) | |||
.equals(msgSignature); | |||
} catch (Exception e) { | |||
return false; | |||
} | |||
} | |||
@Override | |||
public void userAuthenticated(String userId) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/authsucc?userid=" + userId; | |||
get(url, null); | |||
} | |||
@Override | |||
public String getAccessToken() throws WxErrorException { | |||
return getAccessToken(false); | |||
} | |||
@Override | |||
public String getAccessToken(boolean forceRefresh) throws WxErrorException { | |||
if (forceRefresh) { | |||
wxCpConfigStorage.expireAccessToken(); | |||
this.configStorage.expireAccessToken(); | |||
} | |||
if (wxCpConfigStorage.isAccessTokenExpired()) { | |||
synchronized (globalAccessTokenRefreshLock) { | |||
if (wxCpConfigStorage.isAccessTokenExpired()) { | |||
if (this.configStorage.isAccessTokenExpired()) { | |||
synchronized (this.globalAccessTokenRefreshLock) { | |||
if (this.configStorage.isAccessTokenExpired()) { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" | |||
+ "&corpid=" + wxCpConfigStorage.getCorpId() | |||
+ "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); | |||
+ "&corpid=" + this.configStorage.getCorpId() | |||
+ "&corpsecret=" + this.configStorage.getCorpSecret(); | |||
try { | |||
HttpGet httpGet = new HttpGet(url); | |||
if (httpProxy != null) { | |||
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||
if (this.httpProxy != null) { | |||
RequestConfig config = RequestConfig.custom() | |||
.setProxy(this.httpProxy).build(); | |||
httpGet.setConfig(config); | |||
} | |||
CloseableHttpClient httpclient = getHttpclient(); | |||
String resultContent = null; | |||
try (CloseableHttpResponse response = httpclient.execute(httpGet)) { | |||
try (CloseableHttpClient httpclient = getHttpclient(); | |||
CloseableHttpResponse response = httpclient.execute(httpGet)) { | |||
resultContent = new BasicResponseHandler().handleResponse(response); | |||
} finally { | |||
httpGet.releaseConnection(); | |||
@@ -117,7 +129,8 @@ public class WxCpServiceImpl implements WxCpService { | |||
throw new WxErrorException(error); | |||
} | |||
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | |||
wxCpConfigStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
this.configStorage.updateAccessToken( | |||
accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
} catch (ClientProtocolException e) { | |||
throw new RuntimeException(e); | |||
} catch (IOException e) { | |||
@@ -126,59 +139,60 @@ public class WxCpServiceImpl implements WxCpService { | |||
} | |||
} | |||
} | |||
return wxCpConfigStorage.getAccessToken(); | |||
return this.configStorage.getAccessToken(); | |||
} | |||
@Override | |||
public String getJsapiTicket() throws WxErrorException { | |||
return getJsapiTicket(false); | |||
} | |||
@Override | |||
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { | |||
if (forceRefresh) { | |||
wxCpConfigStorage.expireJsapiTicket(); | |||
this.configStorage.expireJsapiTicket(); | |||
} | |||
if (wxCpConfigStorage.isJsapiTicketExpired()) { | |||
synchronized (globalJsapiTicketRefreshLock) { | |||
if (wxCpConfigStorage.isJsapiTicketExpired()) { | |||
if (this.configStorage.isJsapiTicketExpired()) { | |||
synchronized (this.globalJsapiTicketRefreshLock) { | |||
if (this.configStorage.isJsapiTicketExpired()) { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket"; | |||
String responseContent = execute(new SimpleGetRequestExecutor(), url, null); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); | |||
String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); | |||
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); | |||
wxCpConfigStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds); | |||
this.configStorage.updateJsapiTicket(jsapiTicket, | |||
expiresInSeconds); | |||
} | |||
} | |||
} | |||
return wxCpConfigStorage.getJsapiTicket(); | |||
return this.configStorage.getJsapiTicket(); | |||
} | |||
@Override | |||
public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { | |||
long timestamp = System.currentTimeMillis() / 1000; | |||
String noncestr = RandomUtils.getRandomStr(); | |||
String jsapiTicket = getJsapiTicket(false); | |||
try { | |||
String signature = SHA1.genWithAmple( | |||
"jsapi_ticket=" + jsapiTicket, | |||
"noncestr=" + noncestr, | |||
"timestamp=" + timestamp, | |||
"url=" + url | |||
); | |||
WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | |||
jsapiSignature.setTimestamp(timestamp); | |||
jsapiSignature.setNoncestr(noncestr); | |||
jsapiSignature.setUrl(url); | |||
jsapiSignature.setSignature(signature); | |||
// Fixed bug | |||
jsapiSignature.setAppid(this.wxCpConfigStorage.getCorpId()); | |||
return jsapiSignature; | |||
} catch (NoSuchAlgorithmException e) { | |||
throw new RuntimeException(e); | |||
} | |||
String signature = SHA1.genWithAmple( | |||
"jsapi_ticket=" + jsapiTicket, | |||
"noncestr=" + noncestr, | |||
"timestamp=" + timestamp, | |||
"url=" + url | |||
); | |||
WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | |||
jsapiSignature.setTimestamp(timestamp); | |||
jsapiSignature.setNoncestr(noncestr); | |||
jsapiSignature.setUrl(url); | |||
jsapiSignature.setSignature(signature); | |||
// Fixed bug | |||
jsapiSignature.setAppid(this.configStorage.getCorpId()); | |||
return jsapiSignature; | |||
} | |||
@Override | |||
public void messageSend(WxCpMessage message) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send"; | |||
post(url, message.toJson()); | |||
@@ -186,18 +200,19 @@ public class WxCpServiceImpl implements WxCpService { | |||
@Override | |||
public void menuCreate(WxMenu menu) throws WxErrorException { | |||
menuCreate(wxCpConfigStorage.getAgentId(), menu); | |||
menuCreate(this.configStorage.getAgentId(), menu); | |||
} | |||
@Override | |||
public void menuCreate(String agentId, WxMenu menu) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid=" + wxCpConfigStorage.getAgentId(); | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid=" | |||
+ this.configStorage.getAgentId(); | |||
post(url, menu.toJson()); | |||
} | |||
@Override | |||
public void menuDelete() throws WxErrorException { | |||
menuDelete(wxCpConfigStorage.getAgentId()); | |||
menuDelete(this.configStorage.getAgentId()); | |||
} | |||
@Override | |||
@@ -208,7 +223,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
@Override | |||
public WxMenu menuGet() throws WxErrorException { | |||
return menuGet(wxCpConfigStorage.getAgentId()); | |||
return menuGet(this.configStorage.getAgentId()); | |||
} | |||
@Override | |||
@@ -226,42 +241,52 @@ public class WxCpServiceImpl implements WxCpService { | |||
} | |||
} | |||
@Override | |||
public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) | |||
throws WxErrorException, IOException { | |||
return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | |||
} | |||
@Override | |||
public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType; | |||
return execute(new MediaUploadRequestExecutor(), url, file); | |||
} | |||
@Override | |||
public File mediaDownload(String media_id) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; | |||
return execute(new MediaDownloadRequestExecutor(wxCpConfigStorage.getTmpDirFile()), url, "media_id=" + media_id); | |||
return execute( | |||
new MediaDownloadRequestExecutor( | |||
this.configStorage.getTmpDirFile()), | |||
url, "media_id=" + media_id); | |||
} | |||
@Override | |||
public Integer departCreate(WxCpDepart depart) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create"; | |||
String responseContent = execute( | |||
new SimplePostRequestExecutor(), | |||
url, | |||
depart.toJson()); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id")); | |||
} | |||
@Override | |||
public void departUpdate(WxCpDepart group) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/update"; | |||
post(url, group.toJson()); | |||
} | |||
@Override | |||
public void departDelete(Integer departId) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?id=" + departId; | |||
get(url, null); | |||
} | |||
@Override | |||
public List<WxCpDepart> departGet() throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/list"; | |||
String responseContent = get(url, null); | |||
@@ -269,7 +294,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
* 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} } | |||
* 查询时返回的是 { groups : [ { id : ..., name : ..., count : ... }, ... ] } | |||
*/ | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return WxCpGsonBuilder.INSTANCE.create() | |||
.fromJson( | |||
tmpJsonElement.getAsJsonObject().get("department"), | |||
@@ -329,7 +354,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
} | |||
String responseContent = get(url, params); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return WxCpGsonBuilder.INSTANCE.create() | |||
.fromJson( | |||
tmpJsonElement.getAsJsonObject().get("userlist"), | |||
@@ -352,7 +377,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
} | |||
String responseContent = get(url, params); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return WxCpGsonBuilder.INSTANCE.create() | |||
.fromJson( | |||
tmpJsonElement.getAsJsonObject().get("userlist"), | |||
@@ -367,7 +392,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
JsonObject o = new JsonObject(); | |||
o.addProperty("tagname", tagName); | |||
String responseContent = post(url, o.toString()); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return tmpJsonElement.getAsJsonObject().get("tagid").getAsString(); | |||
} | |||
@@ -390,7 +415,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
public List<WxCpTag> tagGet() throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/list"; | |||
String responseContent = get(url, null); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return WxCpGsonBuilder.INSTANCE.create() | |||
.fromJson( | |||
tmpJsonElement.getAsJsonObject().get("taglist"), | |||
@@ -403,7 +428,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
public List<WxCpUser> tagGetUsers(String tagId) throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/get?tagid=" + tagId; | |||
String responseContent = get(url, null); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return WxCpGsonBuilder.INSTANCE.create() | |||
.fromJson( | |||
tmpJsonElement.getAsJsonObject().get("userlist"), | |||
@@ -450,7 +475,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
@Override | |||
public String oauth2buildAuthorizationUrl(String state) { | |||
return this.oauth2buildAuthorizationUrl( | |||
this.wxCpConfigStorage.getOauth2redirectUri(), | |||
this.configStorage.getOauth2redirectUri(), | |||
state | |||
); | |||
} | |||
@@ -458,7 +483,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
@Override | |||
public String oauth2buildAuthorizationUrl(String redirectUri, String state) { | |||
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"; | |||
url += "appid=" + wxCpConfigStorage.getCorpId(); | |||
url += "appid=" + this.configStorage.getCorpId(); | |||
url += "&redirect_uri=" + URIUtil.encodeURIComponent(redirectUri); | |||
url += "&response_type=code"; | |||
url += "&scope=snsapi_base"; | |||
@@ -471,7 +496,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
@Override | |||
public String[] oauth2getUserInfo(String code) throws WxErrorException { | |||
return oauth2getUserInfo(wxCpConfigStorage.getAgentId(), code); | |||
return oauth2getUserInfo(this.configStorage.getAgentId(), code); | |||
} | |||
@Override | |||
@@ -480,7 +505,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
+ "code=" + code | |||
+ "&agendid=" + agentId; | |||
String responseText = get(url, null); | |||
JsonElement je = Streams.parse(new JsonReader(new StringReader(responseText))); | |||
JsonElement je = new JsonParser().parse(responseText); | |||
JsonObject jo = je.getAsJsonObject(); | |||
return new String[]{GsonHelper.getString(jo, "UserId"), GsonHelper.getString(jo, "DeviceId")}; | |||
} | |||
@@ -494,7 +519,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
jsonObject.addProperty("invite_tips", inviteTips); | |||
} | |||
String responseContent = post(url, jsonObject.toString()); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return tmpJsonElement.getAsJsonObject().get("type").getAsInt(); | |||
} | |||
@@ -502,7 +527,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
public String[] getCallbackIp() throws WxErrorException { | |||
String url = "https://qyapi.weixin.qq.com/cgi-bin/getcallbackip"; | |||
String responseContent = get(url, null); | |||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
JsonArray jsonArray = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray(); | |||
String[] ips = new String[jsonArray.size()]; | |||
for (int i = 0; i < jsonArray.size(); i++) { | |||
@@ -511,10 +536,12 @@ public class WxCpServiceImpl implements WxCpService { | |||
return ips; | |||
} | |||
@Override | |||
public String get(String url, String queryParam) throws WxErrorException { | |||
return execute(new SimpleGetRequestExecutor(), url, queryParam); | |||
} | |||
@Override | |||
public String post(String url, String postData) throws WxErrorException { | |||
return execute(new SimplePostRequestExecutor(), url, postData); | |||
} | |||
@@ -522,6 +549,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
/** | |||
* 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | |||
*/ | |||
@Override | |||
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||
int retryTimes = 0; | |||
do { | |||
@@ -533,9 +561,10 @@ public class WxCpServiceImpl implements WxCpService { | |||
* -1 系统繁忙, 1000ms后重试 | |||
*/ | |||
if (error.getErrorCode() == -1) { | |||
int sleepMillis = retrySleepMillis * (1 << retryTimes); | |||
int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | |||
try { | |||
log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis, retryTimes + 1); | |||
this.log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis, | |||
retryTimes + 1); | |||
Thread.sleep(sleepMillis); | |||
} catch (InterruptedException e1) { | |||
throw new RuntimeException(e1); | |||
@@ -544,7 +573,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
throw e; | |||
} | |||
} | |||
} while (++retryTimes < maxRetryTimes); | |||
} while (++retryTimes < this.maxRetryTimes); | |||
throw new RuntimeException("微信服务端异常,超出重试次数"); | |||
} | |||
@@ -559,7 +588,8 @@ public class WxCpServiceImpl implements WxCpService { | |||
uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; | |||
try { | |||
return executor.execute(getHttpclient(), httpProxy, uriWithAccessToken, data); | |||
return executor.execute(getHttpclient(), this.httpProxy, | |||
uriWithAccessToken, data); | |||
} catch (WxErrorException e) { | |||
WxError error = e.getError(); | |||
/* | |||
@@ -569,7 +599,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
*/ | |||
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { | |||
// 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | |||
wxCpConfigStorage.expireAccessToken(); | |||
this.configStorage.expireAccessToken(); | |||
return execute(executor, uri, data); | |||
} | |||
if (error.getErrorCode() != 0) { | |||
@@ -584,21 +614,28 @@ public class WxCpServiceImpl implements WxCpService { | |||
} | |||
protected CloseableHttpClient getHttpclient() { | |||
return httpClient; | |||
return this.httpClient; | |||
} | |||
@Override | |||
public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) { | |||
this.wxCpConfigStorage = wxConfigProvider; | |||
ApacheHttpClientBuilder apacheHttpClientBuilder = wxCpConfigStorage.getApacheHttpClientBuilder(); | |||
this.configStorage = wxConfigProvider; | |||
ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage | |||
.getApacheHttpClientBuilder(); | |||
if (null == apacheHttpClientBuilder) { | |||
apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); | |||
} | |||
apacheHttpClientBuilder.httpProxyHost(wxCpConfigStorage.getHttp_proxy_host()) | |||
.httpProxyPort(wxCpConfigStorage.getHttp_proxy_port()) | |||
.httpProxyUsername(wxCpConfigStorage.getHttp_proxy_username()) | |||
.httpProxyPassword(wxCpConfigStorage.getHttp_proxy_password()); | |||
httpClient = apacheHttpClientBuilder.build(); | |||
apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) | |||
.httpProxyPort(this.configStorage.getHttpProxyPort()) | |||
.httpProxyUsername(this.configStorage.getHttpProxyUsername()) | |||
.httpProxyPassword(this.configStorage.getHttpProxyPassword()); | |||
if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { | |||
this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); | |||
} | |||
this.httpClient = apacheHttpClientBuilder.build(); | |||
} | |||
@Override | |||
@@ -614,18 +651,18 @@ public class WxCpServiceImpl implements WxCpService { | |||
@Override | |||
public WxSession getSession(String id) { | |||
if (sessionManager == null) { | |||
if (this.sessionManager == null) { | |||
return null; | |||
} | |||
return sessionManager.getSession(id); | |||
return this.sessionManager.getSession(id); | |||
} | |||
@Override | |||
public WxSession getSession(String id, boolean create) { | |||
if (sessionManager == null) { | |||
if (this.sessionManager == null) { | |||
return null; | |||
} | |||
return sessionManager.getSession(id, create); | |||
return this.sessionManager.getSession(id, create); | |||
} | |||
@@ -657,7 +694,7 @@ public class WxCpServiceImpl implements WxCpService { | |||
} | |||
public File getTmpDirFile() { | |||
return tmpDirFile; | |||
return this.tmpDirFile; | |||
} | |||
public void setTmpDirFile(File tmpDirFile) { | |||
@@ -11,6 +11,10 @@ import java.io.Serializable; | |||
*/ | |||
public class WxCpDepart implements Serializable { | |||
/** | |||
* | |||
*/ | |||
private static final long serialVersionUID = -5028321625140879571L; | |||
private Integer id; | |||
private String name; | |||
private Integer parentId; | |||
@@ -21,7 +25,7 @@ public class WxCpDepart implements Serializable { | |||
} | |||
public Integer getId() { | |||
return id; | |||
return this.id; | |||
} | |||
public void setId(Integer id) { | |||
@@ -29,7 +33,7 @@ public class WxCpDepart implements Serializable { | |||
} | |||
public String getName() { | |||
return name; | |||
return this.name; | |||
} | |||
public void setName(String name) { | |||
@@ -37,7 +41,7 @@ public class WxCpDepart implements Serializable { | |||
} | |||
public Integer getParentId() { | |||
return parentId; | |||
return this.parentId; | |||
} | |||
public void setParentId(Integer parentId) { | |||
@@ -45,7 +49,7 @@ public class WxCpDepart implements Serializable { | |||
} | |||
public Integer getOrder() { | |||
return order; | |||
return this.order; | |||
} | |||
public void setOrder(Integer order) { | |||
@@ -59,10 +63,10 @@ public class WxCpDepart implements Serializable { | |||
@Override | |||
public String toString() { | |||
return "WxCpDepart{" + | |||
"id=" + id + | |||
", name='" + name + '\'' + | |||
", parentId=" + parentId + | |||
", order=" + order + | |||
"id=" + this.id + | |||
", name='" + this.name + '\'' + | |||
", parentId=" + this.parentId + | |||
", order=" + this.order + | |||
'}'; | |||
} | |||
} |
@@ -14,6 +14,10 @@ import java.util.List; | |||
*/ | |||
public class WxCpMessage implements Serializable { | |||
/** | |||
* | |||
*/ | |||
private static final long serialVersionUID = -2082278303476631708L; | |||
private String toUser; | |||
private String toParty; | |||
private String toTag; | |||
@@ -27,7 +31,7 @@ public class WxCpMessage implements Serializable { | |||
private String musicUrl; | |||
private String hqMusicUrl; | |||
private String safe; | |||
private List<WxArticle> articles = new ArrayList<WxArticle>(); | |||
private List<WxArticle> articles = new ArrayList<>(); | |||
/** | |||
* 获得文本消息builder | |||
@@ -72,7 +76,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getToUser() { | |||
return toUser; | |||
return this.toUser; | |||
} | |||
public void setToUser(String toUser) { | |||
@@ -80,7 +84,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getToParty() { | |||
return toParty; | |||
return this.toParty; | |||
} | |||
public void setToParty(String toParty) { | |||
@@ -88,7 +92,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getToTag() { | |||
return toTag; | |||
return this.toTag; | |||
} | |||
public void setToTag(String toTag) { | |||
@@ -96,7 +100,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getAgentId() { | |||
return agentId; | |||
return this.agentId; | |||
} | |||
public void setAgentId(String agentId) { | |||
@@ -104,7 +108,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getMsgType() { | |||
return msgType; | |||
return this.msgType; | |||
} | |||
/** | |||
@@ -125,7 +129,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getSafe() { | |||
return safe; | |||
return this.safe; | |||
} | |||
public void setSafe(String safe) { | |||
@@ -133,7 +137,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getContent() { | |||
return content; | |||
return this.content; | |||
} | |||
public void setContent(String content) { | |||
@@ -141,7 +145,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getMediaId() { | |||
return mediaId; | |||
return this.mediaId; | |||
} | |||
public void setMediaId(String mediaId) { | |||
@@ -149,7 +153,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getThumbMediaId() { | |||
return thumbMediaId; | |||
return this.thumbMediaId; | |||
} | |||
public void setThumbMediaId(String thumbMediaId) { | |||
@@ -157,7 +161,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getTitle() { | |||
return title; | |||
return this.title; | |||
} | |||
public void setTitle(String title) { | |||
@@ -165,7 +169,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getDescription() { | |||
return description; | |||
return this.description; | |||
} | |||
public void setDescription(String description) { | |||
@@ -173,7 +177,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getMusicUrl() { | |||
return musicUrl; | |||
return this.musicUrl; | |||
} | |||
public void setMusicUrl(String musicUrl) { | |||
@@ -181,7 +185,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getHqMusicUrl() { | |||
return hqMusicUrl; | |||
return this.hqMusicUrl; | |||
} | |||
public void setHqMusicUrl(String hqMusicUrl) { | |||
@@ -189,7 +193,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public List<WxArticle> getArticles() { | |||
return articles; | |||
return this.articles; | |||
} | |||
public void setArticles(List<WxArticle> articles) { | |||
@@ -208,7 +212,7 @@ public class WxCpMessage implements Serializable { | |||
private String picUrl; | |||
public String getTitle() { | |||
return title; | |||
return this.title; | |||
} | |||
public void setTitle(String title) { | |||
@@ -216,7 +220,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getDescription() { | |||
return description; | |||
return this.description; | |||
} | |||
public void setDescription(String description) { | |||
@@ -224,7 +228,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getUrl() { | |||
return url; | |||
return this.url; | |||
} | |||
public void setUrl(String url) { | |||
@@ -232,7 +236,7 @@ public class WxCpMessage implements Serializable { | |||
} | |||
public String getPicUrl() { | |||
return picUrl; | |||
return this.picUrl; | |||
} | |||
public void setPicUrl(String picUrl) { | |||
@@ -9,6 +9,11 @@ import java.io.Serializable; | |||
*/ | |||
public class WxCpTag implements Serializable { | |||
/** | |||
* | |||
*/ | |||
private static final long serialVersionUID = -7243320279646928402L; | |||
private String id; | |||
private String name; | |||
@@ -28,7 +33,7 @@ public class WxCpTag implements Serializable { | |||
} | |||
public String getName() { | |||
return name; | |||
return this.name; | |||
} | |||
public void setName(String name) { | |||
@@ -36,7 +41,7 @@ public class WxCpTag implements Serializable { | |||
} | |||
public String getId() { | |||
return id; | |||
return this.id; | |||
} | |||
public void setId(String id) { | |||
@@ -13,7 +13,11 @@ import java.util.List; | |||
*/ | |||
public class WxCpUser implements Serializable { | |||
private final List<Attr> extAttrs = new ArrayList<Attr>(); | |||
/** | |||
* | |||
*/ | |||
private static final long serialVersionUID = -5696099236344075582L; | |||
private final List<Attr> extAttrs = new ArrayList<>(); | |||
private String userId; | |||
private String name; | |||
private Integer[] departIds; | |||
@@ -32,7 +36,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getUserId() { | |||
return userId; | |||
return this.userId; | |||
} | |||
public void setUserId(String userId) { | |||
@@ -40,7 +44,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getName() { | |||
return name; | |||
return this.name; | |||
} | |||
public void setName(String name) { | |||
@@ -48,7 +52,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public Integer[] getDepartIds() { | |||
return departIds; | |||
return this.departIds; | |||
} | |||
public void setDepartIds(Integer[] departIds) { | |||
@@ -56,7 +60,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getGender() { | |||
return gender; | |||
return this.gender; | |||
} | |||
public void setGender(String gender) { | |||
@@ -64,7 +68,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getPosition() { | |||
return position; | |||
return this.position; | |||
} | |||
public void setPosition(String position) { | |||
@@ -72,7 +76,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getMobile() { | |||
return mobile; | |||
return this.mobile; | |||
} | |||
public void setMobile(String mobile) { | |||
@@ -80,7 +84,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getTel() { | |||
return tel; | |||
return this.tel; | |||
} | |||
public void setTel(String tel) { | |||
@@ -88,7 +92,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getEmail() { | |||
return email; | |||
return this.email; | |||
} | |||
public void setEmail(String email) { | |||
@@ -96,7 +100,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getWeiXinId() { | |||
return weiXinId; | |||
return this.weiXinId; | |||
} | |||
public void setWeiXinId(String weiXinId) { | |||
@@ -104,7 +108,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getAvatar() { | |||
return avatar; | |||
return this.avatar; | |||
} | |||
public void setAvatar(String avatar) { | |||
@@ -112,7 +116,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public Integer getStatus() { | |||
return status; | |||
return this.status; | |||
} | |||
public void setStatus(Integer status) { | |||
@@ -120,7 +124,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public Integer getEnable() { | |||
return enable; | |||
return this.enable; | |||
} | |||
public void setEnable(Integer enable) { | |||
@@ -132,7 +136,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public List<Attr> getExtAttrs() { | |||
return extAttrs; | |||
return this.extAttrs; | |||
} | |||
public String toJson() { | |||
@@ -150,7 +154,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getName() { | |||
return name; | |||
return this.name; | |||
} | |||
public void setName(String name) { | |||
@@ -158,7 +162,7 @@ public class WxCpUser implements Serializable { | |||
} | |||
public String getValue() { | |||
return value; | |||
return this.value; | |||
} | |||
public void setValue(String value) { | |||
@@ -32,6 +32,11 @@ public class WxCpXmlMessage implements Serializable { | |||
// 以下都是微信推送过来的消息的xml的element所对应的属性 | |||
/////////////////////// | |||
/** | |||
* | |||
*/ | |||
private static final long serialVersionUID = -1042994982179476410L; | |||
@XStreamAlias("AgentID") | |||
private Integer agentId; | |||
@@ -200,7 +205,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Integer getAgentId() { | |||
return agentId; | |||
return this.agentId; | |||
} | |||
public void setAgentId(Integer agentId) { | |||
@@ -208,7 +213,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getToUserName() { | |||
return toUserName; | |||
return this.toUserName; | |||
} | |||
public void setToUserName(String toUserName) { | |||
@@ -216,7 +221,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Long getCreateTime() { | |||
return createTime; | |||
return this.createTime; | |||
} | |||
public void setCreateTime(Long createTime) { | |||
@@ -236,7 +241,7 @@ public class WxCpXmlMessage implements Serializable { | |||
* </pre> | |||
*/ | |||
public String getMsgType() { | |||
return msgType; | |||
return this.msgType; | |||
} | |||
/** | |||
@@ -256,7 +261,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getContent() { | |||
return content; | |||
return this.content; | |||
} | |||
public void setContent(String content) { | |||
@@ -264,7 +269,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Long getMsgId() { | |||
return msgId; | |||
return this.msgId; | |||
} | |||
public void setMsgId(Long msgId) { | |||
@@ -272,7 +277,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getPicUrl() { | |||
return picUrl; | |||
return this.picUrl; | |||
} | |||
public void setPicUrl(String picUrl) { | |||
@@ -280,7 +285,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getMediaId() { | |||
return mediaId; | |||
return this.mediaId; | |||
} | |||
public void setMediaId(String mediaId) { | |||
@@ -288,7 +293,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getFormat() { | |||
return format; | |||
return this.format; | |||
} | |||
public void setFormat(String format) { | |||
@@ -296,7 +301,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getThumbMediaId() { | |||
return thumbMediaId; | |||
return this.thumbMediaId; | |||
} | |||
public void setThumbMediaId(String thumbMediaId) { | |||
@@ -304,7 +309,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Double getLocationX() { | |||
return locationX; | |||
return this.locationX; | |||
} | |||
public void setLocationX(Double locationX) { | |||
@@ -312,7 +317,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Double getLocationY() { | |||
return locationY; | |||
return this.locationY; | |||
} | |||
public void setLocationY(Double locationY) { | |||
@@ -320,7 +325,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Double getScale() { | |||
return scale; | |||
return this.scale; | |||
} | |||
public void setScale(Double scale) { | |||
@@ -328,7 +333,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getLabel() { | |||
return label; | |||
return this.label; | |||
} | |||
public void setLabel(String label) { | |||
@@ -336,7 +341,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getTitle() { | |||
return title; | |||
return this.title; | |||
} | |||
public void setTitle(String title) { | |||
@@ -344,7 +349,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getDescription() { | |||
return description; | |||
return this.description; | |||
} | |||
public void setDescription(String description) { | |||
@@ -352,7 +357,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getUrl() { | |||
return url; | |||
return this.url; | |||
} | |||
public void setUrl(String url) { | |||
@@ -360,7 +365,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getEvent() { | |||
return event; | |||
return this.event; | |||
} | |||
public void setEvent(String event) { | |||
@@ -368,7 +373,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getEventKey() { | |||
return eventKey; | |||
return this.eventKey; | |||
} | |||
public void setEventKey(String eventKey) { | |||
@@ -376,7 +381,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getTicket() { | |||
return ticket; | |||
return this.ticket; | |||
} | |||
public void setTicket(String ticket) { | |||
@@ -384,7 +389,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Double getLatitude() { | |||
return latitude; | |||
return this.latitude; | |||
} | |||
public void setLatitude(Double latitude) { | |||
@@ -392,7 +397,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Double getLongitude() { | |||
return longitude; | |||
return this.longitude; | |||
} | |||
public void setLongitude(Double longitude) { | |||
@@ -400,7 +405,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Double getPrecision() { | |||
return precision; | |||
return this.precision; | |||
} | |||
public void setPrecision(Double precision) { | |||
@@ -408,7 +413,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getRecognition() { | |||
return recognition; | |||
return this.recognition; | |||
} | |||
public void setRecognition(String recognition) { | |||
@@ -416,7 +421,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getFromUserName() { | |||
return fromUserName; | |||
return this.fromUserName; | |||
} | |||
public void setFromUserName(String fromUserName) { | |||
@@ -424,7 +429,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getStatus() { | |||
return status; | |||
return this.status; | |||
} | |||
public void setStatus(String status) { | |||
@@ -432,7 +437,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Integer getTotalCount() { | |||
return totalCount; | |||
return this.totalCount; | |||
} | |||
public void setTotalCount(Integer totalCount) { | |||
@@ -440,7 +445,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Integer getFilterCount() { | |||
return filterCount; | |||
return this.filterCount; | |||
} | |||
public void setFilterCount(Integer filterCount) { | |||
@@ -448,7 +453,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Integer getSentCount() { | |||
return sentCount; | |||
return this.sentCount; | |||
} | |||
public void setSentCount(Integer sentCount) { | |||
@@ -456,7 +461,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public Integer getErrorCount() { | |||
return errorCount; | |||
return this.errorCount; | |||
} | |||
public void setErrorCount(Integer errorCount) { | |||
@@ -464,7 +469,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public WxCpXmlMessage.ScanCodeInfo getScanCodeInfo() { | |||
return scanCodeInfo; | |||
return this.scanCodeInfo; | |||
} | |||
public void setScanCodeInfo(WxCpXmlMessage.ScanCodeInfo scanCodeInfo) { | |||
@@ -472,7 +477,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public WxCpXmlMessage.SendPicsInfo getSendPicsInfo() { | |||
return sendPicsInfo; | |||
return this.sendPicsInfo; | |||
} | |||
public void setSendPicsInfo(WxCpXmlMessage.SendPicsInfo sendPicsInfo) { | |||
@@ -480,7 +485,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public WxCpXmlMessage.SendLocationInfo getSendLocationInfo() { | |||
return sendLocationInfo; | |||
return this.sendLocationInfo; | |||
} | |||
public void setSendLocationInfo(WxCpXmlMessage.SendLocationInfo sendLocationInfo) { | |||
@@ -490,39 +495,39 @@ public class WxCpXmlMessage implements Serializable { | |||
@Override | |||
public String toString() { | |||
return "WxCpXmlMessage{" + | |||
"agentId=" + agentId + | |||
", toUserName='" + toUserName + '\'' + | |||
", fromUserName='" + fromUserName + '\'' + | |||
", createTime=" + createTime + | |||
", msgType='" + msgType + '\'' + | |||
", content='" + content + '\'' + | |||
", msgId=" + msgId + | |||
", picUrl='" + picUrl + '\'' + | |||
", mediaId='" + mediaId + '\'' + | |||
", format='" + format + '\'' + | |||
", thumbMediaId='" + thumbMediaId + '\'' + | |||
", locationX=" + locationX + | |||
", locationY=" + locationY + | |||
", scale=" + scale + | |||
", label='" + label + '\'' + | |||
", title='" + title + '\'' + | |||
", description='" + description + '\'' + | |||
", url='" + url + '\'' + | |||
", event='" + event + '\'' + | |||
", eventKey='" + eventKey + '\'' + | |||
", ticket='" + ticket + '\'' + | |||
", latitude=" + latitude + | |||
", longitude=" + longitude + | |||
", precision=" + precision + | |||
", recognition='" + recognition + '\'' + | |||
", status='" + status + '\'' + | |||
", totalCount=" + totalCount + | |||
", filterCount=" + filterCount + | |||
", sentCount=" + sentCount + | |||
", errorCount=" + errorCount + | |||
", scanCodeInfo=" + scanCodeInfo + | |||
", sendPicsInfo=" + sendPicsInfo + | |||
", sendLocationInfo=" + sendLocationInfo + | |||
"agentId=" + this.agentId + | |||
", toUserName='" + this.toUserName + '\'' + | |||
", fromUserName='" + this.fromUserName + '\'' + | |||
", createTime=" + this.createTime + | |||
", msgType='" + this.msgType + '\'' + | |||
", content='" + this.content + '\'' + | |||
", msgId=" + this.msgId + | |||
", picUrl='" + this.picUrl + '\'' + | |||
", mediaId='" + this.mediaId + '\'' + | |||
", format='" + this.format + '\'' + | |||
", thumbMediaId='" + this.thumbMediaId + '\'' + | |||
", locationX=" + this.locationX + | |||
", locationY=" + this.locationY + | |||
", scale=" + this.scale + | |||
", label='" + this.label + '\'' + | |||
", title='" + this.title + '\'' + | |||
", description='" + this.description + '\'' + | |||
", url='" + this.url + '\'' + | |||
", event='" + this.event + '\'' + | |||
", eventKey='" + this.eventKey + '\'' + | |||
", ticket='" + this.ticket + '\'' + | |||
", latitude=" + this.latitude + | |||
", longitude=" + this.longitude + | |||
", precision=" + this.precision + | |||
", recognition='" + this.recognition + '\'' + | |||
", status='" + this.status + '\'' + | |||
", totalCount=" + this.totalCount + | |||
", filterCount=" + this.filterCount + | |||
", sentCount=" + this.sentCount + | |||
", errorCount=" + this.errorCount + | |||
", scanCodeInfo=" + this.scanCodeInfo + | |||
", sendPicsInfo=" + this.sendPicsInfo + | |||
", sendLocationInfo=" + this.sendLocationInfo + | |||
'}'; | |||
} | |||
@@ -542,7 +547,7 @@ public class WxCpXmlMessage implements Serializable { | |||
*/ | |||
public String getScanType() { | |||
return scanType; | |||
return this.scanType; | |||
} | |||
public void setScanType(String scanType) { | |||
@@ -553,7 +558,7 @@ public class WxCpXmlMessage implements Serializable { | |||
* 扫描结果,即二维码对应的字符串信息 | |||
*/ | |||
public String getScanResult() { | |||
return scanResult; | |||
return this.scanResult; | |||
} | |||
public void setScanResult(String scanResult) { | |||
@@ -566,12 +571,12 @@ public class WxCpXmlMessage implements Serializable { | |||
public static class SendPicsInfo { | |||
@XStreamAlias("PicList") | |||
protected final List<Item> picList = new ArrayList<Item>(); | |||
protected final List<Item> picList = new ArrayList<>(); | |||
@XStreamAlias("Count") | |||
private Long count; | |||
public Long getCount() { | |||
return count; | |||
return this.count; | |||
} | |||
public void setCount(Long count) { | |||
@@ -579,7 +584,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public List<Item> getPicList() { | |||
return picList; | |||
return this.picList; | |||
} | |||
@XStreamAlias("item") | |||
@@ -590,11 +595,11 @@ public class WxCpXmlMessage implements Serializable { | |||
private String PicMd5Sum; | |||
public String getPicMd5Sum() { | |||
return PicMd5Sum; | |||
return this.PicMd5Sum; | |||
} | |||
public void setPicMd5Sum(String picMd5Sum) { | |||
PicMd5Sum = picMd5Sum; | |||
this.PicMd5Sum = picMd5Sum; | |||
} | |||
} | |||
} | |||
@@ -623,7 +628,7 @@ public class WxCpXmlMessage implements Serializable { | |||
private String poiname; | |||
public String getLocationX() { | |||
return locationX; | |||
return this.locationX; | |||
} | |||
public void setLocationX(String locationX) { | |||
@@ -631,7 +636,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getLocationY() { | |||
return locationY; | |||
return this.locationY; | |||
} | |||
public void setLocationY(String locationY) { | |||
@@ -639,7 +644,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getScale() { | |||
return scale; | |||
return this.scale; | |||
} | |||
public void setScale(String scale) { | |||
@@ -647,7 +652,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getLabel() { | |||
return label; | |||
return this.label; | |||
} | |||
public void setLabel(String label) { | |||
@@ -655,7 +660,7 @@ public class WxCpXmlMessage implements Serializable { | |||
} | |||
public String getPoiname() { | |||
return poiname; | |||
return this.poiname; | |||
} | |||
public void setPoiname(String poiname) { | |||
@@ -17,7 +17,7 @@ public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { | |||
} | |||
public String getMediaId() { | |||
return mediaId; | |||
return this.mediaId; | |||
} | |||
public void setMediaId(String mediaId) { | |||
@@ -62,7 +62,7 @@ public abstract class WxCpXmlOutMessage { | |||
} | |||
public String getToUserName() { | |||
return toUserName; | |||
return this.toUserName; | |||
} | |||
public void setToUserName(String toUserName) { | |||
@@ -70,7 +70,7 @@ public abstract class WxCpXmlOutMessage { | |||
} | |||
public String getFromUserName() { | |||
return fromUserName; | |||
return this.fromUserName; | |||
} | |||
public void setFromUserName(String fromUserName) { | |||
@@ -78,7 +78,7 @@ public abstract class WxCpXmlOutMessage { | |||
} | |||
public Long getCreateTime() { | |||
return createTime; | |||
return this.createTime; | |||
} | |||
public void setCreateTime(Long createTime) { | |||
@@ -86,7 +86,7 @@ public abstract class WxCpXmlOutMessage { | |||
} | |||
public String getMsgType() { | |||
return msgType; | |||
return this.msgType; | |||
} | |||
public void setMsgType(String msgType) { | |||
@@ -12,7 +12,7 @@ import java.util.List; | |||
public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | |||
@XStreamAlias("Articles") | |||
protected final List<Item> articles = new ArrayList<Item>(); | |||
protected final List<Item> articles = new ArrayList<>(); | |||
@XStreamAlias("ArticleCount") | |||
protected int articleCount; | |||
@@ -21,7 +21,7 @@ public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | |||
} | |||
public int getArticleCount() { | |||
return articleCount; | |||
return this.articleCount; | |||
} | |||
public void addArticle(Item item) { | |||
@@ -30,7 +30,7 @@ public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | |||
} | |||
public List<Item> getArticles() { | |||
return articles; | |||
return this.articles; | |||
} | |||
@@ -54,35 +54,35 @@ public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | |||
private String Url; | |||
public String getTitle() { | |||
return Title; | |||
return this.Title; | |||
} | |||
public void setTitle(String title) { | |||
Title = title; | |||
this.Title = title; | |||
} | |||
public String getDescription() { | |||
return Description; | |||
return this.Description; | |||
} | |||
public void setDescription(String description) { | |||
Description = description; | |||
this.Description = description; | |||
} | |||
public String getPicUrl() { | |||
return PicUrl; | |||
return this.PicUrl; | |||
} | |||
public void setPicUrl(String picUrl) { | |||
PicUrl = picUrl; | |||
this.PicUrl = picUrl; | |||
} | |||
public String getUrl() { | |||
return Url; | |||
return this.Url; | |||
} | |||
public void setUrl(String url) { | |||
Url = url; | |||
this.Url = url; | |||
} | |||
} | |||
@@ -17,7 +17,7 @@ public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { | |||
} | |||
public String getContent() { | |||
return content; | |||
return this.content; | |||
} | |||
public void setContent(String content) { | |||
@@ -16,27 +16,27 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||
} | |||
public String getMediaId() { | |||
return video.getMediaId(); | |||
return this.video.getMediaId(); | |||
} | |||
public void setMediaId(String mediaId) { | |||
video.setMediaId(mediaId); | |||
this.video.setMediaId(mediaId); | |||
} | |||
public String getTitle() { | |||
return video.getTitle(); | |||
return this.video.getTitle(); | |||
} | |||
public void setTitle(String title) { | |||
video.setTitle(title); | |||
this.video.setTitle(title); | |||
} | |||
public String getDescription() { | |||
return video.getDescription(); | |||
return this.video.getDescription(); | |||
} | |||
public void setDescription(String description) { | |||
video.setDescription(description); | |||
this.video.setDescription(description); | |||
} | |||
@@ -56,7 +56,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||
private String description; | |||
public String getMediaId() { | |||
return mediaId; | |||
return this.mediaId; | |||
} | |||
public void setMediaId(String mediaId) { | |||
@@ -64,7 +64,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||
} | |||
public String getTitle() { | |||
return title; | |||
return this.title; | |||
} | |||
public void setTitle(String title) { | |||
@@ -72,7 +72,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||
} | |||
public String getDescription() { | |||
return description; | |||
return this.description; | |||
} | |||
public void setDescription(String description) { | |||
@@ -17,7 +17,7 @@ public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { | |||
} | |||
public String getMediaId() { | |||
return mediaId; | |||
return this.mediaId; | |||
} | |||
public void setMediaId(String mediaId) { | |||
@@ -23,6 +23,7 @@ public final class FileBuilder extends BaseBuilder<FileBuilder> { | |||
return this; | |||
} | |||
@Override | |||
public WxCpMessage build() { | |||
WxCpMessage m = super.build(); | |||
m.setMediaId(this.mediaId); | |||
@@ -23,6 +23,7 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder> { | |||
return this; | |||
} | |||
@Override | |||
public WxCpMessage build() { | |||
WxCpMessage m = super.build(); | |||
m.setMediaId(this.mediaId); | |||
@@ -17,7 +17,7 @@ import java.util.List; | |||
*/ | |||
public final class NewsBuilder extends BaseBuilder<NewsBuilder> { | |||
private List<WxCpMessage.WxArticle> articles = new ArrayList<WxCpMessage.WxArticle>(); | |||
private List<WxCpMessage.WxArticle> articles = new ArrayList<>(); | |||
public NewsBuilder() { | |||
this.msgType = WxConsts.CUSTOM_MSG_NEWS; | |||
@@ -28,6 +28,7 @@ public final class NewsBuilder extends BaseBuilder<NewsBuilder> { | |||
return this; | |||
} | |||
@Override | |||
public WxCpMessage build() { | |||
WxCpMessage m = super.build(); | |||
m.setArticles(this.articles); | |||
@@ -23,6 +23,7 @@ public final class TextBuilder extends BaseBuilder<TextBuilder> { | |||
return this; | |||
} | |||
@Override | |||
public WxCpMessage build() { | |||
WxCpMessage m = super.build(); | |||
m.setContent(this.content); | |||
@@ -47,12 +47,13 @@ public final class VideoBuilder extends BaseBuilder<VideoBuilder> { | |||
return this; | |||
} | |||
@Override | |||
public WxCpMessage build() { | |||
WxCpMessage m = super.build(); | |||
m.setMediaId(this.mediaId); | |||
m.setTitle(title); | |||
m.setDescription(description); | |||
m.setThumbMediaId(thumbMediaId); | |||
m.setTitle(this.title); | |||
m.setDescription(this.description); | |||
m.setThumbMediaId(this.thumbMediaId); | |||
return m; | |||
} | |||
} |
@@ -23,6 +23,7 @@ public final class VoiceBuilder extends BaseBuilder<VoiceBuilder> { | |||
return this; | |||
} | |||
@Override | |||
public WxCpMessage build() { | |||
WxCpMessage m = super.build(); | |||
m.setMediaId(this.mediaId); | |||
@@ -16,6 +16,7 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder, WxCpXmlOutImag | |||
return this; | |||
} | |||
@Override | |||
public WxCpXmlOutImageMessage build() { | |||
WxCpXmlOutImageMessage m = new WxCpXmlOutImageMessage(); | |||
setCommon(m); | |||
@@ -13,16 +13,17 @@ import java.util.List; | |||
*/ | |||
public final class NewsBuilder extends BaseBuilder<NewsBuilder, WxCpXmlOutNewsMessage> { | |||
protected final List<Item> articles = new ArrayList<Item>(); | |||
protected final List<Item> articles = new ArrayList<>(); | |||
public NewsBuilder addArticle(Item item) { | |||
this.articles.add(item); | |||
return this; | |||
} | |||
@Override | |||
public WxCpXmlOutNewsMessage build() { | |||
WxCpXmlOutNewsMessage m = new WxCpXmlOutNewsMessage(); | |||
for (Item item : articles) { | |||
for (Item item : this.articles) { | |||
m.addArticle(item); | |||
} | |||
setCommon(m); | |||
@@ -15,6 +15,7 @@ public final class TextBuilder extends BaseBuilder<TextBuilder, WxCpXmlOutTextMe | |||
return this; | |||
} | |||
@Override | |||
public WxCpXmlOutTextMessage build() { | |||
WxCpXmlOutTextMessage m = new WxCpXmlOutTextMessage(); | |||
setCommon(m); | |||
@@ -28,12 +28,13 @@ public final class VideoBuilder extends BaseBuilder<VideoBuilder, WxCpXmlOutVide | |||
return this; | |||
} | |||
@Override | |||
public WxCpXmlOutVideoMessage build() { | |||
WxCpXmlOutVideoMessage m = new WxCpXmlOutVideoMessage(); | |||
setCommon(m); | |||
m.setTitle(title); | |||
m.setDescription(description); | |||
m.setMediaId(mediaId); | |||
m.setTitle(this.title); | |||
m.setDescription(this.description); | |||
m.setMediaId(this.mediaId); | |||
return m; | |||
} | |||
@@ -16,10 +16,11 @@ public final class VoiceBuilder extends BaseBuilder<VoiceBuilder, WxCpXmlOutVoic | |||
return this; | |||
} | |||
@Override | |||
public WxCpXmlOutVoiceMessage build() { | |||
WxCpXmlOutVoiceMessage m = new WxCpXmlOutVoiceMessage(); | |||
setCommon(m); | |||
m.setMediaId(mediaId); | |||
m.setMediaId(this.mediaId); | |||
return m; | |||
} | |||
@@ -19,6 +19,7 @@ import java.lang.reflect.Type; | |||
*/ | |||
public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDeserializer<WxCpDepart> { | |||
@Override | |||
public JsonElement serialize(WxCpDepart group, Type typeOfSrc, JsonSerializationContext context) { | |||
JsonObject json = new JsonObject(); | |||
if (group.getId() != null) { | |||
@@ -36,6 +37,7 @@ public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDe | |||
return json; | |||
} | |||
@Override | |||
public WxCpDepart deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||
throws JsonParseException { | |||
WxCpDepart depart = new WxCpDepart(); | |||
@@ -20,6 +20,7 @@ import java.lang.reflect.Type; | |||
*/ | |||
public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||
@Override | |||
public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializationContext context) { | |||
JsonObject messageJson = new JsonObject(); | |||
messageJson.addProperty("agentid", message.getAgentId()); | |||
@@ -19,6 +19,7 @@ import java.lang.reflect.Type; | |||
*/ | |||
public class WxCpTagGsonAdapter implements JsonSerializer<WxCpTag>, JsonDeserializer<WxCpTag> { | |||
@Override | |||
public JsonElement serialize(WxCpTag tag, Type typeOfSrc, JsonSerializationContext context) { | |||
JsonObject o = new JsonObject(); | |||
o.addProperty("tagid", tag.getId()); | |||
@@ -26,6 +27,7 @@ public class WxCpTagGsonAdapter implements JsonSerializer<WxCpTag>, JsonDeserial | |||
return o; | |||
} | |||
@Override | |||
public WxCpTag deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||
throws JsonParseException { | |||
JsonObject jsonObject = json.getAsJsonObject(); | |||
@@ -19,6 +19,7 @@ import java.lang.reflect.Type; | |||
*/ | |||
public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSerializer<WxCpUser> { | |||
@Override | |||
public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||
throws JsonParseException { | |||
JsonObject o = json.getAsJsonObject(); | |||
@@ -45,7 +45,7 @@ public class XStreamTransformer { | |||
} | |||
private static Map<Class, XStream> configXStreamInstance() { | |||
Map<Class, XStream> map = new HashMap<Class, XStream>(); | |||
Map<Class, XStream> map = new HashMap<>(); | |||
map.put(WxCpXmlMessage.class, config_WxCpXmlMessage()); | |||
map.put(WxCpXmlOutNewsMessage.class, config_WxCpXmlOutNewsMessage()); | |||
map.put(WxCpXmlOutTextMessage.class, config_WxCpXmlOutTextMessage()); | |||
@@ -1,12 +1,14 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import com.google.inject.Binder; | |||
import com.google.inject.Module; | |||
import com.thoughtworks.xstream.XStream; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import java.io.InputStream; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
public class ApiTestModule implements Module { | |||
@@ -19,13 +21,18 @@ public class ApiTestModule implements Module { | |||
@Override | |||
public void configure(Binder binder) { | |||
InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); | |||
WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, is1); | |||
WxCpServiceImpl wxService = new WxCpServiceImpl(); | |||
wxService.setWxCpConfigStorage(config); | |||
binder.bind(WxCpServiceImpl.class).toInstance(wxService); | |||
binder.bind(WxCpConfigStorage.class).toInstance(config); | |||
try (InputStream is1 = ClassLoader | |||
.getSystemResourceAsStream("test-config.xml")) { | |||
WxXmlCpInMemoryConfigStorage config = fromXml( | |||
WxXmlCpInMemoryConfigStorage.class, is1); | |||
WxCpServiceImpl wxService = new WxCpServiceImpl(); | |||
wxService.setWxCpConfigStorage(config); | |||
binder.bind(WxCpServiceImpl.class).toInstance(wxService); | |||
binder.bind(WxCpConfigStorage.class).toInstance(config); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
@XStreamAlias("xml") | |||
@@ -38,7 +45,7 @@ public class ApiTestModule implements Module { | |||
protected String tagId; | |||
public String getUserId() { | |||
return userId; | |||
return this.userId; | |||
} | |||
public void setUserId(String userId) { | |||
@@ -46,7 +53,7 @@ public class ApiTestModule implements Module { | |||
} | |||
public String getDepartmentId() { | |||
return departmentId; | |||
return this.departmentId; | |||
} | |||
public void setDepartmentId(String departmentId) { | |||
@@ -54,7 +61,7 @@ public class ApiTestModule implements Module { | |||
} | |||
public String getTagId() { | |||
return tagId; | |||
return this.tagId; | |||
} | |||
public void setTagId(String tagId) { | |||
@@ -64,9 +71,9 @@ public class ApiTestModule implements Module { | |||
@Override | |||
public String toString() { | |||
return super.toString() + " > WxXmlCpConfigStorage{" + | |||
"userId='" + userId + '\'' + | |||
", departmentId='" + departmentId + '\'' + | |||
", tagId='" + tagId + '\'' + | |||
"userId='" + this.userId + '\'' + | |||
", departmentId='" + this.departmentId + '\'' + | |||
", tagId='" + this.tagId + '\'' + | |||
'}'; | |||
} | |||
} | |||
@@ -1,12 +1,14 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.StringUtils; | |||
import org.testng.Assert; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.StringUtils; | |||
/** | |||
* 基础API测试 | |||
* | |||
@@ -20,9 +22,9 @@ public class WxCpBaseAPITest { | |||
protected WxCpServiceImpl wxService; | |||
public void testRefreshAccessToken() throws WxErrorException { | |||
WxCpConfigStorage configStorage = wxService.wxCpConfigStorage; | |||
WxCpConfigStorage configStorage = this.wxService.configStorage; | |||
String before = configStorage.getAccessToken(); | |||
wxService.getAccessToken(false); | |||
this.wxService.getAccessToken(false); | |||
String after = configStorage.getAccessToken(); | |||
@@ -1,16 +1,17 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import org.testng.annotations.DataProvider; | |||
import org.testng.annotations.Test; | |||
import java.util.concurrent.ExecutionException; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
import java.util.concurrent.Future; | |||
import org.testng.annotations.DataProvider; | |||
import org.testng.annotations.Test; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
@Test | |||
public class WxCpBusyRetryTest { | |||
@@ -19,7 +20,9 @@ public class WxCpBusyRetryTest { | |||
WxCpService service = new WxCpServiceImpl() { | |||
@Override | |||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||
protected synchronized <T, E> T executeInternal( | |||
RequestExecutor<T, E> executor, String uri, E data) | |||
throws WxErrorException { | |||
WxError error = new WxError(); | |||
error.setErrorCode(-1); | |||
throw new WxErrorException(error); | |||
@@ -1,13 +1,15 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.cp.bean.WxCpDepart; | |||
import java.util.List; | |||
import org.testng.Assert; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
import java.util.List; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.cp.bean.WxCpDepart; | |||
/** | |||
* 测试部门接口 | |||
@@ -24,22 +26,23 @@ public class WxCpDepartAPITest { | |||
protected WxCpDepart depart; | |||
public void testDepartCreate() throws WxErrorException { | |||
WxCpDepart depart = new WxCpDepart(); | |||
depart.setName("子部门" + System.currentTimeMillis()); | |||
depart.setParentId(1); | |||
depart.setOrder(1); | |||
Integer departId = wxCpService.departCreate(depart); | |||
WxCpDepart cpDepart = new WxCpDepart(); | |||
cpDepart.setName("子部门" + System.currentTimeMillis()); | |||
cpDepart.setParentId(1); | |||
cpDepart.setOrder(1); | |||
Integer departId = this.wxCpService.departCreate(cpDepart); | |||
System.out.println(departId); | |||
} | |||
@Test(dependsOnMethods = "testDepartCreate") | |||
public void testDepartGet() throws WxErrorException { | |||
System.out.println("=================获取部门"); | |||
List<WxCpDepart> departList = wxCpService.departGet(); | |||
List<WxCpDepart> departList = this.wxCpService.departGet(); | |||
Assert.assertNotNull(departList); | |||
Assert.assertTrue(departList.size() > 0); | |||
for (WxCpDepart g : departList) { | |||
depart = g; | |||
System.out.println(depart.getId() + ":" + depart.getName()); | |||
this.depart = g; | |||
System.out.println(this.depart.getId() + ":" + this.depart.getName()); | |||
Assert.assertNotNull(g.getName()); | |||
} | |||
} | |||
@@ -47,15 +50,15 @@ public class WxCpDepartAPITest { | |||
@Test(dependsOnMethods = {"testDepartGet", "testDepartCreate"}) | |||
public void testDepartUpdate() throws WxErrorException { | |||
System.out.println("=================更新部门"); | |||
depart.setName("子部门改名" + System.currentTimeMillis()); | |||
wxCpService.departUpdate(depart); | |||
this.depart.setName("子部门改名" + System.currentTimeMillis()); | |||
this.wxCpService.departUpdate(this.depart); | |||
} | |||
@Test(dependsOnMethods = "testDepartUpdate") | |||
public void testDepartDelete() throws WxErrorException { | |||
System.out.println("=================删除部门"); | |||
System.out.println(depart.getId() + ":" + depart.getName()); | |||
wxCpService.departDelete(depart.getId()); | |||
System.out.println(this.depart.getId() + ":" + this.depart.getName()); | |||
this.wxCpService.departDelete(this.depart.getId()); | |||
} | |||
} |
@@ -1,18 +1,20 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.testng.Assert; | |||
import org.testng.annotations.DataProvider; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
/** | |||
* 测试多媒体文件上传下载 | |||
@@ -27,21 +29,25 @@ public class WxCpMediaAPITest { | |||
@Inject | |||
protected WxCpServiceImpl wxService; | |||
private List<String> media_ids = new ArrayList<String>(); | |||
private List<String> media_ids = new ArrayList<>(); | |||
@Test(dataProvider = "uploadMedia") | |||
public void testUploadMedia(String mediaType, String fileType, String fileName) throws WxErrorException, IOException { | |||
InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName); | |||
WxMediaUploadResult res = wxService.mediaUpload(mediaType, fileType, inputStream); | |||
Assert.assertNotNull(res.getType()); | |||
Assert.assertNotNull(res.getCreatedAt()); | |||
Assert.assertTrue(res.getMediaId() != null || res.getThumbMediaId() != null); | |||
try (InputStream inputStream = ClassLoader | |||
.getSystemResourceAsStream(fileName);) { | |||
WxMediaUploadResult res = this.wxService.mediaUpload(mediaType, fileType, | |||
inputStream); | |||
Assert.assertNotNull(res.getType()); | |||
Assert.assertNotNull(res.getCreatedAt()); | |||
Assert.assertTrue( | |||
res.getMediaId() != null || res.getThumbMediaId() != null); | |||
if (res.getMediaId() != null) { | |||
media_ids.add(res.getMediaId()); | |||
} | |||
if (res.getThumbMediaId() != null) { | |||
media_ids.add(res.getThumbMediaId()); | |||
if (res.getMediaId() != null) { | |||
this.media_ids.add(res.getMediaId()); | |||
} | |||
if (res.getThumbMediaId() != null) { | |||
this.media_ids.add(res.getThumbMediaId()); | |||
} | |||
} | |||
} | |||
@@ -57,7 +63,7 @@ public class WxCpMediaAPITest { | |||
@Test(dependsOnMethods = {"testUploadMedia"}, dataProvider = "downloadMedia") | |||
public void testDownloadMedia(String media_id) throws WxErrorException { | |||
wxService.mediaDownload(media_id); | |||
this.wxService.mediaDownload(media_id); | |||
} | |||
@DataProvider | |||
@@ -1,11 +1,13 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
/*** | |||
* 测试发送消息 | |||
@@ -20,21 +22,21 @@ public class WxCpMessageAPITest { | |||
protected WxCpServiceImpl wxService; | |||
public void testSendCustomMessage() throws WxErrorException { | |||
ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) wxService.wxCpConfigStorage; | |||
ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) this.wxService.configStorage; | |||
WxCpMessage message1 = new WxCpMessage(); | |||
message1.setAgentId(configStorage.getAgentId()); | |||
message1.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||
message1.setToUser(configStorage.getUserId()); | |||
message1.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
wxService.messageSend(message1); | |||
this.wxService.messageSend(message1); | |||
WxCpMessage message2 = WxCpMessage | |||
.TEXT() | |||
.agentId(configStorage.getAgentId()) | |||
.toUser(configStorage.getUserId()) | |||
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>") | |||
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>") | |||
.build(); | |||
wxService.messageSend(message2); | |||
this.wxService.messageSend(message2); | |||
} | |||
@@ -286,7 +286,7 @@ public class WxCpMessageRouterTest { | |||
@Override | |||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService, | |||
WxSessionManager sessionManager) { | |||
sb.append(this.echoStr).append(','); | |||
this.sb.append(this.echoStr).append(','); | |||
return null; | |||
} | |||
@@ -23,44 +23,44 @@ public class WxCpTagAPITest { | |||
protected String tagId; | |||
public void testTagCreate() throws Exception { | |||
tagId = wxService.tagCreate("测试标签4"); | |||
System.out.println(tagId); | |||
this.tagId = this.wxService.tagCreate("测试标签4"); | |||
System.out.println(this.tagId); | |||
} | |||
@Test(dependsOnMethods = "testTagCreate") | |||
public void testTagUpdate() throws Exception { | |||
wxService.tagUpdate(tagId, "测试标签-改名"); | |||
this.wxService.tagUpdate(this.tagId, "测试标签-改名"); | |||
} | |||
@Test(dependsOnMethods = "testTagUpdate") | |||
public void testTagGet() throws Exception { | |||
List<WxCpTag> tags = wxService.tagGet(); | |||
List<WxCpTag> tags = this.wxService.tagGet(); | |||
Assert.assertNotEquals(tags.size(), 0); | |||
} | |||
@Test(dependsOnMethods = "testTagGet") | |||
public void testTagAddUsers() throws Exception { | |||
List<String> userIds = new ArrayList<String>(); | |||
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) configStorage).getUserId()); | |||
wxService.tagAddUsers(tagId, userIds, null); | |||
List<String> userIds = new ArrayList<>(); | |||
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) this.configStorage).getUserId()); | |||
this.wxService.tagAddUsers(this.tagId, userIds, null); | |||
} | |||
@Test(dependsOnMethods = "testTagAddUsers") | |||
public void testTagGetUsers() throws Exception { | |||
List<WxCpUser> users = wxService.tagGetUsers(tagId); | |||
List<WxCpUser> users = this.wxService.tagGetUsers(this.tagId); | |||
Assert.assertNotEquals(users.size(), 0); | |||
} | |||
@Test(dependsOnMethods = "testTagGetUsers") | |||
public void testTagRemoveUsers() throws Exception { | |||
List<String> userIds = new ArrayList<String>(); | |||
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) configStorage).getUserId()); | |||
wxService.tagRemoveUsers(tagId, userIds); | |||
List<String> userIds = new ArrayList<>(); | |||
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) this.configStorage).getUserId()); | |||
this.wxService.tagRemoveUsers(this.tagId, userIds); | |||
} | |||
@Test(dependsOnMethods = "testTagRemoveUsers") | |||
public void testTagDelete() throws Exception { | |||
wxService.tagDelete(tagId); | |||
this.wxService.tagDelete(this.tagId); | |||
} | |||
} |
@@ -35,7 +35,7 @@ public class WxCpUserAPITest { | |||
user.setPosition("woman"); | |||
user.setTel("3300393"); | |||
user.addExtAttr("爱好", "table"); | |||
wxCpService.userCreate(user); | |||
this.wxCpService.userCreate(user); | |||
} | |||
@Test(dependsOnMethods = "testUserCreate") | |||
@@ -44,23 +44,23 @@ public class WxCpUserAPITest { | |||
user.setUserId("some.woman"); | |||
user.setName("Some Woman"); | |||
user.addExtAttr("爱好", "table2"); | |||
wxCpService.userUpdate(user); | |||
this.wxCpService.userUpdate(user); | |||
} | |||
@Test(dependsOnMethods = "testUserUpdate") | |||
public void testUserGet() throws WxErrorException { | |||
WxCpUser user = wxCpService.userGet("some.woman"); | |||
WxCpUser user = this.wxCpService.userGet("some.woman"); | |||
Assert.assertNotNull(user); | |||
} | |||
@Test(dependsOnMethods = "testUserGet") | |||
public void testDepartGetUsers() throws WxErrorException { | |||
List<WxCpUser> users = wxCpService.departGetUsers(1, true, 0); | |||
List<WxCpUser> users = this.wxCpService.departGetUsers(1, true, 0); | |||
Assert.assertNotEquals(users.size(), 0); | |||
} | |||
@Test(dependsOnMethods = "testDepartGetUsers") | |||
public void testUserDelete() throws WxErrorException { | |||
wxCpService.userDelete("some.woman"); | |||
this.wxCpService.userDelete("some.woman"); | |||
} | |||
} |
@@ -24,17 +24,17 @@ public class WxMenuAPITest { | |||
@Test(dataProvider = "menu") | |||
public void testCreateMenu(WxMenu wxMenu) throws WxErrorException { | |||
wxService.menuCreate(wxMenu); | |||
this.wxService.menuCreate(wxMenu); | |||
} | |||
@Test(dependsOnMethods = {"testCreateMenu"}) | |||
public void testGetMenu() throws WxErrorException { | |||
Assert.assertNotNull(wxService.menuGet()); | |||
Assert.assertNotNull(this.wxService.menuGet()); | |||
} | |||
@Test(dependsOnMethods = {"testGetMenu"}) | |||
public void testDeleteMenu() throws WxErrorException { | |||
wxService.menuDelete(); | |||
this.wxService.menuDelete(); | |||
} | |||
@DataProvider(name = "menu") | |||
@@ -21,8 +21,8 @@ class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage { | |||
@Override | |||
public String toString() { | |||
return "SimpleWxConfigProvider [appidOrCorpid=" + corpId + ", corpSecret=" + corpSecret + ", accessToken=" + accessToken | |||
+ ", expiresTime=" + expiresTime + ", token=" + token + ", aesKey=" + aesKey + "]"; | |||
return "SimpleWxConfigProvider [appidOrCorpid=" + this.corpId + ", corpSecret=" + this.corpSecret + ", accessToken=" + this.accessToken | |||
+ ", expiresTime=" + this.expiresTime + ", token=" + this.token + ", aesKey=" + this.aesKey + "]"; | |||
} | |||
} |
@@ -1,16 +1,22 @@ | |||
package me.chanjar.weixin.cp.demo; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.cp.api.*; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.Map; | |||
import org.eclipse.jetty.server.Server; | |||
import org.eclipse.jetty.servlet.ServletHandler; | |||
import org.eclipse.jetty.servlet.ServletHolder; | |||
import java.io.InputStream; | |||
import java.util.Map; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.cp.api.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.api.WxCpMessageHandler; | |||
import me.chanjar.weixin.cp.api.WxCpMessageRouter; | |||
import me.chanjar.weixin.cp.api.WxCpService; | |||
import me.chanjar.weixin.cp.api.WxCpServiceImpl; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; | |||
public class WxCpDemoServer { | |||
@@ -36,55 +42,48 @@ public class WxCpDemoServer { | |||
server.join(); | |||
} | |||
private static void initWeixin() { | |||
InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); | |||
WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1); | |||
wxCpConfigStorage = config; | |||
wxCpService = new WxCpServiceImpl(); | |||
wxCpService.setWxCpConfigStorage(config); | |||
WxCpMessageHandler handler = new WxCpMessageHandler() { | |||
@Override | |||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, | |||
WxCpService wxCpService, WxSessionManager sessionManager) { | |||
WxCpXmlOutTextMessage m = WxCpXmlOutMessage | |||
.TEXT() | |||
.content("测试加密消息") | |||
.fromUser(wxMessage.getToUserName()) | |||
.toUser(wxMessage.getFromUserName()) | |||
.build(); | |||
return m; | |||
} | |||
}; | |||
WxCpMessageHandler oauth2handler = new WxCpMessageHandler() { | |||
@Override | |||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, | |||
WxCpService wxCpService, WxSessionManager sessionManager) { | |||
String href = "<a href=\"" + wxCpService.oauth2buildAuthorizationUrl(wxCpConfigStorage.getOauth2redirectUri(), null) | |||
+ "\">测试oauth2</a>"; | |||
return WxCpXmlOutMessage | |||
.TEXT() | |||
.content(href) | |||
.fromUser(wxMessage.getToUserName()) | |||
.toUser(wxMessage.getFromUserName()).build(); | |||
} | |||
}; | |||
wxCpMessageRouter = new WxCpMessageRouter(wxCpService); | |||
wxCpMessageRouter | |||
.rule() | |||
.async(false) | |||
.content("哈哈") // 拦截内容为“哈哈”的消息 | |||
.handler(handler) | |||
.end() | |||
.rule() | |||
.async(false) | |||
.content("oauth") | |||
.handler(oauth2handler) | |||
.end() | |||
; | |||
private static void initWeixin() throws IOException { | |||
try (InputStream is1 = ClassLoader | |||
.getSystemResourceAsStream("test-config.xml")) { | |||
WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage | |||
.fromXml(is1); | |||
wxCpConfigStorage = config; | |||
wxCpService = new WxCpServiceImpl(); | |||
wxCpService.setWxCpConfigStorage(config); | |||
WxCpMessageHandler handler = new WxCpMessageHandler() { | |||
@Override | |||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, | |||
Map<String, Object> context, WxCpService wxService, | |||
WxSessionManager sessionManager) { | |||
WxCpXmlOutTextMessage m = WxCpXmlOutMessage.TEXT().content("测试加密消息") | |||
.fromUser(wxMessage.getToUserName()) | |||
.toUser(wxMessage.getFromUserName()).build(); | |||
return m; | |||
} | |||
}; | |||
WxCpMessageHandler oauth2handler = new WxCpMessageHandler() { | |||
@Override | |||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, | |||
Map<String, Object> context, WxCpService wxService, | |||
WxSessionManager sessionManager) { | |||
String href = "<a href=\"" | |||
+ wxService.oauth2buildAuthorizationUrl( | |||
wxCpConfigStorage.getOauth2redirectUri(), null) | |||
+ "\">测试oauth2</a>"; | |||
return WxCpXmlOutMessage.TEXT().content(href) | |||
.fromUser(wxMessage.getToUserName()) | |||
.toUser(wxMessage.getFromUserName()).build(); | |||
} | |||
}; | |||
wxCpMessageRouter = new WxCpMessageRouter(wxCpService); | |||
wxCpMessageRouter.rule().async(false).content("哈哈") // 拦截内容为“哈哈”的消息 | |||
.handler(handler).end().rule().async(false).content("oauth") | |||
.handler(oauth2handler).end(); | |||
} | |||
} | |||
} |
@@ -1,5 +1,11 @@ | |||
package me.chanjar.weixin.cp.demo; | |||
import java.io.IOException; | |||
import javax.servlet.http.HttpServlet; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import me.chanjar.weixin.common.util.StringUtils; | |||
import me.chanjar.weixin.cp.api.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.api.WxCpMessageRouter; | |||
@@ -8,17 +14,11 @@ import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | |||
import javax.servlet.ServletException; | |||
import javax.servlet.http.HttpServlet; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import java.io.IOException; | |||
/** | |||
* @author Daniel Qian | |||
*/ | |||
public class WxCpEndpointServlet extends HttpServlet { | |||
private static final long serialVersionUID = 1L; | |||
protected WxCpConfigStorage wxCpConfigStorage; | |||
protected WxCpService wxCpService; | |||
protected WxCpMessageRouter wxCpMessageRouter; | |||
@@ -32,7 +32,7 @@ public class WxCpEndpointServlet extends HttpServlet { | |||
@Override | |||
protected void service(HttpServletRequest request, HttpServletResponse response) | |||
throws ServletException, IOException { | |||
throws IOException { | |||
response.setContentType("text/html;charset=utf-8"); | |||
response.setStatus(HttpServletResponse.SC_OK); | |||
@@ -43,12 +43,12 @@ public class WxCpEndpointServlet extends HttpServlet { | |||
String echostr = request.getParameter("echostr"); | |||
if (StringUtils.isNotBlank(echostr)) { | |||
if (!wxCpService.checkSignature(msgSignature, timestamp, nonce, echostr)) { | |||
if (!this.wxCpService.checkSignature(msgSignature, timestamp, nonce, echostr)) { | |||
// 消息签名不正确,说明不是公众平台发过来的消息 | |||
response.getWriter().println("非法请求"); | |||
return; | |||
} | |||
WxCpCryptUtil cryptUtil = new WxCpCryptUtil(wxCpConfigStorage); | |||
WxCpCryptUtil cryptUtil = new WxCpCryptUtil(this.wxCpConfigStorage); | |||
String plainText = cryptUtil.decrypt(echostr); | |||
// 说明是一个仅仅用来验证的请求,回显echostr | |||
response.getWriter().println(plainText); | |||
@@ -56,10 +56,10 @@ public class WxCpEndpointServlet extends HttpServlet { | |||
} | |||
WxCpXmlMessage inMessage = WxCpXmlMessage | |||
.fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature); | |||
WxCpXmlOutMessage outMessage = wxCpMessageRouter.route(inMessage); | |||
.fromEncryptedXml(request.getInputStream(), this.wxCpConfigStorage, timestamp, nonce, msgSignature); | |||
WxCpXmlOutMessage outMessage = this.wxCpMessageRouter.route(inMessage); | |||
if (outMessage != null) { | |||
response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage)); | |||
response.getWriter().write(outMessage.toEncryptedXml(this.wxCpConfigStorage)); | |||
} | |||
return; | |||
@@ -1,16 +1,17 @@ | |||
package me.chanjar.weixin.cp.demo; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.cp.api.WxCpService; | |||
import java.io.IOException; | |||
import java.util.Arrays; | |||
import javax.servlet.ServletException; | |||
import javax.servlet.http.HttpServlet; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import java.io.IOException; | |||
import java.util.Arrays; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.cp.api.WxCpService; | |||
public class WxCpOAuth2Servlet extends HttpServlet { | |||
private static final long serialVersionUID = 1L; | |||
protected WxCpService wxCpService; | |||
@@ -20,7 +21,7 @@ public class WxCpOAuth2Servlet extends HttpServlet { | |||
@Override | |||
protected void service(HttpServletRequest request, HttpServletResponse response) | |||
throws ServletException, IOException { | |||
throws IOException { | |||
response.setContentType("text/html;charset=utf-8"); | |||
response.setStatus(HttpServletResponse.SC_OK); | |||
@@ -30,7 +31,7 @@ public class WxCpOAuth2Servlet extends HttpServlet { | |||
response.getWriter().println("<h1>code</h1>"); | |||
response.getWriter().println(code); | |||
String[] res = wxCpService.oauth2getUserInfo(code); | |||
String[] res = this.wxCpService.oauth2getUserInfo(code); | |||
response.getWriter().println("<h1>result</h1>"); | |||
response.getWriter().println(Arrays.toString(res)); | |||
} catch (WxErrorException e) { | |||
@@ -6,7 +6,7 @@ | |||
<parent> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-parent</artifactId> | |||
<version>2.1.0</version> | |||
<version>2.1.2</version> | |||
</parent> | |||
<artifactId>weixin-java-mp</artifactId> | |||
<name>WeiXin Java Tools - MP</name> | |||
@@ -47,7 +47,7 @@ | |||
<groupId>org.eclipse.jetty</groupId> | |||
<artifactId>jetty-servlet</artifactId> | |||
<scope>test</scope> | |||
</dependency><!-- https://mvnrepository.com/artifact/joda-time/joda-time --> | |||
</dependency> | |||
<dependency> | |||
<groupId>joda-time</groupId> | |||
<artifactId>joda-time</artifactId> | |||
@@ -8,8 +8,10 @@ import java.util.List; | |||
/** | |||
* 用户分组相关操作接口 | |||
* @author Binary Wang | |||
* 分组接口属于老接口,不知道啥时候被替换成用户标签接口 | |||
* | |||
*/ | |||
@Deprecated | |||
public interface WxMpGroupService { | |||
@@ -1,12 +1,18 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.result.*; | |||
import java.io.File; | |||
import java.util.Date; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList; | |||
/** | |||
* 客服接口 , | |||
* 命名采用kefu拼音的原因是: | |||
@@ -17,6 +23,14 @@ import java.util.Date; | |||
*/ | |||
public interface WxMpKefuService { | |||
/** | |||
* <pre> | |||
* 发送客服消息 | |||
* 详情请见: <a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547&token=&lang=zh_CN">发送客服消息</a> | |||
* </pre> | |||
*/ | |||
boolean customMessageSend(WxMpCustomMessage message) throws WxErrorException; | |||
//*******************客服管理接口***********************// | |||
/** | |||
@@ -1,24 +1,25 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.concurrent.ExecutionException; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
import java.util.concurrent.Future; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | |||
import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; | |||
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; | |||
import me.chanjar.weixin.common.session.InternalSession; | |||
import me.chanjar.weixin.common.session.InternalSessionManager; | |||
import me.chanjar.weixin.common.session.StandardSessionManager; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.common.util.LogExceptionHandler; | |||
import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | |||
import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; | |||
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.concurrent.ExecutionException; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
import java.util.concurrent.Future; | |||
/** | |||
* <pre> | |||
@@ -155,7 +156,7 @@ public class WxMpMessageRouter { | |||
} | |||
WxMpXmlOutMessage res = null; | |||
final List<Future> futures = new ArrayList<>(); | |||
final List<Future<?>> futures = new ArrayList<>(); | |||
for (final WxMpMessageRouterRule rule : matchRules) { | |||
// 返回最后一个非异步的rule的执行结果 | |||
if(rule.isAsync()) { | |||
@@ -179,7 +180,7 @@ public class WxMpMessageRouter { | |||
this.executorService.submit(new Runnable() { | |||
@Override | |||
public void run() { | |||
for (Future future : futures) { | |||
for (Future<?> future : futures) { | |||
try { | |||
future.get(); | |||
WxMpMessageRouter.this.log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUserName()); | |||
@@ -3,18 +3,25 @@ package me.chanjar.weixin.mp.api; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.mp.bean.*; | |||
import me.chanjar.weixin.mp.bean.result.*; | |||
import java.text.SimpleDateFormat; | |||
import me.chanjar.weixin.mp.bean.WxMpIndustry; | |||
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassNews; | |||
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassVideo; | |||
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; | |||
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUser; | |||
/** | |||
* 微信API的Service | |||
*/ | |||
public interface WxMpService { | |||
SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); | |||
/** | |||
* <pre> | |||
* 验证推送过来的消息的正确性 | |||
@@ -74,14 +81,6 @@ public interface WxMpService { | |||
*/ | |||
WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 发送客服消息 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=发送客服消息 | |||
* </pre> | |||
*/ | |||
void customMessageSend(WxMpCustomMessage message) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 上传群发用的图文消息,上传后才能群发图文消息 | |||
@@ -152,6 +151,20 @@ public interface WxMpService { | |||
*/ | |||
WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 构造第三方使用网站应用授权登录的url | |||
* 详情请见: <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN">网站应用微信登录开发指南</a> | |||
* URL格式为:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect | |||
* </pre> | |||
* | |||
* @param redirectURI 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode | |||
* @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 | |||
* @param state 非必填,用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 | |||
* @return url | |||
*/ | |||
String buildQrConnectUrl(String redirectURI, String scope, String state); | |||
/** | |||
* <pre> | |||
* 构造oauth2授权的url连接 | |||
@@ -314,8 +327,16 @@ public interface WxMpService { | |||
* | |||
* @return WxMpGroupService | |||
*/ | |||
WxMpGroupService getGroupService(); | |||
/** | |||
* 返回用户标签相关接口的方法实现类,以方便调用个其各种接口 | |||
* | |||
* @return WxMpUserTagService | |||
*/ | |||
WxMpUserTagService getUserTagService(); | |||
/** | |||
* 返回二维码相关接口的方法实现类,以方便调用个其各种接口 | |||
* | |||
@@ -343,4 +364,11 @@ public interface WxMpService { | |||
* @return WxMpDataCubeService | |||
*/ | |||
WxMpDataCubeService getDataCubeService(); | |||
/** | |||
* 返回用户黑名单管理相关接口的方法实现类,以方便调用其各种借口 | |||
* | |||
* @return WxMpUserBlackListService | |||
*/ | |||
WxMpUserBlacklistService getBlackListService(); | |||
} |
@@ -0,0 +1,35 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult; | |||
import java.util.List; | |||
/** | |||
* @author miller | |||
*/ | |||
public interface WxMpUserBlacklistService { | |||
/** | |||
* <pre> | |||
* 获取公众号的黑名单列表 | |||
* 详情请见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN | |||
* </pre> | |||
*/ | |||
WxMpUserBlacklistGetResult getBlacklist(String nextOpenid) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 拉黑用户 | |||
* 详情请见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN | |||
* </pre> | |||
*/ | |||
void pushToBlacklist(List<String> openidList) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 取消拉黑用户 | |||
* 详情请见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN | |||
* </pre> | |||
*/ | |||
void pullFromBlacklist(List<String> openidList) throws WxErrorException; | |||
} |
@@ -0,0 +1,58 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import java.util.List; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.tag.WxUserTag; | |||
/** | |||
* 用户标签管理相关接口 | |||
* Created by Binary Wang on 2016/9/2. | |||
* @author binarywang(https://github.com/binarywang) | |||
* | |||
*/ | |||
public interface WxMpUserTagService { | |||
/** | |||
* <pre> | |||
* 创建标签 | |||
* 一个公众号,最多可以创建100个标签。 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">用户标签管理</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/tags/create?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* | |||
* @param name 标签名字(30个字符以内) | |||
*/ | |||
WxUserTag tagCreate(String name) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 获取公众号已创建的标签 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">用户标签管理</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/tags/get?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* | |||
*/ | |||
List<WxUserTag> tagGet() throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 编辑标签 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">用户标签管理</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/tags/update?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* | |||
*/ | |||
Boolean tagUpdate(Integer id, String name) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 删除标签 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">用户标签管理</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/tags/delete?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* | |||
*/ | |||
Boolean tagDelete(Integer id) throws WxErrorException; | |||
} |
@@ -1,6 +1,5 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.util.Arrays; | |||
import org.slf4j.Logger; | |||
@@ -111,16 +110,12 @@ public class WxMpCardServiceImpl implements WxMpCardService { | |||
signParam[optionalSignParam.length] = String.valueOf(timestamp); | |||
signParam[optionalSignParam.length + 1] = nonceStr; | |||
signParam[optionalSignParam.length + 2] = cardApiTicket; | |||
try { | |||
String signature = SHA1.gen(signParam); | |||
WxCardApiSignature cardApiSignature = new WxCardApiSignature(); | |||
cardApiSignature.setTimestamp(timestamp); | |||
cardApiSignature.setNonceStr(nonceStr); | |||
cardApiSignature.setSignature(signature); | |||
return cardApiSignature; | |||
} catch (NoSuchAlgorithmException e) { | |||
throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build()); | |||
} | |||
String signature = SHA1.gen(signParam); | |||
WxCardApiSignature cardApiSignature = new WxCardApiSignature(); | |||
cardApiSignature.setTimestamp(timestamp); | |||
cardApiSignature.setNonceStr(nonceStr); | |||
cardApiSignature.setSignature(signature); | |||
return cardApiSignature; | |||
} | |||
/** | |||
@@ -1,8 +1,15 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import java.text.Format; | |||
import java.util.Date; | |||
import java.util.List; | |||
import org.apache.commons.lang3.time.FastDateFormat; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.reflect.TypeToken; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.api.WxMpDataCubeService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
@@ -12,12 +19,6 @@ import me.chanjar.weixin.mp.bean.datacube.WxDataCubeInterfaceResult; | |||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeMsgResult; | |||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; | |||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.util.Date; | |||
import java.util.List; | |||
/** | |||
* Created by Binary Wang on 2016/8/23. | |||
@@ -27,6 +28,9 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
protected final Logger log = LoggerFactory.getLogger(WxMpDataCubeServiceImpl.class); | |||
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/datacube"; | |||
private final Format dateFormat = FastDateFormat.getInstance("yyyy-MM-dd"); | |||
private WxMpService wxMpService; | |||
public WxMpDataCubeServiceImpl(WxMpService wxMpService) { | |||
@@ -37,104 +41,88 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
public List<WxDataCubeUserSummary> getUserSummary(Date beginDate, Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getusersummary"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeUserSummary>>() { | |||
}.getType()); | |||
return WxDataCubeUserSummary.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<WxDataCubeUserCumulate> getUserCumulate(Date beginDate, Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getusercumulate"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeUserCumulate>>() { | |||
}.getType()); | |||
return WxDataCubeUserCumulate.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<WxDataCubeArticleResult> getArticleSummary(Date beginDate, Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getarticlesummary"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeArticleResult>>() { | |||
}.getType()); | |||
return WxDataCubeArticleResult.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<WxDataCubeArticleTotal> getArticleTotal(Date beginDate, Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getarticletotal"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeArticleTotal>>() { | |||
}.getType()); | |||
return WxDataCubeArticleTotal.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<WxDataCubeArticleResult> getUserRead(Date beginDate, Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getuserread"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeArticleResult>>() { | |||
}.getType()); | |||
return WxDataCubeArticleResult.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<WxDataCubeArticleResult> getUserReadHour(Date beginDate, Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getuserreadhour"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeArticleResult>>() { | |||
}.getType()); | |||
return WxDataCubeArticleResult.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<WxDataCubeArticleResult> getUserShare(Date beginDate, Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getusershare"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeArticleResult>>() { | |||
}.getType()); | |||
return WxDataCubeArticleResult.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<WxDataCubeArticleResult> getUserShareHour(Date beginDate, Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getusersharehour"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeArticleResult>>() { | |||
}.getType()); | |||
return WxDataCubeArticleResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -142,13 +130,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getupstreammsg"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeMsgResult>>() { | |||
}.getType()); | |||
return WxDataCubeMsgResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -156,13 +142,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getupstreammsghour"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeMsgResult>>() { | |||
}.getType()); | |||
return WxDataCubeMsgResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -170,13 +154,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getupstreammsgweek"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeMsgResult>>() { | |||
}.getType()); | |||
return WxDataCubeMsgResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -184,13 +166,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getupstreammsgmonth"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeMsgResult>>() { | |||
}.getType()); | |||
return WxDataCubeMsgResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -198,13 +178,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getupstreammsgdist"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeMsgResult>>() { | |||
}.getType()); | |||
return WxDataCubeMsgResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -212,13 +190,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getupstreammsgdistweek"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeMsgResult>>() { | |||
}.getType()); | |||
return WxDataCubeMsgResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -226,13 +202,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getupstreammsgdistmonth"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeMsgResult>>() { | |||
}.getType()); | |||
return WxDataCubeMsgResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -240,13 +214,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getinterfacesummary"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeInterfaceResult>>() { | |||
}.getType()); | |||
return WxDataCubeInterfaceResult.fromJson(responseContent); | |||
} | |||
@Override | |||
@@ -254,12 +226,10 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService { | |||
Date endDate) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/getinterfacesummaryhour"; | |||
JsonObject param = new JsonObject(); | |||
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate)); | |||
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate)); | |||
param.addProperty("begin_date", this.dateFormat.format(beginDate)); | |||
param.addProperty("end_date", this.dateFormat.format(endDate)); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent); | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeInterfaceResult>>() { | |||
}.getType()); | |||
return WxDataCubeInterfaceResult.fromJson(responseContent); | |||
} | |||
} |
@@ -1,12 +1,9 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import java.util.List; | |||
import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.reflect.TypeToken; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
@@ -16,9 +13,12 @@ import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.WxMpGroup; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
import java.util.List; | |||
/** | |||
* Created by Binary Wang on 2016/7/21. | |||
*/ | |||
@Deprecated | |||
public class WxMpGroupServiceImpl implements WxMpGroupService { | |||
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/groups"; | |||
private WxMpService wxMpService; | |||
@@ -3,15 +3,18 @@ package me.chanjar.weixin.mp.api.impl; | |||
import java.io.File; | |||
import java.util.Date; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.google.gson.JsonObject; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.mp.api.WxMpKefuService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; | |||
@@ -27,6 +30,8 @@ import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList; | |||
* | |||
*/ | |||
public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
protected final Logger log = LoggerFactory | |||
.getLogger(WxMpKefuServiceImpl.class); | |||
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/customservice"; | |||
private WxMpService wxMpService; | |||
@@ -34,19 +39,31 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
this.wxMpService = wxMpService; | |||
} | |||
@Override | |||
public boolean customMessageSend(WxMpCustomMessage message) | |||
throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send"; | |||
String responseContent = this.wxMpService.post(url, message.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, message.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@Override | |||
public WxMpKfList kfList() throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist"; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String url = API_URL_PREFIX + "/getkflist"; | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfList.fromJson(responseContent); | |||
} | |||
@Override | |||
public WxMpKfOnlineList kfOnlineList() throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist"; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String url = API_URL_PREFIX + "/getonlinekflist"; | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfOnlineList.fromJson(responseContent); | |||
} | |||
@@ -54,8 +71,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public boolean kfAccountAdd(WxMpKfAccountRequest request) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/add"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@@ -63,16 +81,18 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public boolean kfAccountUpdate(WxMpKfAccountRequest request) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/update"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/inviteworker"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@@ -80,14 +100,20 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/uploadheadimg?kf_account=" + kfAccount; | |||
this.wxMpService.execute(new MediaUploadRequestExecutor(), url, imgFile); | |||
WxMediaUploadResult responseContent = this.wxMpService | |||
.execute(new MediaUploadRequestExecutor(), url, imgFile); | |||
this.log.debug("\nurl:{}\nparams:{}&file:{}\nresponse:{}", url, kfAccount, | |||
imgFile.getAbsolutePath(), | |||
responseContent); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfAccountDel(String kfAccount) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/del?kf_account=" + kfAccount; | |||
this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null); | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return true; | |||
} | |||
@@ -96,8 +122,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
throws WxErrorException { | |||
WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); | |||
String url = API_URL_PREFIX + "/kfsession/create"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@@ -106,8 +133,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
throws WxErrorException { | |||
WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); | |||
String url = API_URL_PREFIX + "/kfsession/close"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@@ -115,8 +143,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public WxMpKfSessionGetResult kfSessionGet(String openid) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfsession/getsession?openid=" + openid; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfSessionGetResult.fromJson(responseContent); | |||
} | |||
@@ -124,8 +153,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public WxMpKfSessionList kfSessionList(String kfAccount) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfsession/getsessionlist?kf_account=" + kfAccount; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfSessionList.fromJson(responseContent); | |||
} | |||
@@ -133,8 +163,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public WxMpKfSessionWaitCaseList kfSessionGetWaitCase() | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfsession/getwaitcase"; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfSessionWaitCaseList.fromJson(responseContent); | |||
} | |||
@@ -156,7 +187,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
param.addProperty("msgid", msgId); //msgid 消息id顺序从小到大,从1开始 | |||
param.addProperty("number", number); //number 每次获取条数,最多10000条 | |||
String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, param.toString()); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, param.toString(), | |||
responseContent); | |||
return WxMpKfMsgList.fromJson(responseContent); | |||
} | |||
@@ -12,10 +12,38 @@ import me.chanjar.weixin.common.session.StandardSessionManager; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.common.util.RandomUtils; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.common.util.http.*; | |||
import me.chanjar.weixin.mp.api.*; | |||
import me.chanjar.weixin.mp.bean.*; | |||
import me.chanjar.weixin.mp.bean.result.*; | |||
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.DefaultApacheHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.URIUtil; | |||
import me.chanjar.weixin.mp.api.WxMpCardService; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpDataCubeService; | |||
import me.chanjar.weixin.mp.api.WxMpGroupService; | |||
import me.chanjar.weixin.mp.api.WxMpKefuService; | |||
import me.chanjar.weixin.mp.api.WxMpMaterialService; | |||
import me.chanjar.weixin.mp.api.WxMpMenuService; | |||
import me.chanjar.weixin.mp.api.WxMpPayService; | |||
import me.chanjar.weixin.mp.api.WxMpQrcodeService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.api.WxMpUserBlacklistService; | |||
import me.chanjar.weixin.mp.api.WxMpUserService; | |||
import me.chanjar.weixin.mp.api.WxMpUserTagService; | |||
import me.chanjar.weixin.mp.bean.WxMpIndustry; | |||
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassNews; | |||
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassVideo; | |||
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; | |||
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUser; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.client.config.RequestConfig; | |||
import org.apache.http.client.methods.CloseableHttpResponse; | |||
@@ -28,7 +56,6 @@ import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.IOException; | |||
import java.security.NoSuchAlgorithmException; | |||
public class WxMpServiceImpl implements WxMpService { | |||
@@ -46,8 +73,8 @@ public class WxMpServiceImpl implements WxMpService { | |||
*/ | |||
private final Object globalJsapiTicketRefreshLock = new Object(); | |||
private WxMpConfigStorage wxMpConfigStorage; | |||
private WxMpConfigStorage configStorage; | |||
private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); | |||
private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); | |||
@@ -58,6 +85,8 @@ public class WxMpServiceImpl implements WxMpService { | |||
private WxMpGroupService groupService = new WxMpGroupServiceImpl(this); | |||
private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this); | |||
private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); | |||
private WxMpCardService cardService = new WxMpCardServiceImpl(this); | |||
@@ -66,6 +95,8 @@ public class WxMpServiceImpl implements WxMpService { | |||
private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); | |||
private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); | |||
private CloseableHttpClient httpClient; | |||
private HttpHost httpProxy; | |||
@@ -79,7 +110,8 @@ public class WxMpServiceImpl implements WxMpService { | |||
@Override | |||
public boolean checkSignature(String timestamp, String nonce, String signature) { | |||
try { | |||
return SHA1.gen(this.wxMpConfigStorage.getToken(), timestamp, nonce).equals(signature); | |||
return SHA1.gen(this.configStorage.getToken(), timestamp, nonce) | |||
.equals(signature); | |||
} catch (Exception e) { | |||
return false; | |||
} | |||
@@ -93,14 +125,14 @@ public class WxMpServiceImpl implements WxMpService { | |||
@Override | |||
public String getAccessToken(boolean forceRefresh) throws WxErrorException { | |||
if (forceRefresh) { | |||
this.wxMpConfigStorage.expireAccessToken(); | |||
this.configStorage.expireAccessToken(); | |||
} | |||
if (this.wxMpConfigStorage.isAccessTokenExpired()) { | |||
if (this.configStorage.isAccessTokenExpired()) { | |||
synchronized (this.globalAccessTokenRefreshLock) { | |||
if (this.wxMpConfigStorage.isAccessTokenExpired()) { | |||
if (this.configStorage.isAccessTokenExpired()) { | |||
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + | |||
"&appid=" + this.wxMpConfigStorage.getAppId() + | |||
"&secret=" + this.wxMpConfigStorage.getSecret(); | |||
"&appid=" + this.configStorage.getAppId() + "&secret=" | |||
+ this.configStorage.getSecret(); | |||
try { | |||
HttpGet httpGet = new HttpGet(url); | |||
if (this.httpProxy != null) { | |||
@@ -114,7 +146,8 @@ public class WxMpServiceImpl implements WxMpService { | |||
throw new WxErrorException(error); | |||
} | |||
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | |||
this.wxMpConfigStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
this.configStorage.updateAccessToken(accessToken.getAccessToken(), | |||
accessToken.getExpiresIn()); | |||
}finally { | |||
httpGet.releaseConnection(); | |||
} | |||
@@ -124,7 +157,7 @@ public class WxMpServiceImpl implements WxMpService { | |||
} | |||
} | |||
} | |||
return this.wxMpConfigStorage.getAccessToken(); | |||
return this.configStorage.getAccessToken(); | |||
} | |||
@Override | |||
@@ -135,23 +168,23 @@ public class WxMpServiceImpl implements WxMpService { | |||
@Override | |||
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { | |||
if (forceRefresh) { | |||
this.wxMpConfigStorage.expireJsapiTicket(); | |||
this.configStorage.expireJsapiTicket(); | |||
} | |||
if (this.wxMpConfigStorage.isJsapiTicketExpired()) { | |||
if (this.configStorage.isJsapiTicketExpired()) { | |||
synchronized (this.globalJsapiTicketRefreshLock) { | |||
if (this.wxMpConfigStorage.isJsapiTicketExpired()) { | |||
if (this.configStorage.isJsapiTicketExpired()) { | |||
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi"; | |||
String responseContent = execute(new SimpleGetRequestExecutor(), url, null); | |||
JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); | |||
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); | |||
String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); | |||
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); | |||
this.wxMpConfigStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds); | |||
this.configStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds); | |||
} | |||
} | |||
} | |||
return this.wxMpConfigStorage.getJsapiTicket(); | |||
return this.configStorage.getJsapiTicket(); | |||
} | |||
@Override | |||
@@ -159,29 +192,15 @@ public class WxMpServiceImpl implements WxMpService { | |||
long timestamp = System.currentTimeMillis() / 1000; | |||
String noncestr = RandomUtils.getRandomStr(); | |||
String jsapiTicket = getJsapiTicket(false); | |||
try { | |||
String signature = SHA1.genWithAmple( | |||
"jsapi_ticket=" + jsapiTicket, | |||
"noncestr=" + noncestr, | |||
"timestamp=" + timestamp, | |||
"url=" + url | |||
); | |||
WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | |||
jsapiSignature.setAppid(this.wxMpConfigStorage.getAppId()); | |||
jsapiSignature.setTimestamp(timestamp); | |||
jsapiSignature.setNoncestr(noncestr); | |||
jsapiSignature.setUrl(url); | |||
jsapiSignature.setSignature(signature); | |||
return jsapiSignature; | |||
} catch (NoSuchAlgorithmException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
@Override | |||
public void customMessageSend(WxMpCustomMessage message) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send"; | |||
execute(new SimplePostRequestExecutor(), url, message.toJson()); | |||
String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, | |||
"noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); | |||
WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | |||
jsapiSignature.setAppid(this.configStorage.getAppId()); | |||
jsapiSignature.setTimestamp(timestamp); | |||
jsapiSignature.setNoncestr(noncestr); | |||
jsapiSignature.setUrl(url); | |||
jsapiSignature.setSignature(signature); | |||
return jsapiSignature; | |||
} | |||
@Override | |||
@@ -271,13 +290,30 @@ public class WxMpServiceImpl implements WxMpService { | |||
public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) { | |||
StringBuilder url = new StringBuilder(); | |||
url.append("https://open.weixin.qq.com/connect/oauth2/authorize?"); | |||
url.append("appid=").append(this.wxMpConfigStorage.getAppId()); | |||
url.append("appid=").append(this.configStorage.getAppId()); | |||
url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI)); | |||
url.append("&response_type=code"); | |||
url.append("&scope=").append(scope); | |||
if (state != null) { | |||
url.append("&state=").append(state); | |||
} | |||
url.append("#wechat_redirect"); | |||
return url.toString(); | |||
} | |||
@Override | |||
public String buildQrConnectUrl(String redirectURI, String scope, | |||
String state) { | |||
StringBuilder url = new StringBuilder(); | |||
url.append("https://open.weixin.qq.com/connect/qrconnect?"); | |||
url.append("appid=").append(this.configStorage.getAppId()); | |||
url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI)); | |||
url.append("&response_type=code"); | |||
url.append("&scope=").append(scope); | |||
if (state != null) { | |||
url.append("&state=").append(state); | |||
} | |||
url.append("#wechat_redirect"); | |||
return url.toString(); | |||
} | |||
@@ -296,8 +332,8 @@ public class WxMpServiceImpl implements WxMpService { | |||
public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException { | |||
StringBuilder url = new StringBuilder(); | |||
url.append("https://api.weixin.qq.com/sns/oauth2/access_token?"); | |||
url.append("appid=").append(this.wxMpConfigStorage.getAppId()); | |||
url.append("&secret=").append(this.wxMpConfigStorage.getSecret()); | |||
url.append("appid=").append(this.configStorage.getAppId()); | |||
url.append("&secret=").append(this.configStorage.getSecret()); | |||
url.append("&code=").append(code); | |||
url.append("&grant_type=authorization_code"); | |||
@@ -308,7 +344,7 @@ public class WxMpServiceImpl implements WxMpService { | |||
public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException { | |||
StringBuilder url = new StringBuilder(); | |||
url.append("https://api.weixin.qq.com/sns/oauth2/refresh_token?"); | |||
url.append("appid=").append(this.wxMpConfigStorage.getAppId()); | |||
url.append("appid=").append(this.configStorage.getAppId()); | |||
url.append("&grant_type=refresh_token"); | |||
url.append("&refresh_token=").append(refreshToken); | |||
@@ -428,7 +464,7 @@ public class WxMpServiceImpl implements WxMpService { | |||
*/ | |||
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { | |||
// 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | |||
this.wxMpConfigStorage.expireAccessToken(); | |||
this.configStorage.expireAccessToken(); | |||
return execute(executor, uri, data); | |||
} | |||
if (error.getErrorCode() != 0) { | |||
@@ -439,7 +475,7 @@ public class WxMpServiceImpl implements WxMpService { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
public HttpHost getHttpProxy() { | |||
return this.httpProxy; | |||
} | |||
@@ -450,33 +486,39 @@ public class WxMpServiceImpl implements WxMpService { | |||
@Override | |||
public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { | |||
this.wxMpConfigStorage = wxConfigProvider; | |||
this.configStorage = wxConfigProvider; | |||
this.initHttpClient(); | |||
} | |||
private void initHttpClient() { | |||
ApacheHttpClientBuilder apacheHttpClientBuilder = this.wxMpConfigStorage.getApacheHttpClientBuilder(); | |||
ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage | |||
.getApacheHttpClientBuilder(); | |||
if (null == apacheHttpClientBuilder) { | |||
apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); | |||
} | |||
apacheHttpClientBuilder.httpProxyHost(this.wxMpConfigStorage.getHttpProxyHost()) | |||
.httpProxyPort(this.wxMpConfigStorage.getHttpProxyPort()) | |||
.httpProxyUsername(this.wxMpConfigStorage.getHttpProxyUsername()) | |||
.httpProxyPassword(this.wxMpConfigStorage.getHttpProxyPassword()); | |||
if (this.wxMpConfigStorage.getSSLContext() != null){ | |||
apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) | |||
.httpProxyPort(this.configStorage.getHttpProxyPort()) | |||
.httpProxyUsername(this.configStorage.getHttpProxyUsername()) | |||
.httpProxyPassword(this.configStorage.getHttpProxyPassword()); | |||
if (this.configStorage.getSSLContext() != null) { | |||
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( | |||
this.wxMpConfigStorage.getSSLContext(), new String[] { "TLSv1" }, null, new DefaultHostnameVerifier()); | |||
this.configStorage.getSSLContext(), new String[] { "TLSv1" }, null, | |||
new DefaultHostnameVerifier()); | |||
apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf); | |||
} | |||
if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { | |||
this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); | |||
} | |||
this.httpClient = apacheHttpClientBuilder.build(); | |||
} | |||
@Override | |||
public WxMpConfigStorage getWxMpConfigStorage() { | |||
return this.wxMpConfigStorage; | |||
return this.configStorage; | |||
} | |||
@Override | |||
@@ -514,6 +556,11 @@ public class WxMpServiceImpl implements WxMpService { | |||
return this.groupService; | |||
} | |||
@Override | |||
public WxMpUserTagService getUserTagService() { | |||
return this.tagService; | |||
} | |||
@Override | |||
public WxMpQrcodeService getQrcodeService() { | |||
return this.qrCodeService; | |||
@@ -534,4 +581,9 @@ public class WxMpServiceImpl implements WxMpService { | |||
return this.dataCubeService; | |||
} | |||
@Override | |||
public WxMpUserBlacklistService getBlackListService() { | |||
return this.blackListService; | |||
} | |||
} |
@@ -0,0 +1,50 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import com.google.gson.Gson; | |||
import com.google.gson.JsonObject; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.api.WxMpUserBlacklistService; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
/** | |||
* @author miller | |||
*/ | |||
public class WxMpUserBlacklistServiceImpl implements WxMpUserBlacklistService { | |||
private static final String API_BLACKLIST_PREFIX = "https://api.weixin.qq.com/cgi-bin/tags/members"; | |||
private WxMpService wxMpService; | |||
public WxMpUserBlacklistServiceImpl(WxMpService wxMpService) { | |||
this.wxMpService = wxMpService; | |||
} | |||
@Override | |||
public WxMpUserBlacklistGetResult getBlacklist(String nextOpenid) throws WxErrorException { | |||
JsonObject jsonObject = new JsonObject(); | |||
jsonObject.addProperty("begin_openid", nextOpenid); | |||
String url = API_BLACKLIST_PREFIX + "/getblacklist"; | |||
String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, jsonObject.toString()); | |||
return WxMpUserBlacklistGetResult.fromJson(responseContent); | |||
} | |||
@Override | |||
public void pushToBlacklist(List<String> openidList) throws WxErrorException { | |||
Map<String, Object> map = new HashMap<>(); | |||
map.put("openid_list", openidList); | |||
String url = API_BLACKLIST_PREFIX + "/batchblacklist"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, new Gson().toJson(map)); | |||
} | |||
@Override | |||
public void pullFromBlacklist(List<String> openidList) throws WxErrorException { | |||
Map<String, Object> map = new HashMap<>(); | |||
map.put("openid_list", openidList); | |||
String url = API_BLACKLIST_PREFIX + "/batchunblacklist"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, new Gson().toJson(map)); | |||
} | |||
} |
@@ -0,0 +1,95 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import java.util.List; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.google.gson.JsonObject; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.api.WxMpUserTagService; | |||
import me.chanjar.weixin.mp.bean.tag.WxUserTag; | |||
/** | |||
* | |||
* @author binarywang(https://github.com/binarywang) | |||
* Created by Binary Wang on 2016/9/2. | |||
*/ | |||
public class WxMpUserTagServiceImpl implements WxMpUserTagService { | |||
protected final Logger log = LoggerFactory | |||
.getLogger(WxMpDataCubeServiceImpl.class); | |||
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/tags"; | |||
private WxMpService wxMpService; | |||
public WxMpUserTagServiceImpl(WxMpService wxMpService) { | |||
this.wxMpService = wxMpService; | |||
} | |||
@Override | |||
public WxUserTag tagCreate(String name) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/create"; | |||
JsonObject json = new JsonObject(); | |||
JsonObject tagJson = new JsonObject(); | |||
tagJson.addProperty("name", name); | |||
json.add("tag", tagJson); | |||
String responseContent = this.wxMpService.post(url, json.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, json.toString(), | |||
responseContent); | |||
return WxUserTag.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<WxUserTag> tagGet() throws WxErrorException { | |||
String url = API_URL_PREFIX + "/get"; | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, "[empty]", | |||
responseContent); | |||
return WxUserTag.listFromJson(responseContent); | |||
} | |||
@Override | |||
public Boolean tagUpdate(Integer id, String name) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/update"; | |||
JsonObject json = new JsonObject(); | |||
JsonObject tagJson = new JsonObject(); | |||
tagJson.addProperty("id", id); | |||
tagJson.addProperty("name", name); | |||
json.add("tag", tagJson); | |||
String responseContent = this.wxMpService.post(url, json.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, json.toString(), responseContent); | |||
WxError wxError = WxError.fromJson(responseContent); | |||
if (wxError.getErrorCode() == 0) { | |||
return true; | |||
} | |||
throw new WxErrorException(wxError); | |||
} | |||
@Override | |||
public Boolean tagDelete(Integer id) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/delete"; | |||
JsonObject json = new JsonObject(); | |||
JsonObject tagJson = new JsonObject(); | |||
tagJson.addProperty("id", id); | |||
json.add("tag", tagJson); | |||
String responseContent = this.wxMpService.post(url, json.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, json.toString(), | |||
responseContent); | |||
WxError wxError = WxError.fromJson(responseContent); | |||
if (wxError.getErrorCode() == 0) { | |||
return true; | |||
} | |||
throw new WxErrorException(wxError); | |||
} | |||
} |
@@ -6,8 +6,6 @@ import java.io.Serializable; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; | |||
import me.chanjar.weixin.mp.util.json.WxLongTimeJsonSerializer; | |||
import org.apache.commons.io.IOUtils; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
@@ -49,7 +47,6 @@ public class WxMpXmlMessage implements Serializable { | |||
private String fromUserName; | |||
@XStreamAlias("CreateTime") | |||
@JsonSerialize(using = WxLongTimeJsonSerializer.class) | |||
private Long createTime; | |||
@XStreamAlias("MsgType") | |||
@@ -1,6 +1,12 @@ | |||
package me.chanjar.weixin.mp.bean.datacube; | |||
import java.util.List; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.annotations.SerializedName; | |||
import com.google.gson.reflect.TypeToken; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* 图文分析数据接口返回结果对象 | |||
@@ -9,6 +15,8 @@ import com.google.gson.annotations.SerializedName; | |||
*/ | |||
public class WxDataCubeArticleResult extends WxDataCubeBaseResult { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
/** | |||
* ref_hour | |||
* 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 | |||
@@ -203,5 +211,11 @@ public class WxDataCubeArticleResult extends WxDataCubeBaseResult { | |||
public void setUserSource(Integer userSource) { | |||
this.userSource = userSource; | |||
} | |||
public static List<WxDataCubeArticleResult> fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson( | |||
JSON_PARSER.parse(json).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeArticleResult>>() { | |||
}.getType()); | |||
} | |||
} |
@@ -1,8 +1,12 @@ | |||
package me.chanjar.weixin.mp.bean.datacube; | |||
import java.util.List; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.annotations.SerializedName; | |||
import com.google.gson.reflect.TypeToken; | |||
import java.util.List; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* 图文分析数据接口返回结果对象 | |||
@@ -11,6 +15,8 @@ import java.util.List; | |||
*/ | |||
public class WxDataCubeArticleTotal extends WxDataCubeBaseResult { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
/** | |||
* msgid | |||
* 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id)和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index,假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 | |||
@@ -55,5 +61,11 @@ public class WxDataCubeArticleTotal extends WxDataCubeBaseResult { | |||
public void setDetails(List<WxDataCubeArticleTotalDetail> details) { | |||
this.details = details; | |||
} | |||
public static List<WxDataCubeArticleTotal> fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson( | |||
JSON_PARSER.parse(json).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeArticleTotal>>() { | |||
}.getType()); | |||
} | |||
} |
@@ -1,6 +1,12 @@ | |||
package me.chanjar.weixin.mp.bean.datacube; | |||
import java.util.List; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.annotations.SerializedName; | |||
import com.google.gson.reflect.TypeToken; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* 接口分析数据接口返回结果对象 | |||
@@ -9,6 +15,8 @@ import com.google.gson.annotations.SerializedName; | |||
*/ | |||
public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
/** | |||
* ref_hour | |||
* 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 | |||
@@ -83,5 +91,12 @@ public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult { | |||
public void setMaxTimeCost(Integer maxTimeCost) { | |||
this.maxTimeCost = maxTimeCost; | |||
} | |||
public static List<WxDataCubeInterfaceResult> fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson( | |||
JSON_PARSER.parse(json).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeInterfaceResult>>() { | |||
}.getType()); | |||
} | |||
} |
@@ -1,6 +1,12 @@ | |||
package me.chanjar.weixin.mp.bean.datacube; | |||
import java.util.List; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.annotations.SerializedName; | |||
import com.google.gson.reflect.TypeToken; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* 消息分析数据接口返回结果对象 | |||
@@ -9,6 +15,8 @@ import com.google.gson.annotations.SerializedName; | |||
*/ | |||
public class WxDataCubeMsgResult extends WxDataCubeBaseResult { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
/** | |||
* ref_hour | |||
* 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 | |||
@@ -114,4 +122,11 @@ public class WxDataCubeMsgResult extends WxDataCubeBaseResult { | |||
this.oriPageReadUser = oriPageReadUser; | |||
} | |||
public static List<WxDataCubeMsgResult> fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson( | |||
JSON_PARSER.parse(json).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeMsgResult>>() { | |||
}.getType()); | |||
} | |||
} |
@@ -1,19 +1,27 @@ | |||
package me.chanjar.weixin.mp.bean.datacube; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
import java.util.List; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.reflect.TypeToken; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* <pre> | |||
* 累计用户数据接口的返回JSON数据包 | |||
* http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html | |||
* 详情查看文档:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141082&token=&lang=zh_CN">用户分析数据接口</a> | |||
* </pre> | |||
*/ | |||
public class WxDataCubeUserCumulate implements Serializable { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
private static final long serialVersionUID = -3570981300225093657L; | |||
private Date refDate; | |||
@@ -40,4 +48,11 @@ public class WxDataCubeUserCumulate implements Serializable { | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public static List<WxDataCubeUserCumulate> fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson( | |||
JSON_PARSER.parse(json).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeUserCumulate>>() { | |||
}.getType()); | |||
} | |||
} |
@@ -1,20 +1,28 @@ | |||
package me.chanjar.weixin.mp.bean.datacube; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
import java.util.List; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.reflect.TypeToken; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* <pre> | |||
* 用户增减数据接口的返回JSON数据包 | |||
* http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html | |||
* 详情查看文档:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141082&token=&lang=zh_CN">用户分析数据接口</a> | |||
* </pre> | |||
*/ | |||
public class WxDataCubeUserSummary implements Serializable { | |||
private static final long serialVersionUID = -2336654489906694173L; | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
private Date refDate; | |||
private Integer userSource; | |||
@@ -59,4 +67,11 @@ public class WxDataCubeUserSummary implements Serializable { | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public static List<WxDataCubeUserSummary> fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson( | |||
JSON_PARSER.parse(json).getAsJsonObject().get("list"), | |||
new TypeToken<List<WxDataCubeUserSummary>>() { | |||
}.getType()); | |||
} | |||
} |
@@ -1,11 +1,10 @@ | |||
package me.chanjar.weixin.mp.bean.kefu.result; | |||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; | |||
import com.google.gson.annotations.SerializedName; | |||
import me.chanjar.weixin.mp.util.json.WxLongTimeJsonSerializer; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.SerializedName; | |||
/** | |||
* Created by Binary Wang on 2016/7/18. | |||
*/ | |||
@@ -38,7 +37,6 @@ public class WxMpKfMsgRecord { | |||
* time 操作时间,unix时间戳 | |||
*/ | |||
@SerializedName("time") | |||
@JsonSerialize(using = WxLongTimeJsonSerializer.class) | |||
private Long time; | |||
@Override | |||
@@ -0,0 +1,57 @@ | |||
package me.chanjar.weixin.mp.bean.result; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
/** | |||
* @author miller | |||
*/ | |||
public class WxMpUserBlacklistGetResult { | |||
protected int total = -1; | |||
protected int count = -1; | |||
protected List<String> openidList = new ArrayList<>(); | |||
protected String nextOpenid; | |||
public static WxMpUserBlacklistGetResult fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUserBlacklistGetResult.class); | |||
} | |||
public int getTotal() { | |||
return this.total; | |||
} | |||
public void setTotal(int total) { | |||
this.total = total; | |||
} | |||
public int getCount() { | |||
return this.count; | |||
} | |||
public void setCount(int count) { | |||
this.count = count; | |||
} | |||
public List<String> getOpenidList() { | |||
return this.openidList; | |||
} | |||
public void setOpenidList(List<String> openidList) { | |||
this.openidList = openidList; | |||
} | |||
public String getNextOpenid() { | |||
return this.nextOpenid; | |||
} | |||
public void setNextOpenid(String nextOpenid) { | |||
this.nextOpenid = nextOpenid; | |||
} | |||
@Override | |||
public String toString() { | |||
return WxMpGsonBuilder.INSTANCE.create().toJson(this); | |||
} | |||
} |
@@ -0,0 +1,78 @@ | |||
package me.chanjar.weixin.mp.bean.tag; | |||
import java.util.List; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.reflect.TypeToken; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* 用户标签对象 | |||
* @author binarywang(https://github.com/binarywang) | |||
* Created by Binary Wang on 2016/9/2. | |||
*/ | |||
public class WxUserTag { | |||
/** | |||
* id 标签id,由微信分配 | |||
*/ | |||
private Integer id; | |||
/** | |||
* name 标签名,UTF8编码 | |||
*/ | |||
private String name; | |||
/** | |||
* count 此标签下粉丝数 | |||
*/ | |||
private Integer count; | |||
public String getName() { | |||
return this.name; | |||
} | |||
public void setName(String name) { | |||
this.name = name; | |||
} | |||
public Integer getCount() { | |||
return this.count; | |||
} | |||
public void setCount(Integer count) { | |||
this.count = count; | |||
} | |||
public Integer getId() { | |||
return this.id; | |||
} | |||
public void setId(Integer id) { | |||
this.id = id; | |||
} | |||
public static WxUserTag fromJson(String json) { | |||
return WxMpGsonBuilder.create().fromJson( | |||
new JsonParser().parse(json).getAsJsonObject().get("tag"), | |||
WxUserTag.class); | |||
} | |||
public static List<WxUserTag> listFromJson(String json) { | |||
return WxMpGsonBuilder.create().fromJson( | |||
new JsonParser().parse(json).getAsJsonObject().get("tags"), | |||
new TypeToken<List<WxUserTag>>(){}.getType()); | |||
} | |||
public String toJson() { | |||
return WxMpGsonBuilder.create().toJson(this); | |||
} | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
} |
@@ -1,23 +0,0 @@ | |||
package me.chanjar.weixin.mp.util.json; | |||
import java.io.IOException; | |||
import java.text.SimpleDateFormat; | |||
import com.fasterxml.jackson.core.JsonGenerator; | |||
import com.fasterxml.jackson.databind.JsonSerializer; | |||
import com.fasterxml.jackson.databind.SerializerProvider; | |||
/** | |||
* Created by Binary Wang on 2016/7/13. | |||
*/ | |||
public class WxLongTimeJsonSerializer extends JsonSerializer<Long> { | |||
private static SimpleDateFormat DF = new SimpleDateFormat( | |||
"yyyy-MM-dd HH:mm:ss"); | |||
@Override | |||
public void serialize(Long value, JsonGenerator gen, | |||
SerializerProvider serializers) | |||
throws IOException { | |||
gen.writeString(DF.format(value * 1000)); | |||
} | |||
} |
@@ -45,6 +45,7 @@ public class WxMpGsonBuilder { | |||
INSTANCE.registerTypeAdapter(WxMpMassPreviewMessage.class, new WxMpMassPreviewMessageGsonAdapter()); | |||
INSTANCE.registerTypeAdapter(WxMediaImgUploadResult.class, new WxMediaImgUploadResultGsonAdapter()); | |||
INSTANCE.registerTypeAdapter(WxMpIndustry.class, new WxMpIndustryGsonAdapter()); | |||
INSTANCE.registerTypeAdapter(WxMpUserBlacklistGetResult.class, new WxUserBlacklistGetResultGsonAdapter()); | |||
} | |||
public static Gson create() { | |||
@@ -1,5 +1,7 @@ | |||
package me.chanjar.weixin.mp.util.json; | |||
import java.lang.reflect.Type; | |||
import com.google.gson.JsonDeserializationContext; | |||
import com.google.gson.JsonDeserializer; | |||
import com.google.gson.JsonElement; | |||
@@ -7,38 +9,43 @@ import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParseException; | |||
import com.google.gson.JsonSerializationContext; | |||
import com.google.gson.JsonSerializer; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.mp.bean.Industry; | |||
import me.chanjar.weixin.mp.bean.WxMpIndustry; | |||
import java.lang.reflect.Type; | |||
/** | |||
* @author miller | |||
*/ | |||
public class WxMpIndustryGsonAdapter implements JsonSerializer<WxMpIndustry>, JsonDeserializer<WxMpIndustry> { | |||
@Override | |||
public JsonElement serialize(WxMpIndustry wxMpIndustry, Type type, JsonSerializationContext jsonSerializationContext) { | |||
JsonObject json = new JsonObject(); | |||
json.addProperty("industry_id1", wxMpIndustry.getPrimaryIndustry().getId()); | |||
json.addProperty("industry_id2", wxMpIndustry.getSecondIndustry().getId()); | |||
return json; | |||
} | |||
public class WxMpIndustryGsonAdapter | |||
implements JsonSerializer<WxMpIndustry>, JsonDeserializer<WxMpIndustry> { | |||
@Override | |||
public JsonElement serialize(WxMpIndustry wxMpIndustry, Type type, | |||
JsonSerializationContext jsonSerializationContext) { | |||
JsonObject json = new JsonObject(); | |||
json.addProperty("industry_id1", wxMpIndustry.getPrimaryIndustry().getId()); | |||
json.addProperty("industry_id2", wxMpIndustry.getSecondIndustry().getId()); | |||
return json; | |||
} | |||
@Override | |||
public WxMpIndustry deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { | |||
WxMpIndustry wxMpIndustry = new WxMpIndustry(); | |||
JsonObject primaryIndustry = jsonElement.getAsJsonObject().get("primary_industry").getAsJsonObject(); | |||
wxMpIndustry.setPrimaryIndustry(convertFromJson(primaryIndustry)); | |||
JsonObject secondaryIndustry = jsonElement.getAsJsonObject().get("secondary_industry").getAsJsonObject(); | |||
wxMpIndustry.setSecondIndustry(convertFromJson(secondaryIndustry)); | |||
return wxMpIndustry; | |||
} | |||
@Override | |||
public WxMpIndustry deserialize(JsonElement jsonElement, Type type, | |||
JsonDeserializationContext jsonDeserializationContext) | |||
throws JsonParseException { | |||
WxMpIndustry wxMpIndustry = new WxMpIndustry(); | |||
JsonObject primaryIndustry = jsonElement.getAsJsonObject() | |||
.get("primary_industry").getAsJsonObject(); | |||
wxMpIndustry.setPrimaryIndustry(convertFromJson(primaryIndustry)); | |||
JsonObject secondaryIndustry = jsonElement.getAsJsonObject() | |||
.get("secondary_industry").getAsJsonObject(); | |||
wxMpIndustry.setSecondIndustry(convertFromJson(secondaryIndustry)); | |||
return wxMpIndustry; | |||
} | |||
private Industry convertFromJson(JsonObject json) { | |||
Industry industry = new Industry(); | |||
industry.setFirstClass(GsonHelper.getString(json, "first_class")); | |||
industry.setSecondClass(GsonHelper.getString(json, "second_class")); | |||
return industry; | |||
} | |||
private static Industry convertFromJson(JsonObject json) { | |||
Industry industry = new Industry(); | |||
industry.setFirstClass(GsonHelper.getString(json, "first_class")); | |||
industry.setSecondClass(GsonHelper.getString(json, "second_class")); | |||
return industry; | |||
} | |||
} |
@@ -8,13 +8,19 @@ | |||
*/ | |||
package me.chanjar.weixin.mp.util.json; | |||
import com.google.gson.*; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; | |||
import java.lang.reflect.Type; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import org.apache.commons.lang3.time.FastDateFormat; | |||
import com.google.gson.JsonDeserializationContext; | |||
import com.google.gson.JsonDeserializer; | |||
import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParseException; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; | |||
/** | |||
* | |||
@@ -23,7 +29,8 @@ import java.text.SimpleDateFormat; | |||
*/ | |||
public class WxMpUserCumulateGsonAdapter implements JsonDeserializer<WxDataCubeUserCumulate> { | |||
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); | |||
private static final FastDateFormat DATE_FORMAT = FastDateFormat | |||
.getInstance("yyyy-MM-dd"); | |||
@Override | |||
public WxDataCubeUserCumulate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||
@@ -33,7 +40,7 @@ public class WxMpUserCumulateGsonAdapter implements JsonDeserializer<WxDataCubeU | |||
try { | |||
String refDate = GsonHelper.getString(summaryJsonObject, "ref_date"); | |||
if (refDate != null) { | |||
cumulate.setRefDate(SIMPLE_DATE_FORMAT.parse(refDate)); | |||
cumulate.setRefDate(DATE_FORMAT.parse(refDate)); | |||
} | |||
cumulate.setCumulateUser(GsonHelper.getInteger(summaryJsonObject, "cumulate_user")); | |||
} catch (ParseException e) { | |||
@@ -8,20 +8,27 @@ | |||
*/ | |||
package me.chanjar.weixin.mp.util.json; | |||
import com.google.gson.*; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary; | |||
import java.lang.reflect.Type; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import org.apache.commons.lang3.time.FastDateFormat; | |||
import com.google.gson.JsonDeserializationContext; | |||
import com.google.gson.JsonDeserializer; | |||
import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParseException; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary; | |||
/** | |||
* @author Daniel Qian | |||
*/ | |||
public class WxMpUserSummaryGsonAdapter implements JsonDeserializer<WxDataCubeUserSummary> { | |||
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); | |||
private static final FastDateFormat DATE_FORMAT = FastDateFormat | |||
.getInstance("yyyy-MM-dd"); | |||
@Override | |||
public WxDataCubeUserSummary deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||
@@ -32,7 +39,7 @@ public class WxMpUserSummaryGsonAdapter implements JsonDeserializer<WxDataCubeUs | |||
try { | |||
String refDate = GsonHelper.getString(summaryJsonObject, "ref_date"); | |||
if (refDate != null) { | |||
summary.setRefDate(SIMPLE_DATE_FORMAT.parse(refDate)); | |||
summary.setRefDate(DATE_FORMAT.parse(refDate)); | |||
} | |||
summary.setUserSource(GsonHelper.getInteger(summaryJsonObject, "user_source")); | |||
summary.setNewUser(GsonHelper.getInteger(summaryJsonObject, "new_user")); | |||
@@ -0,0 +1,28 @@ | |||
package me.chanjar.weixin.mp.util.json; | |||
import com.google.gson.*; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult; | |||
import java.lang.reflect.Type; | |||
/** | |||
* @author miller | |||
*/ | |||
public class WxUserBlacklistGetResultGsonAdapter implements JsonDeserializer<WxMpUserBlacklistGetResult> { | |||
@Override | |||
public WxMpUserBlacklistGetResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||
JsonObject o = json.getAsJsonObject(); | |||
WxMpUserBlacklistGetResult wxMpUserBlacklistGetResult = new WxMpUserBlacklistGetResult(); | |||
wxMpUserBlacklistGetResult.setTotal(GsonHelper.getInteger(o, "total")); | |||
wxMpUserBlacklistGetResult.setCount(GsonHelper.getInteger(o, "count")); | |||
wxMpUserBlacklistGetResult.setNextOpenid(GsonHelper.getString(o, "next_openid")); | |||
if (o.get("data") != null && !o.get("data").isJsonNull() && !o.get("data").getAsJsonObject().get("openid").isJsonNull()) { | |||
JsonArray data = o.get("data").getAsJsonObject().get("openid").getAsJsonArray(); | |||
for (int i = 0; i < data.size(); i++) { | |||
wxMpUserBlacklistGetResult.getOpenidList().add(GsonHelper.getAsString(data.get(i))); | |||
} | |||
} | |||
return wxMpUserBlacklistGetResult; | |||
} | |||
} |
@@ -1,16 +1,25 @@ | |||
package me.chanjar.weixin.mp.util.xml; | |||
import com.thoughtworks.xstream.XStream; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.mp.bean.*; | |||
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.mp.bean.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutImageMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutMusicMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutNewsMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutTransferCustomerServiceMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutVideoMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutVoiceMessage; | |||
public class XStreamTransformer { | |||
protected static final Map<Class, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance(); | |||
protected static final Map<Class<?>, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance(); | |||
/** | |||
* xml -> pojo | |||
@@ -32,7 +41,7 @@ public class XStreamTransformer { | |||
* @param clz 类型 | |||
* @param xStream xml解析器 | |||
*/ | |||
public static void register(Class clz,XStream xStream){ | |||
public static void register(Class<?> clz, XStream xStream) { | |||
CLASS_2_XSTREAM_INSTANCE.put(clz,xStream); | |||
} | |||
@@ -44,8 +53,8 @@ public class XStreamTransformer { | |||
return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); | |||
} | |||
private static Map<Class, XStream> configXStreamInstance() { | |||
Map<Class, XStream> map = new HashMap<>(); | |||
private static Map<Class<?>, XStream> configXStreamInstance() { | |||
Map<Class<?>, XStream> map = new HashMap<>(); | |||
map.put(WxMpXmlMessage.class, config_WxMpXmlMessage()); | |||
map.put(WxMpXmlOutMusicMessage.class, config_WxMpXmlOutMusicMessage()); | |||
map.put(WxMpXmlOutNewsMessage.class, config_WxMpXmlOutNewsMessage()); | |||
@@ -31,6 +31,7 @@ public class ApiTestModule implements Module { | |||
} | |||
} | |||
@SuppressWarnings("unchecked") | |||
public static <T> T fromXml(Class<T> clazz, InputStream is) { | |||
XStream xstream = XStreamInitializer.getInstance(); | |||
xstream.alias("xml", clazz); | |||
@@ -42,15 +43,16 @@ public class ApiTestModule implements Module { | |||
public static class WxXmlMpInMemoryConfigStorage | |||
extends WxMpInMemoryConfigStorage { | |||
private String openId; | |||
private String openid; | |||
private String kfAccount; | |||
private String qrconnectRedirectUrl; | |||
public String getOpenId() { | |||
return this.openId; | |||
public String getOpenid() { | |||
return this.openid; | |||
} | |||
public void setOpenId(String openId) { | |||
this.openId = openId; | |||
public void setOpenid(String openid) { | |||
this.openid = openid; | |||
} | |||
@Override | |||
@@ -66,6 +68,14 @@ public class ApiTestModule implements Module { | |||
this.kfAccount = kfAccount; | |||
} | |||
public String getQrconnectRedirectUrl() { | |||
return this.qrconnectRedirectUrl; | |||
} | |||
public void setQrconnectRedirectUrl(String qrconnectRedirectUrl) { | |||
this.qrconnectRedirectUrl = qrconnectRedirectUrl; | |||
} | |||
} | |||
} |
@@ -1,17 +1,18 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
import org.testng.annotations.DataProvider; | |||
import org.testng.annotations.Test; | |||
import java.util.concurrent.ExecutionException; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
import java.util.concurrent.Future; | |||
import org.testng.annotations.DataProvider; | |||
import org.testng.annotations.Test; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
@Test | |||
public class WxMpBusyRetryTest { | |||
@@ -20,7 +21,9 @@ public class WxMpBusyRetryTest { | |||
WxMpService service = new WxMpServiceImpl() { | |||
@Override | |||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||
protected synchronized <T, E> T executeInternal( | |||
RequestExecutor<T, E> executor, String uri, E data) | |||
throws WxErrorException { | |||
WxError error = new WxError(); | |||
error.setErrorCode(-1); | |||
throw new WxErrorException(error); | |||
@@ -1,44 +0,0 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
/*** | |||
* 测试发送客服消息 | |||
* @author chanjarster | |||
* | |||
*/ | |||
@Test(groups="customMessageAPI") | |||
@Guice(modules = ApiTestModule.class) | |||
public class WxMpCustomMessageAPITest { | |||
@Inject | |||
protected WxMpServiceImpl wxService; | |||
public void testSendCustomMessage() throws WxErrorException { | |||
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage(); | |||
WxMpCustomMessage message = new WxMpCustomMessage(); | |||
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||
message.setToUser(configStorage.getOpenId()); | |||
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
this.wxService.customMessageSend(message); | |||
} | |||
public void testSendCustomMessageWithKfAccount() throws WxErrorException { | |||
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage(); | |||
WxMpCustomMessage message = new WxMpCustomMessage(); | |||
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||
message.setToUser(configStorage.getOpenId()); | |||
message.setKfAccount(configStorage.getKfAccount()); | |||
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
this.wxService.customMessageSend(message); | |||
} | |||
} |
@@ -1,14 +1,14 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
import org.testng.Assert; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
import java.security.NoSuchAlgorithmException; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
/** | |||
* 测试jsapi ticket接口 | |||
@@ -29,7 +29,7 @@ public class WxMpJsAPITest { | |||
Assert.assertNotNull(jsapiTicket); | |||
} | |||
public void test() throws NoSuchAlgorithmException { | |||
public void test() { | |||
long timestamp = 1419835025l; | |||
String url = "http://omstest.vmall.com:23568/thirdparty/wechat/vcode/gotoshare?quantity=1&batchName=MATE7"; | |||
String noncestr = "82693e11-b9bc-448e-892f-f5289f46cd0f"; | |||
@@ -41,7 +41,7 @@ public class WxMpMassMessageAPITest { | |||
WxMpMassOpenIdsMessage massMessage = new WxMpMassOpenIdsMessage(); | |||
massMessage.setMsgType(WxConsts.MASS_MSG_TEXT); | |||
massMessage.setContent("测试群发消息\n欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
massMessage.getToUsers().add(configProvider.getOpenId()); | |||
massMessage.getToUsers().add(configProvider.getOpenid()); | |||
WxMpMassSendResult massResult = this.wxService | |||
.massOpenIdsMessageSend(massMessage); | |||
@@ -58,7 +58,7 @@ public class WxMpMassMessageAPITest { | |||
WxMpMassOpenIdsMessage massMessage = new WxMpMassOpenIdsMessage(); | |||
massMessage.setMsgType(massMsgType); | |||
massMessage.setMediaId(mediaId); | |||
massMessage.getToUsers().add(configProvider.getOpenId()); | |||
massMessage.getToUsers().add(configProvider.getOpenid()); | |||
WxMpMassSendResult massResult = this.wxService | |||
.massOpenIdsMessageSend(massMessage); | |||
@@ -73,13 +73,13 @@ public class WxMpMassMessageAPITest { | |||
massMessage.setContent("测试群发消息\n欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
massMessage | |||
.setGroupId(this.wxService.getGroupService().groupGet().get(0).getId()); | |||
WxMpMassSendResult massResult = this.wxService | |||
.massGroupMessageSend(massMessage); | |||
Assert.assertNotNull(massResult); | |||
Assert.assertNotNull(massResult.getMsgId()); | |||
} | |||
@Test(dataProvider="massMessages") | |||
public void testMediaMassGroupMessageSend(String massMsgType, String mediaId) | |||
throws WxErrorException { | |||
@@ -94,7 +94,7 @@ public class WxMpMassMessageAPITest { | |||
Assert.assertNotNull(massResult); | |||
Assert.assertNotNull(massResult.getMsgId()); | |||
} | |||
@DataProvider | |||
public Object[][] massMessages() throws WxErrorException, IOException { | |||
Object[][] messages = new Object[4][]; | |||
@@ -109,7 +109,7 @@ public class WxMpMassMessageAPITest { | |||
.mediaUpload(WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, inputStream); | |||
Assert.assertNotNull(uploadMediaRes); | |||
Assert.assertNotNull(uploadMediaRes.getMediaId()); | |||
// 把视频变成可被群发的媒体 | |||
WxMpMassVideo video = new WxMpMassVideo(); | |||
video.setTitle("测试标题"); | |||
@@ -155,7 +155,7 @@ public class WxMpMassMessageAPITest { | |||
.mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream); | |||
Assert.assertNotNull(uploadMediaRes); | |||
Assert.assertNotNull(uploadMediaRes.getMediaId()); | |||
// 上传图文消息 | |||
WxMpMassNews news = new WxMpMassNews(); | |||
WxMpMassNews.WxMpMassNewsArticle article1 = new WxMpMassNews.WxMpMassNewsArticle(); | |||
@@ -163,7 +163,7 @@ public class WxMpMassMessageAPITest { | |||
article1.setContent("内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1"); | |||
article1.setThumbMediaId(uploadMediaRes.getMediaId()); | |||
news.addArticle(article1); | |||
WxMpMassNews.WxMpMassNewsArticle article2 = new WxMpMassNews.WxMpMassNewsArticle(); | |||
article2.setTitle("标题2"); | |||
article2.setContent("内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2"); | |||
@@ -173,7 +173,7 @@ public class WxMpMassMessageAPITest { | |||
article2.setContentSourceUrl("www.baidu.com"); | |||
article2.setDigest("摘要2"); | |||
news.addArticle(article2); | |||
WxMpMassUploadResult massUploadResult = this.wxService | |||
.massNewsUpload(news); | |||
Assert.assertNotNull(massUploadResult); | |||
@@ -183,5 +183,5 @@ public class WxMpMassMessageAPITest { | |||
return messages; | |||
} | |||
} |
@@ -1,10 +1,10 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import java.util.List; | |||
import org.apache.commons.lang3.time.FastDateFormat; | |||
import org.testng.Assert; | |||
import org.testng.annotations.DataProvider; | |||
import org.testng.annotations.Guice; | |||
@@ -28,39 +28,39 @@ import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary; | |||
*/ | |||
@Guice(modules = ApiTestModule.class) | |||
public class WxMpDataCubeServiceImplTest { | |||
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat( | |||
"yyyy-MM-dd"); | |||
private FastDateFormat simpleDateFormat = FastDateFormat | |||
.getInstance("yyyy-MM-dd"); | |||
@Inject | |||
protected WxMpServiceImpl wxService; | |||
@DataProvider | |||
public Object[][] oneDay() throws ParseException { | |||
return new Object[][] { { simpleDateFormat.parse("2016-08-22") } }; | |||
return new Object[][] { { this.simpleDateFormat.parse("2016-08-22") } }; | |||
} | |||
@DataProvider | |||
public Object[][] threeDays() throws ParseException { | |||
return new Object[][] { { simpleDateFormat.parse("2016-08-20"), | |||
simpleDateFormat.parse("2016-08-22") } }; | |||
return new Object[][] { { this.simpleDateFormat.parse("2016-08-20"), | |||
this.simpleDateFormat.parse("2016-08-22") } }; | |||
} | |||
@DataProvider | |||
public Object[][] sevenDays() throws ParseException { | |||
return new Object[][] { { simpleDateFormat.parse("2016-08-16"), | |||
simpleDateFormat.parse("2016-08-22") } }; | |||
return new Object[][] { { this.simpleDateFormat.parse("2016-08-16"), | |||
this.simpleDateFormat.parse("2016-08-22") } }; | |||
} | |||
@DataProvider | |||
public Object[][] fifteenDays() throws ParseException { | |||
return new Object[][] { { simpleDateFormat.parse("2016-08-14"), | |||
simpleDateFormat.parse("2016-08-27") } }; | |||
return new Object[][] { { this.simpleDateFormat.parse("2016-08-14"), | |||
this.simpleDateFormat.parse("2016-08-27") } }; | |||
} | |||
@DataProvider | |||
public Object[][] thirtyDays() throws ParseException { | |||
return new Object[][] { { simpleDateFormat.parse("2016-07-30"), | |||
simpleDateFormat.parse("2016-08-27") } }; | |||
return new Object[][] { { this.simpleDateFormat.parse("2016-07-30"), | |||
this.simpleDateFormat.parse("2016-08-27") } }; | |||
} | |||
@Test(dataProvider = "sevenDays") | |||
@@ -12,9 +12,10 @@ import java.util.List; | |||
/** | |||
* 测试分组接口 | |||
* | |||
* | |||
* @author chanjarster | |||
*/ | |||
@Deprecated | |||
@Test(groups = "groupAPI") | |||
@Guice(modules = ApiTestModule.class) | |||
public class WxMpGroupServiceImplTest { | |||
@@ -23,7 +24,7 @@ public class WxMpGroupServiceImplTest { | |||
protected WxMpServiceImpl wxService; | |||
protected WxMpGroup group; | |||
public void testGroupCreate() throws WxErrorException { | |||
WxMpGroup res = this.wxService.getGroupService().groupCreate("测试分组1"); | |||
Assert.assertEquals(res.getName(), "测试分组1"); | |||
@@ -39,11 +40,22 @@ public class WxMpGroupServiceImplTest { | |||
Assert.assertNotNull(g.getName()); | |||
} | |||
} | |||
@Test(dependsOnMethods={"testGroupGet", "testGroupCreate"}) | |||
public void getGroupUpdate() throws WxErrorException { | |||
this.group.setName("分组改名"); | |||
this.wxService.getGroupService().groupUpdate(this.group); | |||
} | |||
public void testGroupQueryUserGroup() throws WxErrorException { | |||
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage(); | |||
long groupid = this.wxService.getGroupService().userGetGroup(configStorage.getOpenid()); | |||
Assert.assertTrue(groupid != -1l); | |||
} | |||
public void testGroupMoveUser() throws WxErrorException { | |||
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage(); | |||
this.wxService.getGroupService().userUpdateGroup(configStorage.getOpenid(), this.wxService.getGroupService().groupGet().get(3).getId()); | |||
} | |||
} |