Checks if a CharSequence is whitespace, empty ("") or null.
- *- *
- * StringUtils.isBlank(null) = true - * StringUtils.isBlank("") = true - * StringUtils.isBlank(" ") = true - * StringUtils.isBlank("bob") = false - * StringUtils.isBlank(" bob ") = false - *- * - * @param cs the CharSequence to check, may be null - * @return {@code true} if the CharSequence is null, empty or whitespace - * @since 3.0 Changed signature from isBlank(String) to isBlank(CharSequence) - */ - public static boolean isBlank(CharSequence cs) { - int strLen; - if (cs == null || (strLen = cs.length()) == 0) { - return true; - } - for (int i = 0; i < strLen; i++) { - if (Character.isWhitespace(cs.charAt(i)) == false) { - return false; - } - } - return true; - } - - /** - *
Checks if a CharSequence is not empty (""), not null and not whitespace only.
- *- *
- * StringUtils.isNotBlank(null) = false - * StringUtils.isNotBlank("") = false - * StringUtils.isNotBlank(" ") = false - * StringUtils.isNotBlank("bob") = true - * StringUtils.isNotBlank(" bob ") = true - *- * - * @param cs the CharSequence to check, may be null - * @return {@code true} if the CharSequence is - * not empty and not null and not whitespace - * @since 3.0 Changed signature from isNotBlank(String) to isNotBlank(CharSequence) - */ - public static boolean isNotBlank(CharSequence cs) { - return !StringUtils.isBlank(cs); - } - - /** - *
Checks if a CharSequence is empty ("") or null.
- *- *
- * StringUtils.isEmpty(null) = true - * StringUtils.isEmpty("") = true - * StringUtils.isEmpty(" ") = false - * StringUtils.isEmpty("bob") = false - * StringUtils.isEmpty(" bob ") = false - *- *
- *
NOTE: This method changed in Lang version 2.0. - * It no longer trims the CharSequence. - * That functionality is available in isBlank().
- * - * @param cs the CharSequence to check, may be null - * @return {@code true} if the CharSequence is empty or null - * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence) - */ - public static boolean isEmpty(CharSequence cs) { - return cs == null || cs.length() == 0; - } - - /** - *Checks if a CharSequence is not empty ("") and not null.
- *- *
- * StringUtils.isNotEmpty(null) = false - * StringUtils.isNotEmpty("") = false - * StringUtils.isNotEmpty(" ") = true - * StringUtils.isNotEmpty("bob") = true - * StringUtils.isNotEmpty(" bob ") = true - *- * - * @param cs the CharSequence to check, may be null - * @return {@code true} if the CharSequence is not empty and not null - * @since 3.0 Changed signature from isNotEmpty(String) to isNotEmpty(CharSequence) - */ - public static boolean isNotEmpty(CharSequence cs) { - return !StringUtils.isEmpty(cs); - } - -} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/ToStringUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/ToStringUtils.java new file mode 100644 index 00000000..0fa38391 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/ToStringUtils.java @@ -0,0 +1,61 @@ +package me.chanjar.weixin.common.util; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + *
+ * 自定义的ToString方法,用于产生去掉空值属性的字符串 + * Created by Binary Wang on 2016-10-27. + * @author binarywang(Binary Wang) + *+ */ +public class ToStringUtils { + public static final ToStringStyle THE_STYLE = new SimpleMultiLineToStringStyle(); + private static class SimpleMultiLineToStringStyle extends ToStringStyle { + private static final long serialVersionUID = 4645306494220335355L; + private static final String LINE_SEPARATOR = "\n"; + private static final String NULL_TEXT = "
- * 针对org.apache.commons.codec.binary.Base64,
- * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
- * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
- */
-
-// ------------------------------------------------------------------------
-
-/**
- * 针对org.apache.commons.codec.binary.Base64,
- * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
- * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
- */
-package me.chanjar.weixin.common.util.crypto;
-
-import java.io.StringReader;
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.Random;
-
-import javax.crypto.Cipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.commons.codec.binary.Base64;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.InputSource;
-
-public class WxCryptUtil {
-
- private static final Base64 base64 = new Base64();
- private static final Charset CHARSET = Charset.forName("utf-8");
-
- private static final ThreadLocal
+ * 针对org.apache.commons.codec.binary.Base64,
+ * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
+ * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * 针对org.apache.commons.codec.binary.Base64,
+ * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
+ * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
+ */
+package me.chanjar.weixin.common.util.crypto;
+
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Random;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.codec.binary.Base64;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+public class WxCryptUtil {
+
+ private static final Base64 base64 = new Base64();
+ private static final Charset CHARSET = Charset.forName("utf-8");
+
+ private static final ThreadLocal
+ * 设置为零时不超时,一直等待.
+ * 设置为负数是使用系统默认设置(非上述的3000ms的默认值,而是httpclient的默认设置).
+ *
+ * 设置为零时不超时,一直等待.
+ * 设置为负数是使用系统默认设置(非上述的5000ms的默认值,而是httpclient的默认设置).
+ *
+ * 超时的链接将在下一次空闲链接检查是被销毁
+ *
- *
- *
- * @param plainText 公众平台待回复用户的消息,xml格式的字符串
- * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
- */
- public String encrypt(String plainText) {
- // 加密
- String encryptedXml = encrypt(genRandomStr(), plainText);
-
- // 生成安全签名
- String timeStamp = Long.toString(System.currentTimeMillis() / 1000l);
- String nonce = genRandomStr();
-
- String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedXml);
- String result = generateXml(encryptedXml, signature, timeStamp, nonce);
- return result;
- }
-
- /**
- * 对明文进行加密.
- *
- * @param plainText 需要加密的明文
- * @return 加密后base64编码的字符串
- */
- protected String encrypt(String randomStr, String plainText) {
- ByteGroup byteCollector = new ByteGroup();
- byte[] randomStringBytes = randomStr.getBytes(CHARSET);
- byte[] plainTextBytes = plainText.getBytes(CHARSET);
- byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder(
- plainTextBytes.length);
- byte[] appIdBytes = this.appidOrCorpid.getBytes(CHARSET);
-
- // randomStr + networkBytesOrder + text + appid
- byteCollector.addBytes(randomStringBytes);
- byteCollector.addBytes(bytesOfSizeInNetworkOrder);
- byteCollector.addBytes(plainTextBytes);
- byteCollector.addBytes(appIdBytes);
-
- // ... + pad: 使用自定义的填充方式对明文进行补位填充
- byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
- byteCollector.addBytes(padBytes);
-
- // 获得最终的字节流, 未加密
- byte[] unencrypted = byteCollector.toBytes();
-
- try {
- // 设置加密模式为AES的CBC模式
- Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
- SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES");
- IvParameterSpec iv = new IvParameterSpec(this.aesKey, 0, 16);
- cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
-
- // 加密
- byte[] encrypted = cipher.doFinal(unencrypted);
-
- // 使用BASE64对加密后的字符串进行编码
- String base64Encrypted = base64.encodeToString(encrypted);
-
- return base64Encrypted;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * 检验消息的真实性,并且获取解密后的明文.
- *
- *
- *
- * @param msgSignature 签名串,对应URL参数的msg_signature
- * @param timeStamp 时间戳,对应URL参数的timestamp
- * @param nonce 随机串,对应URL参数的nonce
- * @param encryptedXml 密文,对应POST请求的数据
- * @return 解密后的原文
- */
- public String decrypt(String msgSignature, String timeStamp, String nonce,
- String encryptedXml) {
- // 密钥,公众账号的app corpSecret
- // 提取密文
- String cipherText = extractEncryptPart(encryptedXml);
-
- // 验证安全签名
- String signature = SHA1.gen(this.token, timeStamp, nonce, cipherText);
- if (!signature.equals(msgSignature)) {
- throw new RuntimeException("加密消息签名校验失败");
- }
-
- // 解密
- String result = decrypt(cipherText);
- return result;
- }
-
- /**
- * 对密文进行解密.
- *
- * @param cipherText 需要解密的密文
- * @return 解密得到的明文
- */
- public String decrypt(String cipherText) {
- byte[] original;
- try {
- // 设置解密模式为AES的CBC模式
- Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
- SecretKeySpec key_spec = new SecretKeySpec(this.aesKey, "AES");
- IvParameterSpec iv = new IvParameterSpec(
- Arrays.copyOfRange(this.aesKey, 0, 16));
- cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
-
- // 使用BASE64对密文进行解码
- byte[] encrypted = Base64.decodeBase64(cipherText);
-
- // 解密
- original = cipher.doFinal(encrypted);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- String xmlContent, from_appid;
- try {
- // 去除补位字符
- byte[] bytes = PKCS7Encoder.decode(original);
-
- // 分离16位随机字符串,网络字节序和AppId
- byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
-
- int xmlLength = bytesNetworkOrder2Number(networkOrder);
-
- xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength),
- CHARSET);
- from_appid = new String(
- Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- // appid不相同的情况
- if (!from_appid.equals(this.appidOrCorpid)) {
- throw new RuntimeException("AppID不正确");
- }
-
- return xmlContent;
-
- }
-
- /**
- * 将一个数字转换成生成4个字节的网络字节序bytes数组
- *
- * @param number
- */
- private static byte[] number2BytesInNetworkOrder(int number) {
- byte[] orderBytes = new byte[4];
- orderBytes[3] = (byte) (number & 0xFF);
- orderBytes[2] = (byte) (number >> 8 & 0xFF);
- orderBytes[1] = (byte) (number >> 16 & 0xFF);
- orderBytes[0] = (byte) (number >> 24 & 0xFF);
- return orderBytes;
- }
-
- /**
- * 4个字节的网络字节序bytes数组还原成一个数字
- *
- * @param bytesInNetworkOrder
- */
- private static int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) {
- int sourceNumber = 0;
- for (int i = 0; i < 4; i++) {
- sourceNumber <<= 8;
- sourceNumber |= bytesInNetworkOrder[i] & 0xff;
- }
- return sourceNumber;
- }
-
- /**
- * 随机生成16位字符串
- */
- private static String genRandomStr() {
- String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- Random random = new Random();
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < 16; i++) {
- int number = random.nextInt(base.length());
- sb.append(base.charAt(number));
- }
- return sb.toString();
- }
-
- /**
- * 生成xml消息
- *
- * @param encrypt 加密后的消息密文
- * @param signature 安全签名
- * @param timestamp 时间戳
- * @param nonce 随机字符串
- * @return 生成的xml字符串
- */
- private static String generateXml(String encrypt, String signature,
- String timestamp, String nonce) {
- String format = "
+ *
+ *
+ * @param plainText 公众平台待回复用户的消息,xml格式的字符串
+ * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
+ */
+ public String encrypt(String plainText) {
+ // 加密
+ String encryptedXml = encrypt(genRandomStr(), plainText);
+
+ // 生成安全签名
+ String timeStamp = Long.toString(System.currentTimeMillis() / 1000l);
+ String nonce = genRandomStr();
+
+ String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedXml);
+ String result = generateXml(encryptedXml, signature, timeStamp, nonce);
+ return result;
+ }
+
+ /**
+ * 对明文进行加密.
+ *
+ * @param plainText 需要加密的明文
+ * @return 加密后base64编码的字符串
+ */
+ protected String encrypt(String randomStr, String plainText) {
+ ByteGroup byteCollector = new ByteGroup();
+ byte[] randomStringBytes = randomStr.getBytes(CHARSET);
+ byte[] plainTextBytes = plainText.getBytes(CHARSET);
+ byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder(
+ plainTextBytes.length);
+ byte[] appIdBytes = this.appidOrCorpid.getBytes(CHARSET);
+
+ // randomStr + networkBytesOrder + text + appid
+ byteCollector.addBytes(randomStringBytes);
+ byteCollector.addBytes(bytesOfSizeInNetworkOrder);
+ byteCollector.addBytes(plainTextBytes);
+ byteCollector.addBytes(appIdBytes);
+
+ // ... + pad: 使用自定义的填充方式对明文进行补位填充
+ byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
+ byteCollector.addBytes(padBytes);
+
+ // 获得最终的字节流, 未加密
+ byte[] unencrypted = byteCollector.toBytes();
+
+ try {
+ // 设置加密模式为AES的CBC模式
+ Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+ SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES");
+ IvParameterSpec iv = new IvParameterSpec(this.aesKey, 0, 16);
+ cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
+
+ // 加密
+ byte[] encrypted = cipher.doFinal(unencrypted);
+
+ // 使用BASE64对加密后的字符串进行编码
+ String base64Encrypted = base64.encodeToString(encrypted);
+
+ return base64Encrypted;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 检验消息的真实性,并且获取解密后的明文.
+ *
+ *
+ *
+ * @param msgSignature 签名串,对应URL参数的msg_signature
+ * @param timeStamp 时间戳,对应URL参数的timestamp
+ * @param nonce 随机串,对应URL参数的nonce
+ * @param encryptedXml 密文,对应POST请求的数据
+ * @return 解密后的原文
+ */
+ public String decrypt(String msgSignature, String timeStamp, String nonce,
+ String encryptedXml) {
+ // 密钥,公众账号的app corpSecret
+ // 提取密文
+ String cipherText = extractEncryptPart(encryptedXml);
+
+ // 验证安全签名
+ String signature = SHA1.gen(this.token, timeStamp, nonce, cipherText);
+ if (!signature.equals(msgSignature)) {
+ throw new RuntimeException("加密消息签名校验失败");
+ }
+
+ // 解密
+ String result = decrypt(cipherText);
+ return result;
+ }
+
+ /**
+ * 对密文进行解密.
+ *
+ * @param cipherText 需要解密的密文
+ * @return 解密得到的明文
+ */
+ public String decrypt(String cipherText) {
+ byte[] original;
+ try {
+ // 设置解密模式为AES的CBC模式
+ Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+ SecretKeySpec key_spec = new SecretKeySpec(this.aesKey, "AES");
+ IvParameterSpec iv = new IvParameterSpec(
+ Arrays.copyOfRange(this.aesKey, 0, 16));
+ cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
+
+ // 使用BASE64对密文进行解码
+ byte[] encrypted = Base64.decodeBase64(cipherText);
+
+ // 解密
+ original = cipher.doFinal(encrypted);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ String xmlContent, from_appid;
+ try {
+ // 去除补位字符
+ byte[] bytes = PKCS7Encoder.decode(original);
+
+ // 分离16位随机字符串,网络字节序和AppId
+ byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
+
+ int xmlLength = bytesNetworkOrder2Number(networkOrder);
+
+ xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength),
+ CHARSET);
+ from_appid = new String(
+ Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ // appid不相同的情况
+ if (!from_appid.equals(this.appidOrCorpid)) {
+ throw new RuntimeException("AppID不正确");
+ }
+
+ return xmlContent;
+
+ }
+
+ /**
+ * 将一个数字转换成生成4个字节的网络字节序bytes数组
+ *
+ * @param number
+ */
+ private static byte[] number2BytesInNetworkOrder(int number) {
+ byte[] orderBytes = new byte[4];
+ orderBytes[3] = (byte) (number & 0xFF);
+ orderBytes[2] = (byte) (number >> 8 & 0xFF);
+ orderBytes[1] = (byte) (number >> 16 & 0xFF);
+ orderBytes[0] = (byte) (number >> 24 & 0xFF);
+ return orderBytes;
+ }
+
+ /**
+ * 4个字节的网络字节序bytes数组还原成一个数字
+ *
+ * @param bytesInNetworkOrder
+ */
+ private static int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) {
+ int sourceNumber = 0;
+ for (int i = 0; i < 4; i++) {
+ sourceNumber <<= 8;
+ sourceNumber |= bytesInNetworkOrder[i] & 0xff;
+ }
+ return sourceNumber;
+ }
+
+ /**
+ * 随机生成16位字符串
+ */
+ private static String genRandomStr() {
+ String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ Random random = new Random();
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < 16; i++) {
+ int number = random.nextInt(base.length());
+ sb.append(base.charAt(number));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 生成xml消息
+ *
+ * @param encrypt 加密后的消息密文
+ * @param signature 安全签名
+ * @param timestamp 时间戳
+ * @param nonce 随机字符串
+ * @return 生成的xml字符串
+ */
+ private static String generateXml(String encrypt, String signature,
+ String timestamp, String nonce) {
+ String format = "
@@ -188,7 +188,7 @@ public interface WxCpService {
*
*
* @throws WxErrorException
- * @see #menuDelete(String)
+ * @see #menuDelete(Integer)
*/
void menuDelete() throws WxErrorException;
@@ -204,7 +204,7 @@ public interface WxCpService {
* @throws WxErrorException
* @see #menuDelete()
*/
- void menuDelete(String agentId) throws WxErrorException;
+ void menuDelete(Integer agentId) throws WxErrorException;
/**
*
@@ -215,7 +215,7 @@ public interface WxCpService {
*
*
* @throws WxErrorException
- * @see #menuGet(String)
+ * @see #menuGet(Integer)
*/
WxMenu menuGet() throws WxErrorException;
@@ -231,7 +231,7 @@ public interface WxCpService {
* @throws WxErrorException
* @see #menuGet()
*/
- WxMenu menuGet(String agentId) throws WxErrorException;
+ WxMenu menuGet(Integer agentId) throws WxErrorException;
/**
*
@@ -396,12 +396,12 @@ public interface WxCpService {
*
* 构造oauth2授权的url连接
*
- *
+ *
* @param state
* @return url
*/
String oauth2buildAuthorizationUrl(String state);
-
+
/**
*
* 构造oauth2授权的url连接
@@ -425,7 +425,7 @@ public interface WxCpService {
*
* @param code
* @return [userid, deviceid]
- * @see #oauth2getUserInfo(String, String)
+ * @see #oauth2getUserInfo(Integer, String)
*/
String[] oauth2getUserInfo(String code) throws WxErrorException;
@@ -443,7 +443,7 @@ public interface WxCpService {
* @return [userid, deviceid]
* @see #oauth2getUserInfo(String)
*/
- String[] oauth2getUserInfo(String agentId, String code) throws WxErrorException;
+ String[] oauth2getUserInfo(Integer agentId, String code) throws WxErrorException;
/**
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
index da95cab0..d44bbf5f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
@@ -12,7 +12,6 @@ import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager;
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.*;
@@ -22,8 +21,8 @@ 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.commons.lang3.StringUtils;
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;
@@ -69,7 +68,7 @@ public class WxCpServiceImpl implements WxCpService {
public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) {
try {
return SHA1.gen(this.configStorage.getToken(), timestamp, nonce, data)
- .equals(msgSignature);
+ .equals(msgSignature);
} catch (Exception e) {
return false;
}
@@ -95,18 +94,18 @@ public class WxCpServiceImpl implements WxCpService {
synchronized (this.globalAccessTokenRefreshLock) {
if (this.configStorage.isAccessTokenExpired()) {
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
- + "&corpid=" + this.configStorage.getCorpId()
- + "&corpsecret=" + this.configStorage.getCorpSecret();
+ + "&corpid=" + this.configStorage.getCorpId()
+ + "&corpsecret=" + this.configStorage.getCorpSecret();
try {
HttpGet httpGet = new HttpGet(url);
if (this.httpProxy != null) {
RequestConfig config = RequestConfig.custom()
- .setProxy(this.httpProxy).build();
+ .setProxy(this.httpProxy).build();
httpGet.setConfig(config);
}
String resultContent = null;
try (CloseableHttpClient httpclient = getHttpclient();
- CloseableHttpResponse response = httpclient.execute(httpGet)) {
+ CloseableHttpResponse response = httpclient.execute(httpGet)) {
resultContent = new BasicResponseHandler().handleResponse(response);
} finally {
httpGet.releaseConnection();
@@ -117,9 +116,7 @@ public class WxCpServiceImpl implements WxCpService {
}
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
this.configStorage.updateAccessToken(
- accessToken.getAccessToken(), accessToken.getExpiresIn());
- } catch (ClientProtocolException e) {
- throw new RuntimeException(e);
+ accessToken.getAccessToken(), accessToken.getExpiresIn());
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -149,7 +146,7 @@ public class WxCpServiceImpl implements WxCpService {
String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
this.configStorage.updateJsapiTicket(jsapiTicket,
- expiresInSeconds);
+ expiresInSeconds);
}
}
}
@@ -162,10 +159,10 @@ public class WxCpServiceImpl implements WxCpService {
String noncestr = RandomUtils.getRandomStr();
String jsapiTicket = getJsapiTicket(false);
String signature = SHA1.genWithAmple(
- "jsapi_ticket=" + jsapiTicket,
- "noncestr=" + noncestr,
- "timestamp=" + timestamp,
- "url=" + url
+ "jsapi_ticket=" + jsapiTicket,
+ "noncestr=" + noncestr,
+ "timestamp=" + timestamp,
+ "url=" + url
);
WxJsapiSignature jsapiSignature = new WxJsapiSignature();
jsapiSignature.setTimestamp(timestamp);
@@ -191,9 +188,9 @@ public class WxCpServiceImpl implements WxCpService {
}
@Override
- public void menuCreate(String agentId, WxMenu menu) throws WxErrorException {
+ public void menuCreate(Integer agentId, WxMenu menu) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid="
- + this.configStorage.getAgentId();
+ + this.configStorage.getAgentId();
post(url, menu.toJson());
}
@@ -203,7 +200,7 @@ public class WxCpServiceImpl implements WxCpService {
}
@Override
- public void menuDelete(String agentId) throws WxErrorException {
+ public void menuDelete(Integer agentId) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete?agentid=" + agentId;
get(url, null);
}
@@ -214,7 +211,7 @@ public class WxCpServiceImpl implements WxCpService {
}
@Override
- public WxMenu menuGet(String agentId) throws WxErrorException {
+ public WxMenu menuGet(Integer agentId) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/get?agentid=" + agentId;
try {
String resultContent = get(url, null);
@@ -230,7 +227,7 @@ public class WxCpServiceImpl implements WxCpService {
@Override
public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream)
- throws WxErrorException, IOException {
+ throws WxErrorException, IOException {
return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
}
@@ -244,9 +241,9 @@ public class WxCpServiceImpl implements WxCpService {
public File mediaDownload(String media_id) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get";
return execute(
- new MediaDownloadRequestExecutor(
-this.configStorage.getTmpDirFile()),
- url, "media_id=" + media_id);
+ new MediaDownloadRequestExecutor(
+ this.configStorage.getTmpDirFile()),
+ url, "media_id=" + media_id);
}
@@ -254,9 +251,9 @@ this.configStorage.getTmpDirFile()),
public Integer departCreate(WxCpDepart depart) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create";
String responseContent = execute(
- new SimplePostRequestExecutor(),
- url,
- depart.toJson());
+ new SimplePostRequestExecutor(),
+ url,
+ depart.toJson());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id"));
}
@@ -283,11 +280,11 @@ this.configStorage.getTmpDirFile()),
*/
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("department"),
- new TypeToken
>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("department"),
+ new TypeToken
>() {
+ }.getType()
+ );
}
@Override
@@ -313,8 +310,8 @@ this.configStorage.getTmpDirFile()),
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/batchdelete";
JsonObject jsonObject = new JsonObject();
JsonArray jsonArray = new JsonArray();
- for (int i = 0; i < userids.length; i++) {
- jsonArray.add(new JsonPrimitive(userids[i]));
+ for (String userid : userids) {
+ jsonArray.add(new JsonPrimitive(userid));
}
jsonObject.add("useridlist", jsonArray);
post(url, jsonObject.toString());
@@ -343,11 +340,11 @@ this.configStorage.getTmpDirFile()),
String responseContent = get(url, params);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("userlist"),
- new TypeToken
>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("userlist"),
+ new TypeToken
>() {
+ }.getType()
+ );
}
@Override
@@ -366,11 +363,11 @@ this.configStorage.getTmpDirFile()),
String responseContent = get(url, params);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("userlist"),
- new TypeToken
>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("userlist"),
+ new TypeToken
>() {
+ }.getType()
+ );
}
@Override
@@ -404,11 +401,11 @@ this.configStorage.getTmpDirFile()),
String responseContent = get(url, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("taglist"),
- new TypeToken
>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("taglist"),
+ new TypeToken
>() {
+ }.getType()
+ );
}
@Override
@@ -417,11 +414,11 @@ this.configStorage.getTmpDirFile()),
String responseContent = get(url, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("userlist"),
- new TypeToken
>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("userlist"),
+ new TypeToken
>() {
+ }.getType()
+ );
}
@Override
@@ -460,14 +457,14 @@ this.configStorage.getTmpDirFile()),
}
@Override
- public String oauth2buildAuthorizationUrl(String state) {
- return this.oauth2buildAuthorizationUrl(
-this.configStorage.getOauth2redirectUri(),
- state
- );
- }
+ public String oauth2buildAuthorizationUrl(String state) {
+ return this.oauth2buildAuthorizationUrl(
+ this.configStorage.getOauth2redirectUri(),
+ state
+ );
+ }
- @Override
+ @Override
public String oauth2buildAuthorizationUrl(String redirectUri, String state) {
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?";
url += "appid=" + this.configStorage.getCorpId();
@@ -487,10 +484,10 @@ this.configStorage.getOauth2redirectUri(),
}
@Override
- public String[] oauth2getUserInfo(String agentId, String code) throws WxErrorException {
+ public String[] oauth2getUserInfo(Integer agentId, String code) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?"
- + "code=" + code
- + "&agentid=" + agentId;
+ + "code=" + code
+ + "&agentid=" + agentId;
String responseText = get(url, null);
JsonElement je = new JsonParser().parse(responseText);
JsonObject jo = je.getAsJsonObject();
@@ -544,14 +541,14 @@ this.configStorage.getOauth2redirectUri(),
return executeInternal(executor, uri, data);
} catch (WxErrorException e) {
WxError error = e.getError();
- /**
+ /*
* -1 系统繁忙, 1000ms后重试
*/
if (error.getErrorCode() == -1) {
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
try {
this.log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis,
- retryTimes + 1);
+ retryTimes + 1);
Thread.sleep(sleepMillis);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
@@ -566,7 +563,7 @@ this.configStorage.getOauth2redirectUri(),
}
protected synchronized
* 发送客服消息
* 详情请见: 发送客服消息
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
*
*/
boolean sendKefuMessage(WxMpKefuMessage message) throws WxErrorException;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
index 48a6f610..8c867c5f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
@@ -2,11 +2,12 @@ package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException;
-import me.chanjar.weixin.mp.bean.*;
-import me.chanjar.weixin.mp.bean.result.*;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialArticleUpdate;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews;
+import me.chanjar.weixin.mp.bean.material.*;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
/**
@@ -20,21 +21,58 @@ import java.io.InputStream;
public interface WxMpMaterialService {
/**
+ *
* 新增临时素材
- *
- * @param mediaType
- * @param file
+ * 公众号经常有需要用到一些临时性的多媒体素材的场景,例如在使用接口特别是发送消息时,对多媒体文件、多媒体消息的获取和调用等操作,是通过media_id来进行的。
+ * 素材管理接口对所有认证的订阅号和服务号开放。通过本接口,公众号可以新增临时素材(即上传临时多媒体文件)。
+ * 请注意:
+ * 1、对于临时素材,每个素材(media_id)会在开发者上传或粉丝发送到微信服务器3天后自动删除(所以用户发送给开发者的素材,若开发者需要,应尽快下载到本地),以节省服务器资源。
+ * 2、media_id是可复用的。
+ * 3、素材的格式大小等要求与公众平台官网一致。具体是,图片大小不超过2M,支持png/jpeg/jpg/gif格式,语音大小不超过5M,长度不超过60秒,支持mp3/amr格式
+ * 4、需使用https调用本接口。
+ * 本接口即为原“上传多媒体文件”接口。
+ * 注意事项:
+ * 上传的临时多媒体文件有格式和大小限制,如下:
+ * 图片(image): 2M,支持PNG\JPEG\JPG\GIF格式
+ * 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式
+ * 视频(video):10MB,支持MP4格式
+ * 缩略图(thumb):64KB,支持JPG格式
+ *媒体文件在后台保存时间为3天,即3天后media_id失效。
+ * 详情请见: 新增临时素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
+ *
+ * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts}
+ * @param file 文件对象
* @throws WxErrorException
* @see #mediaUpload(String, String, InputStream)
*/
WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException;
+ /**
+ *
+ * 新增临时素材
+ * 本接口即为原“上传多媒体文件”接口。
+ *
+ * 详情请见: 新增临时素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
+ *
+ *
+ * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts}
+ * @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts}
+ * @param inputStream 输入流
+ * @throws WxErrorException
+ * @see #mediaUpload(java.lang.String, java.io.File)
+ */
+ WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException;
+
/**
*
* 获取临时素材
+ * 公众号可以使用本接口获取临时素材(即下载临时的多媒体文件)。请注意,视频文件不支持https下载,调用该接口需http协议。
* 本接口即为原“下载多媒体文件”接口。
* 根据微信文档,视频文件下载不了,会返回null
- * 详情请见: 获取临时素材
+ * 详情请见: 获取临时素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*
*
* @param media_id
@@ -46,10 +84,12 @@ public interface WxMpMaterialService {
/**
*
* 上传图文消息内的图片获取URL
- * 详情请见:http://mp.weixin.qq.com/wiki/15/40b6865b893947b764e2de8e4a1fb55f.html#.E4.B8.8A.E4.BC.A0.E5.9B.BE.E6.96.87.E6.B6.88.E6.81.AF.E5.86.85.E7.9A.84.E5.9B.BE.E7.89.87.E8.8E.B7.E5.8F.96URL.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91
+ * 请注意,本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制。图片仅支持jpg/png格式,大小必须在1MB以下。
+ * 详情请见: 新增永久素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*
*
- * @param file
+ * @param file 上传的文件对象
* @return WxMediaImgUploadResult 返回图片url
* @throws WxErrorException
*/
@@ -57,114 +97,123 @@ public interface WxMpMaterialService {
/**
*
- * 新增临时素材
- * 本接口即为原“上传多媒体文件”接口。
- *
- * 上传的多媒体文件有格式和大小限制,如下:
- * 图片(image): 1M,支持JPG格式
- * 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式
- * 视频(video):10MB,支持MP4格式
- * 缩略图(thumb):64KB,支持JPG格式
- *
- * 详情请见: 新增临时素材
- *
- *
- * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts}
- * @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts}
- * @param inputStream 输入流
- * @throws WxErrorException
- */
- WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException;
-
- /**
- *
- * 上传非图文永久素材
- *
- * 上传的多媒体文件有格式和大小限制,如下:
- * 图片(image): 图片大小不超过2M,支持bmp/png/jpeg/jpg/gif格式
- * 语音(voice):语音大小不超过5M,长度不超过60秒,支持mp3/wma/wav/amr格式
- * 视频(video):在上传视频素材时需要POST另一个表单,id为description,包含素材的描述信息,内容格式为JSON
- * 缩略图(thumb):文档未说明
- *
- * 详情请见: http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html
+ * 新增非图文永久素材
+ * 通过POST表单来调用接口,表单id为media,包含需要上传的素材内容,有filename、filelength、content-type等信息。请注意:图片素材将进入公众平台官网素材管理模块中的默认分组。
+ * 新增永久视频素材需特别注意:
+ * 在上传视频素材时需要POST另一个表单,id为description,包含素材的描述信息,内容格式为JSON,格式如下:
+ * { "title":VIDEO_TITLE, "introduction":INTRODUCTION }
+ * 详情请见: 新增永久素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE
+ *
+ * 除了3天就会失效的临时素材外,开发者有时需要永久保存一些素材,届时就可以通过本接口新增永久素材。
+ 永久图片素材新增后,将带有URL返回给开发者,开发者可以在腾讯系域名内使用(腾讯系域名外使用,图片将被屏蔽)。
+ 请注意:
+ 1、新增的永久素材也可以在公众平台官网素材管理模块中看到
+ 2、永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000,其他类型为1000
+ 3、素材的格式大小等要求与公众平台官网一致。具体是,图片大小不超过2M,支持bmp/png/jpeg/jpg/gif格式,语音大小不超过5M,长度不超过60秒,支持mp3/wma/wav/amr格式
+ 4、调用该接口需https协议
*
*
* @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts}
- * @param material 上传的素材, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterial}
+ * @param material 上传的素材, 请看{@link WxMpMaterial}
*/
WxMpMaterialUploadResult materialFileUpload(String mediaType, WxMpMaterial material) throws WxErrorException;
/**
*
- * 上传永久图文素材
- *
- * 详情请见: http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html
+ * 新增永久图文素材
+ *
+ * 详情请见: 新增永久素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=ACCESS_TOKEN
+ *
+ * 除了3天就会失效的临时素材外,开发者有时需要永久保存一些素材,届时就可以通过本接口新增永久素材。
+ 永久图片素材新增后,将带有URL返回给开发者,开发者可以在腾讯系域名内使用(腾讯系域名外使用,图片将被屏蔽)。
+ 请注意:
+ 1、新增的永久素材也可以在公众平台官网素材管理模块中看到
+ 2、永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000,其他类型为1000
+ 3、素材的格式大小等要求与公众平台官网一致。具体是,图片大小不超过2M,支持bmp/png/jpeg/jpg/gif格式,语音大小不超过5M,长度不超过60秒,支持mp3/wma/wav/amr格式
+ 4、调用该接口需https协议
*
*
- * @param news 上传的图文消息, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterialNews}
+ * @param news 上传的图文消息, 请看{@link WxMpMaterialNews}
*/
WxMpMaterialUploadResult materialNewsUpload(WxMpMaterialNews news) throws WxErrorException;
/**
*
- * 下载声音或者图片永久素材
+ * 获取声音或者图片永久素材
*
- * 详情请见: http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html
+ * 详情请见: 获取永久素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*
*
- * @param media_id 永久素材的id
+ * @param mediaId 永久素材的id
*/
- InputStream materialImageOrVoiceDownload(String media_id) throws WxErrorException;
+ InputStream materialImageOrVoiceDownload(String mediaId) throws WxErrorException;
/**
*
* 获取视频永久素材的信息和下载地址
*
- * 详情请见: http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html
+ * 详情请见: 获取永久素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*
*
- * @param media_id 永久素材的id
+ * @param mediaId 永久素材的id
*/
- WxMpMaterialVideoInfoResult materialVideoInfo(String media_id) throws WxErrorException;
+ WxMpMaterialVideoInfoResult materialVideoInfo(String mediaId) throws WxErrorException;
/**
*
* 获取图文永久素材的信息
*
- * 详情请见: http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html
+ * 详情请见: 获取永久素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*
*
- * @param media_id 永久素材的id
+ * @param mediaId 永久素材的id
*/
- WxMpMaterialNews materialNewsInfo(String media_id) throws WxErrorException;
+ WxMpMaterialNews materialNewsInfo(String mediaId) throws WxErrorException;
/**
*
- * 更新图文永久素材
+ * 修改永久图文素材
*
- * 详情请见: http://mp.weixin.qq.com/wiki/4/19a59cba020d506e767360ca1be29450.html
+ * 详情请见: 修改永久图文素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/update_news?access_token=ACCESS_TOKEN
*
*
- * @param wxMpMaterialArticleUpdate 用来更新图文素材的bean, 请看{@link me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate}
+ * @param wxMpMaterialArticleUpdate 用来更新图文素材的bean, 请看{@link WxMpMaterialArticleUpdate}
*/
boolean materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException;
/**
*
* 删除永久素材
- *
- * 详情请见: http://mp.weixin.qq.com/wiki/5/e66f61c303db51a6c0f90f46b15af5f5.html
+ * 在新增了永久素材后,开发者可以根据本接口来删除不再需要的永久素材,节省空间。
+ * 请注意:
+ * 1、请谨慎操作本接口,因为它可以删除公众号在公众平台官网素材管理模块中新建的图文消息、语音、视频等素材(但需要先通过获取素材列表来获知素材的media_id)
+ * 2、临时素材无法通过本接口删除
+ * 3、调用该接口需https协议
+ * 详情请见: 删除永久素材
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*
*
- * @param media_id 永久素材的id
+ * @param mediaId 永久素材的id
*/
- boolean materialDelete(String media_id) throws WxErrorException;
+ boolean materialDelete(String mediaId) throws WxErrorException;
/**
*
* 获取各类素材总数
- *
- * 详情请见: http://mp.weixin.qq.com/wiki/16/8cc64f8c189674b421bee3ed403993b8.html
+ * 开发者可以根据本接口来获取永久素材的列表,需要时也可保存到本地。
+ * 请注意:
+ * 1.永久素材的总数,也会计算公众平台官网素材管理中的素材
+ * 2.图片和图文消息素材(包括单图文和多图文)的总数上限为5000,其他素材的总数上限为1000
+ * 3.调用该接口需https协议
+ *
+ * 详情请见: 获取素材总数
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*
*/
WxMpMaterialCountResult materialCount() throws WxErrorException;
@@ -173,7 +222,8 @@ public interface WxMpMaterialService {
*
* 分页获取图文素材列表
*
- * 详情请见: http://mp.weixin.qq.com/wiki/12/2108cd7aafff7f388f41f37efa710204.html
+ * 详情请见: 获取素材列表
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
*
*
* @param offset 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回
@@ -185,7 +235,8 @@ public interface WxMpMaterialService {
*
* 分页获取其他媒体素材列表
*
- * 详情请见: http://mp.weixin.qq.com/wiki/12/2108cd7aafff7f388f41f37efa710204.html
+ * 详情请见: 获取素材列表
+ * 接口url格式:https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
*
*
* @param type 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
index dae2a238..5a336bc8 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
@@ -2,8 +2,8 @@ package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
-import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
-import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import java.util.Map;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java
index 3fcd6d95..15223895 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java
@@ -2,7 +2,7 @@ package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
-import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import java.util.Map;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageMatcher.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageMatcher.java
index 68798ae2..812992c9 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageMatcher.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageMatcher.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.mp.api;
-import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
/**
* 消息匹配器,用在消息路由的时候
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
index 7db50e79..24dc4451 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
@@ -1,230 +1,230 @@
-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.mp.bean.WxMpXmlMessage;
-import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
-
-/**
- *
- * 微信消息路由器,通过代码化的配置,把来自微信的消息交给handler处理
- *
- * 说明:
- * 1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理
- * 2. 默认情况下消息只会被处理一次,除非使用 {@link WxMpMessageRouterRule#next()}
- * 3. 规则的结束必须用{@link WxMpMessageRouterRule#end()}或者{@link WxMpMessageRouterRule#next()},否则不会生效
- *
- * 使用方法:
- * WxMpMessageRouter router = new WxMpMessageRouter();
- * router
- * .rule()
- * .msgType("MSG_TYPE").event("EVENT").eventKey("EVENT_KEY").content("CONTENT")
- * .interceptor(interceptor, ...).handler(handler, ...)
- * .end()
- * .rule()
- * // 另外一个匹配规则
- * .end()
- * ;
- *
- * // 将WxXmlMessage交给消息路由器
- * router.route(message);
- *
- *
- * @author Daniel Qian
- *
- */
-public class WxMpMessageRouter {
-
- protected final Logger log = LoggerFactory.getLogger(WxMpMessageRouter.class);
-
- private static final int DEFAULT_THREAD_POOL_SIZE = 100;
-
- private final List
- * 设置自定义的 {@link ExecutorService}
- * 如果不调用该方法,默认使用 Executors.newFixedThreadPool(100)
- *
- * @param executorService
- */
- public void setExecutorService(ExecutorService executorService) {
- this.executorService = executorService;
- }
-
- /**
- *
- * 设置自定义的 {@link me.chanjar.weixin.common.api.WxMessageDuplicateChecker}
- * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker}
- *
- * @param messageDuplicateChecker
- */
- public void setMessageDuplicateChecker(WxMessageDuplicateChecker messageDuplicateChecker) {
- this.messageDuplicateChecker = messageDuplicateChecker;
- }
-
- /**
- *
- * 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager}
- * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.session.StandardSessionManager}
- *
- * @param sessionManager
- */
- public void setSessionManager(WxSessionManager sessionManager) {
- this.sessionManager = sessionManager;
- }
-
- /**
- *
- * 设置自定义的{@link me.chanjar.weixin.common.api.WxErrorExceptionHandler}
- * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler}
- *
- * @param exceptionHandler
- */
- public void setExceptionHandler(WxErrorExceptionHandler exceptionHandler) {
- this.exceptionHandler = exceptionHandler;
- }
-
- List
+ * 微信消息路由器,通过代码化的配置,把来自微信的消息交给handler处理
+ *
+ * 说明:
+ * 1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理
+ * 2. 默认情况下消息只会被处理一次,除非使用 {@link WxMpMessageRouterRule#next()}
+ * 3. 规则的结束必须用{@link WxMpMessageRouterRule#end()}或者{@link WxMpMessageRouterRule#next()},否则不会生效
+ *
+ * 使用方法:
+ * WxMpMessageRouter router = new WxMpMessageRouter();
+ * router
+ * .rule()
+ * .msgType("MSG_TYPE").event("EVENT").eventKey("EVENT_KEY").content("CONTENT")
+ * .interceptor(interceptor, ...).handler(handler, ...)
+ * .end()
+ * .rule()
+ * // 另外一个匹配规则
+ * .end()
+ * ;
+ *
+ * // 将WxXmlMessage交给消息路由器
+ * router.route(message);
+ *
+ *
+ * @author Daniel Qian
+ *
+ */
+public class WxMpMessageRouter {
+
+ protected final Logger log = LoggerFactory.getLogger(WxMpMessageRouter.class);
+
+ private static final int DEFAULT_THREAD_POOL_SIZE = 100;
+
+ private final List
+ * 设置自定义的 {@link ExecutorService}
+ * 如果不调用该方法,默认使用 Executors.newFixedThreadPool(100)
+ *
+ * @param executorService
+ */
+ public void setExecutorService(ExecutorService executorService) {
+ this.executorService = executorService;
+ }
+
+ /**
+ *
+ * 设置自定义的 {@link me.chanjar.weixin.common.api.WxMessageDuplicateChecker}
+ * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker}
+ *
+ * @param messageDuplicateChecker
+ */
+ public void setMessageDuplicateChecker(WxMessageDuplicateChecker messageDuplicateChecker) {
+ this.messageDuplicateChecker = messageDuplicateChecker;
+ }
+
+ /**
+ *
+ * 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager}
+ * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.session.StandardSessionManager}
+ *
+ * @param sessionManager
+ */
+ public void setSessionManager(WxSessionManager sessionManager) {
+ this.sessionManager = sessionManager;
+ }
+
+ /**
+ *
+ * 设置自定义的{@link me.chanjar.weixin.common.api.WxErrorExceptionHandler}
+ * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler}
+ *
+ * @param exceptionHandler
+ */
+ public void setExceptionHandler(WxErrorExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ List
+ * 关闭订单
+ * 应用场景
+ * 以下情况需要调用关单接口:
+ * 1. 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;
+ * 2. 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。
+ * 注意:订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。
+ * 接口地址:https://api.mch.weixin.qq.com/pay/closeorder
+ * 是否需要证书: 不需要。
+ *
+ * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。
+ * @throws WxErrorException
+ */
+ WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxErrorException;
+
/**
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
@@ -63,6 +81,13 @@ public interface WxMpPayService {
*/
WxPayRefundResult refund(WxPayRefundRequest request, File keyFile) throws WxErrorException;
+ /**
+ * 读取支付结果通知
+ * 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
+ *
+ */
+ WxPayJsSDKCallback getJSSDKCallbackData(String xmlData) throws WxErrorException;
+
/**
*
* 计算Map键值对是否和签名相符,
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
index e77b60d9..a74e718d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
@@ -5,6 +5,7 @@ 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 org.apache.http.HttpHost;
/**
* 微信API的Service
@@ -113,6 +114,20 @@ public interface WxMpService {
*/
WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException;
+ /**
+ *
+ * 群发消息预览接口
+ * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100次),请勿滥用。
+ * 接口调用请求说明
+ * http请求方式: POST
+ * https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN
+ * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
+ *
+ *
+ * @return wxMpMassSendResult
+ */
+ WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws Exception;
+
/**
*
* 长链接转短链接接口
@@ -214,6 +229,11 @@ public interface WxMpService {
*/
- * 预览接口
- * 详情请见:http://mp.weixin.qq.com/wiki/15/40b6865b893947b764e2de8e4a1fb55f.html#.E9.A2.84.E8.A7.88.E6.8E.A5.E5.8F.A3.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91
- *
- *
- * @return wxMpMassSendResult
- */
- WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws Exception;
-
/**
* 获取WxMpConfigStorage 对象
*
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java
index f46ca634..96499128 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java
@@ -1,12 +1,12 @@
package me.chanjar.weixin.mp.api;
-import java.util.List;
-
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.WxMpUserQuery;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.result.WxMpUserList;
+import java.util.List;
+
/**
* 用户管理相关操作接口
*
@@ -16,8 +16,10 @@ public interface WxMpUserService {
/**
*
- * 设置用户备注名接口
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=设置用户备注名接口
+ * 设置用户备注名
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140838&token=&lang=zh_CN
+ * http请求方式: POST(请使用https协议)
+ * 接口地址:https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token=ACCESS_TOKEN
*
*
* @param openid 用户openid
@@ -25,10 +27,24 @@ public interface WxMpUserService {
*/
void userUpdateRemark(String openid, String remark) throws WxErrorException;
+ /**
+ *
+ * 获取用户基本信息(语言为默认的zh_CN 简体)
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839&token=&lang=zh_CN
+ * http请求方式: GET
+ * 接口地址:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
+ *
+ *
+ * @param openid 用户openid
+ */
+ WxMpUser userInfo(String openid) throws WxErrorException;
+
/**
*
* 获取用户基本信息
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取用户基本信息
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839&token=&lang=zh_CN
+ * http请求方式: GET
+ * 接口地址:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
*
*
* @param openid 用户openid
@@ -39,7 +55,10 @@ public interface WxMpUserService {
/**
*
* 获取用户基本信息列表
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=批量获取用户基本信息
+ * 开发者可通过该接口来批量获取用户基本信息。最多支持一次拉取100条。
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839&token=&lang=zh_CN
+ * http请求方式: POST
+ * 接口地址:https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN
*
*
* @param openids 用户openid列表
@@ -49,7 +68,10 @@ public interface WxMpUserService {
/**
*
* 获取用户基本信息列表
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=批量获取用户基本信息
+ * 开发者可通过该接口来批量获取用户基本信息。最多支持一次拉取100条。
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839&token=&lang=zh_CN
+ * http请求方式: POST
+ * 接口地址:https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN
*
*
* @param userQuery 详细查询参数
@@ -58,8 +80,11 @@ public interface WxMpUserService {
/**
*
- * 获取关注者列表
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取关注者列表
+ * 获取用户列表
+ * 公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140840&token=&lang=zh_CN
+ * http请求方式: GET(请使用https协议)
+ * 接口地址:https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
*
*
* @param nextOpenid 可选,第一个拉取的OPENID,null为从头开始拉取
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
index 63e13809..2e6bf88e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
@@ -1,6 +1,7 @@
package me.chanjar.weixin.mp.api.impl;
import java.util.Arrays;
+import java.util.concurrent.locks.Lock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,11 +30,6 @@ public class WxMpCardServiceImpl implements WxMpCardService {
private final Logger log = LoggerFactory.getLogger(WxMpCardServiceImpl.class);
- /**
- * 全局的是否正在刷新卡券api_ticket的锁
- */
- private final Object globalCardApiTicketRefreshLock = new Object();
-
private WxMpService wxMpService;
public WxMpCardServiceImpl(WxMpService wxMpService) {
@@ -66,21 +62,25 @@ public class WxMpCardServiceImpl implements WxMpCardService {
*/
@Override
public String getCardApiTicket(boolean forceRefresh) throws WxErrorException {
- if (forceRefresh) {
- this.wxMpService.getWxMpConfigStorage().expireCardApiTicket();
- }
- if (this.wxMpService.getWxMpConfigStorage().isCardApiTicketExpired()) {
- synchronized (this.globalCardApiTicketRefreshLock) {
- if (this.wxMpService.getWxMpConfigStorage().isCardApiTicketExpired()) {
- String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card";
- String responseContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null);
- JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
- JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
- String cardApiTicket = tmpJsonObject.get("ticket").getAsString();
- int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
- this.wxMpService.getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds);
- }
+ Lock lock = wxMpService.getWxMpConfigStorage().getCardApiTicketLock();
+ try {
+ lock.lock();
+
+ if (forceRefresh) {
+ this.wxMpService.getWxMpConfigStorage().expireCardApiTicket();
+ }
+
+ if (this.wxMpService.getWxMpConfigStorage().isCardApiTicketExpired()) {
+ String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card";
+ String responseContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null);
+ JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
+ JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
+ String cardApiTicket = tmpJsonObject.get("ticket").getAsString();
+ int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
+ this.wxMpService.getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds);
}
+ } finally {
+ lock.unlock();
}
return this.wxMpService.getWxMpConfigStorage().getCardApiTicket();
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
index 310bbe78..af9fa54c 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
@@ -10,10 +10,10 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.mp.api.WxMpMaterialService;
import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.bean.WxMpMaterial;
-import me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate;
-import me.chanjar.weixin.mp.bean.WxMpMaterialNews;
-import me.chanjar.weixin.mp.bean.result.*;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialArticleUpdate;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews;
+import me.chanjar.weixin.mp.bean.material.*;
import me.chanjar.weixin.mp.util.http.*;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
@@ -37,8 +37,13 @@ public class WxMpMaterialServiceImpl implements WxMpMaterialService {
}
@Override
- public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException {
- return this.mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
+ public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException {
+ try {
+ return this.mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build());
+ }
}
@Override
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java
index 3b3b7510..3273cd2b 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java
@@ -7,11 +7,15 @@ import me.chanjar.weixin.common.util.BeanUtils;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.api.WxMpPayService;
import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.pay.WxPayJsSDKCallback;
+import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderCloseResult;
import me.chanjar.weixin.mp.bean.pay.request.*;
import me.chanjar.weixin.mp.bean.pay.result.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Consts;
+import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
@@ -21,10 +25,13 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOException;
import java.security.KeyStore;
import java.util.*;
@@ -35,6 +42,8 @@ import java.util.*;
*/
public class WxMpPayServiceImpl implements WxMpPayService {
+ protected final Logger log = LoggerFactory.getLogger(this.getClass());
+
private static final String PAY_BASE_URL = "https://api.mch.weixin.qq.com";
private static final String[] TRADE_TYPES = new String[]{"JSAPI","NATIVE", "APP"};
private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS",
@@ -52,8 +61,8 @@ public class WxMpPayServiceImpl implements WxMpPayService {
checkParameters(request);
XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxPayRefundResult.class);
xstream.processAnnotations(WxPayRefundRequest.class);
+ xstream.processAnnotations(WxPayRefundResult.class);
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
String partnerId = this.wxMpService.getWxMpConfigStorage().getPartnerId();
@@ -65,21 +74,20 @@ public class WxMpPayServiceImpl implements WxMpPayService {
String url = PAY_BASE_URL + "/secapi/pay/refund";
String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), partnerId);
- WxPayRefundResult wxMpPayRefundResult = (WxPayRefundResult) xstream.fromXML(responseContent);
-
- if (!"SUCCESS".equalsIgnoreCase(wxMpPayRefundResult.getResultCode())
- || !"SUCCESS".equalsIgnoreCase(wxMpPayRefundResult.getReturnCode())) {
- WxError error = new WxError();
- error.setErrorCode(-1);
- error.setErrorMsg("return_code:" + wxMpPayRefundResult.getReturnCode()
- + ";return_msg:" + wxMpPayRefundResult.getReturnMsg()
- + ";result_code:" + wxMpPayRefundResult.getResultCode() + ";err_code"
- + wxMpPayRefundResult.getErrCode() + ";err_code_des"
- + wxMpPayRefundResult.getErrCodeDes());
- throw new WxErrorException(error);
- }
+ WxPayRefundResult result = (WxPayRefundResult) xstream.fromXML(responseContent);
+ this.checkResult(result);
+ return result;
+ }
- return wxMpPayRefundResult;
+ private void checkResult(WxPayBaseResult result) throws WxErrorException {
+ if (!"SUCCESS".equalsIgnoreCase(result.getReturnCode())
+ || !"SUCCESS".equalsIgnoreCase(result.getResultCode())) {
+ throw new WxErrorException(WxError.newBuilder().setErrorCode(-1)
+ .setErrorMsg("返回代码:" + result.getReturnCode() + ", 返回信息: "
+ + result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: "
+ + result.getErrCode() + ", 错误详情: " + result.getErrCodeDes())
+ .build());
+ }
}
private void checkParameters(WxPayRefundRequest request) throws WxErrorException {
@@ -96,6 +104,18 @@ public class WxMpPayServiceImpl implements WxMpPayService {
}
}
+ @Override
+ public WxPayJsSDKCallback getJSSDKCallbackData(String xmlData) throws WxErrorException {
+ try {
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.alias("xml", WxPayJsSDKCallback.class);
+ return (WxPayJsSDKCallback) xstream.fromXML(xmlData);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new WxErrorException(WxError.newBuilder().setErrorMsg("发生异常" + e.getMessage()).build());
+ }
+ }
+
@Override
public boolean checkJSSDKCallbackDataSignature(Map
* 累计用户数据接口的返回JSON数据包
@@ -46,7 +43,7 @@ public class WxDataCubeUserCumulate implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
public static List
* 用户增减数据接口的返回JSON数据包
@@ -65,7 +62,7 @@ public class WxDataCubeUserSummary implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
public static List
* 群发图文消息article
- * 1. thumbMediaId (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得
+ * 1. thumbMediaId (必填) 图文消息的封面图片素材id(必须是永久mediaID)
* 2. author 图文消息的作者
* 3. title (必填) 图文消息的标题
* 4. contentSourceUrl 在图文消息页面点击“阅读原文”后的页面链接
@@ -157,12 +156,12 @@ public class WxMpMaterialNews implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
}
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMaterialNewsBatchGetResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNewsBatchGetResult.java
similarity index 79%
rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMaterialNewsBatchGetResult.java
rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNewsBatchGetResult.java
index 48563244..03f0a6d8 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMaterialNewsBatchGetResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNewsBatchGetResult.java
@@ -1,17 +1,14 @@
-package me.chanjar.weixin.mp.bean.result;
+package me.chanjar.weixin.mp.bean.material;
-import me.chanjar.weixin.mp.bean.WxMpMaterialNews;
+import me.chanjar.weixin.common.util.ToStringUtils;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class WxMpMaterialNewsBatchGetResult implements Serializable {
-
- /**
- *
- */
private static final long serialVersionUID = -1617952797921001666L;
+
private int totalCount;
private int itemCount;
private List
@@ -56,6 +53,9 @@ public class WxMpXmlMessage implements Serializable {
@XStreamConverter(value = XStreamCDataConverter.class)
private String content;
+ @XStreamAlias("MenuId")
+ private Long menuId;
+
@XStreamAlias("MsgId")
private Long msgId;
@@ -687,6 +687,14 @@ public class WxMpXmlMessage implements Serializable {
this.sendLocationInfo = sendLocationInfo;
}
+ public Long getMenuId() {
+ return this.menuId;
+ }
+
+ public void setMenuId(Long menuId) {
+ this.menuId = menuId;
+ }
+
public String getKfAccount() {
return this.kfAccount;
}
@@ -715,7 +723,7 @@ public class WxMpXmlMessage implements Serializable {
public static class ScanCodeInfo {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
@XStreamAlias("ScanType")
@@ -755,7 +763,7 @@ public class WxMpXmlMessage implements Serializable {
public static class SendPicsInfo {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
@XStreamAlias("Count")
@@ -780,8 +788,7 @@ public class WxMpXmlMessage implements Serializable {
public static class Item {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this,
- ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
@XStreamAlias("PicMd5Sum")
@@ -823,7 +830,7 @@ public class WxMpXmlMessage implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
public String getLocationX() {
@@ -869,6 +876,6 @@ public class WxMpXmlMessage implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java
similarity index 93%
rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessage.java
rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java
index 18204a51..62852ca8 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java
@@ -1,4 +1,4 @@
-package me.chanjar.weixin.mp.bean;
+package me.chanjar.weixin.mp.bean.message;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
@@ -9,7 +9,7 @@ import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter;
public class WxMpXmlOutImageMessage extends WxMpXmlOutMessage {
/**
- *
+ *
*/
private static final long serialVersionUID = -2684778597067990723L;
@XStreamAlias("Image")
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java
similarity index 96%
rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMessage.java
rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java
index 2eb6818b..5b8b81e5 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java
@@ -1,10 +1,10 @@
-package me.chanjar.weixin.mp.bean;
+package me.chanjar.weixin.mp.bean.message;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
-import me.chanjar.weixin.mp.bean.outxmlbuilder.*;
+import me.chanjar.weixin.mp.builder.outxml.*;
import me.chanjar.weixin.mp.util.crypto.WxMpCryptUtil;
import me.chanjar.weixin.mp.util.xml.XStreamTransformer;
@@ -18,14 +18,14 @@ public abstract class WxMpXmlOutMessage implements Serializable {
@XStreamAlias("ToUserName")
@XStreamConverter(value=XStreamCDataConverter.class)
protected String toUserName;
-
+
@XStreamAlias("FromUserName")
@XStreamConverter(value=XStreamCDataConverter.class)
protected String fromUserName;
-
+
@XStreamAlias("CreateTime")
protected Long createTime;
-
+
@XStreamAlias("MsgType")
@XStreamConverter(value=XStreamCDataConverter.class)
protected String msgType;
@@ -61,7 +61,7 @@ public abstract class WxMpXmlOutMessage implements Serializable {
public void setMsgType(String msgType) {
this.msgType = msgType;
}
-
+
public String toXml() {
return XStreamTransformer.toXml((Class
@@ -71,7 +68,7 @@ public class WxEntPayQueryRequest extends WxPayBaseRequest {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java
index 196ef95f..ef6e8d0a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java
@@ -1,9 +1,7 @@
package me.chanjar.weixin.mp.bean.pay.request;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
import com.thoughtworks.xstream.annotations.XStreamAlias;
+import me.chanjar.weixin.common.util.ToStringUtils;
/**
*
@@ -278,7 +276,7 @@ public class WxEntPayRequest {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java
index aabbdfd1..341c3b2e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java
@@ -1,9 +1,7 @@
package me.chanjar.weixin.mp.bean.pay.request;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
import com.thoughtworks.xstream.annotations.XStreamAlias;
+import me.chanjar.weixin.common.util.ToStringUtils;
/**
*
@@ -103,6 +101,6 @@ public abstract class WxPayBaseRequest {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java
new file mode 100644
index 00000000..8f26750f
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.mp.bean.pay.request;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ *
+ * 关闭订单请求对象类
+ * Created by Binary Wang on 2016-10-27.
+ * @author binarywang(Binary Wang)
+ *
+ */
+@XStreamAlias("xml")
+public class WxPayOrderCloseRequest extends WxPayBaseRequest{
+
+ /**
+ *
+ * 商户订单号
+ * out_trade_no
+ * 二选一
+ * String(32)
+ * 20150806125346
+ * 商户系统内部的订单号,当没提供transaction_id时需要传这个。
+ *
+ */
+ @XStreamAlias("out_trade_no")
+ private String outTradeNo;
+
+ public String getOutTradeNo() {
+ return this.outTradeNo;
+ }
+
+ public void setOutTradeNo(String outTradeNo) {
+ this.outTradeNo = outTradeNo;
+ }
+
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
index 79f8dbb5..64310138 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
@@ -1,9 +1,7 @@
package me.chanjar.weixin.mp.bean.pay.result;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
import com.thoughtworks.xstream.annotations.XStreamAlias;
+import me.chanjar.weixin.common.util.ToStringUtils;
/**
*
@@ -15,7 +13,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
public abstract class WxPayBaseResult {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
/**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java
new file mode 100644
index 00000000..ccfa07bf
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.mp.bean.pay.result;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ *
+ * 关闭订单结果对象类
+ * Created by Binary Wang on 2016-10-27.
+ * @author binarywang(Binary Wang)
+ *
+ */
+@XStreamAlias("xml")
+public class WxPayOrderCloseResult extends WxPayBaseResult {
+
+ /**
+ * 业务结果描述
+ */
+ @XStreamAlias("result_msg")
+ private String resultMsg;
+
+ public String getResultMsg() {
+ return this.resultMsg;
+ }
+
+ public void setResultMsg(String resultMsg) {
+ this.resultMsg = resultMsg;
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java
index 7a711ba1..b39d2fed 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java
@@ -1,8 +1,7 @@
package me.chanjar.weixin.mp.bean.result;
+import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.mp.bean.WxMpCard;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
@@ -15,7 +14,7 @@ import java.io.Serializable;
public class WxMpCardResult implements Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = -7950878428289035637L;
@@ -65,7 +64,7 @@ public class WxMpCardResult implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
public String getUserCardStatus() {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
index e3e894cb..8d7090fd 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
@@ -1,18 +1,15 @@
package me.chanjar.weixin.mp.bean.result;
-import java.io.Serializable;
-import java.lang.reflect.Type;
-import java.util.List;
-
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
-
+import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import java.io.Serializable;
+import java.lang.reflect.Type;
+import java.util.List;
+
/**
* 微信用户信息
* @author chanjarster
@@ -175,7 +172,7 @@ public class WxMpUser implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreBaseInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreBaseInfo.java
index 409e41c3..91d52d2e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreBaseInfo.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreBaseInfo.java
@@ -4,9 +4,8 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;
import me.chanjar.weixin.common.annotation.Required;
+import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
import java.util.List;
@@ -19,7 +18,7 @@ import java.util.List;
public class WxMpStoreBaseInfo {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
public static WxMpStoreBaseInfo fromJson(String json) {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreInfo.java
index 9d07eb03..1450bc3c 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreInfo.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreInfo.java
@@ -1,14 +1,12 @@
package me.chanjar.weixin.mp.bean.store;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
import com.google.gson.annotations.SerializedName;
+import me.chanjar.weixin.common.util.ToStringUtils;
public class WxMpStoreInfo {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
@SerializedName("base_info")
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreListResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreListResult.java
index f16c1534..f9cc3fbe 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreListResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreListResult.java
@@ -1,14 +1,11 @@
package me.chanjar.weixin.mp.bean.store;
-import java.util.List;
-
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
import com.google.gson.annotations.SerializedName;
-
+import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import java.util.List;
+
/**
* 门店列表结果类
* @author binarywang(Binary Wang)
@@ -18,7 +15,7 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
public class WxMpStoreListResult {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
public static WxMpStoreListResult fromJson(String json) {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxTagListUser.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxTagListUser.java
index 47ed067a..e1307be7 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxTagListUser.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxTagListUser.java
@@ -1,14 +1,11 @@
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.annotations.SerializedName;
-
+import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import java.util.List;
+
/**
* 获取标签下粉丝列表的结果对象
* @author binarywang(Binary Wang)
@@ -26,7 +23,7 @@ public class WxTagListUser {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
/**
@@ -74,7 +71,7 @@ public class WxTagListUser {
public static class WxTagListUserData {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
/**
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxUserTag.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxUserTag.java
index 67b443a4..6554c261 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxUserTag.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxUserTag.java
@@ -1,15 +1,12 @@
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.common.util.ToStringUtils;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import java.util.List;
+
/**
* 用户标签对象
* @author binarywang(Binary Wang)
@@ -73,6 +70,6 @@ public class WxUserTag {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplate.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplate.java
index 0b3a1e61..368284f2 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplate.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplate.java
@@ -1,16 +1,13 @@
package me.chanjar.weixin.mp.bean.template;
-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.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
-
+import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import java.util.List;
+
/**
*
* 模板列表信息
@@ -30,9 +27,9 @@ public class WxMpTemplate {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
-
+
/**
* template_id
* 模板ID
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustry.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustry.java
index b0f689a4..6d0db1ab 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustry.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustry.java
@@ -1,9 +1,8 @@
package me.chanjar.weixin.mp.bean.template;
+import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
@@ -48,7 +47,7 @@ public class WxMpTemplateIndustry implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
public String getId() {
@@ -78,7 +77,7 @@ public class WxMpTemplateIndustry implements Serializable {
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return ToStringUtils.toSimpleString(this);
}
public static WxMpTemplateIndustry fromJson(String json) {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java
index 106e5fb6..df8e708d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java
@@ -1,18 +1,20 @@
package me.chanjar.weixin.mp.bean.template;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
-
+/**
+ * 参考 http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN 发送模板消息接口部分
+ */
public class WxMpTemplateMessage implements Serializable {
private static final long serialVersionUID = 5063374783759519418L;
private String toUser;
private String templateId;
private String url;
- private String topColor;
private List