mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2026-03-10 00:13:40 +08:00
code clean up for common module
This commit is contained in:
@@ -7,7 +7,7 @@ public class StringUtils {
|
||||
|
||||
/**
|
||||
* <p>Checks if a CharSequence is whitespace, empty ("") or null.</p>
|
||||
*
|
||||
* <p>
|
||||
* <pre>
|
||||
* StringUtils.isBlank(null) = true
|
||||
* StringUtils.isBlank("") = true
|
||||
@@ -16,9 +16,8 @@ public class StringUtils {
|
||||
* StringUtils.isBlank(" bob ") = false
|
||||
* </pre>
|
||||
*
|
||||
* @param cs the CharSequence to check, may be null
|
||||
* @param cs the CharSequence to check, may be null
|
||||
* @return {@code true} if the CharSequence is null, empty or whitespace
|
||||
* @since 2.0
|
||||
* @since 3.0 Changed signature from isBlank(String) to isBlank(CharSequence)
|
||||
*/
|
||||
public static boolean isBlank(CharSequence cs) {
|
||||
@@ -36,7 +35,7 @@ public class StringUtils {
|
||||
|
||||
/**
|
||||
* <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
|
||||
*
|
||||
* <p>
|
||||
* <pre>
|
||||
* StringUtils.isNotBlank(null) = false
|
||||
* StringUtils.isNotBlank("") = false
|
||||
@@ -45,10 +44,9 @@ public class StringUtils {
|
||||
* StringUtils.isNotBlank(" bob ") = true
|
||||
* </pre>
|
||||
*
|
||||
* @param cs the CharSequence to check, may be null
|
||||
* @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 2.0
|
||||
* 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) {
|
||||
@@ -57,7 +55,7 @@ public class StringUtils {
|
||||
|
||||
/**
|
||||
* <p>Checks if a CharSequence is empty ("") or null.</p>
|
||||
*
|
||||
* <p>
|
||||
* <pre>
|
||||
* StringUtils.isEmpty(null) = true
|
||||
* StringUtils.isEmpty("") = true
|
||||
@@ -65,12 +63,12 @@ public class StringUtils {
|
||||
* StringUtils.isEmpty("bob") = false
|
||||
* StringUtils.isEmpty(" bob ") = false
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* <p>NOTE: This method changed in Lang version 2.0.
|
||||
* It no longer trims the CharSequence.
|
||||
* That functionality is available in isBlank().</p>
|
||||
*
|
||||
* @param cs the CharSequence to check, may be null
|
||||
* @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)
|
||||
*/
|
||||
@@ -80,7 +78,7 @@ public class StringUtils {
|
||||
|
||||
/**
|
||||
* <p>Checks if a CharSequence is not empty ("") and not null.</p>
|
||||
*
|
||||
* <p>
|
||||
* <pre>
|
||||
* StringUtils.isNotEmpty(null) = false
|
||||
* StringUtils.isNotEmpty("") = false
|
||||
@@ -89,7 +87,7 @@ public class StringUtils {
|
||||
* StringUtils.isNotEmpty(" bob ") = true
|
||||
* </pre>
|
||||
*
|
||||
* @param cs the CharSequence to check, may be null
|
||||
* @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)
|
||||
*/
|
||||
|
||||
@@ -3,24 +3,24 @@ package me.chanjar.weixin.common.util.crypto;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ByteGroup {
|
||||
ArrayList<Byte> byteContainer = new ArrayList<Byte>();
|
||||
ArrayList<Byte> byteContainer = new ArrayList<Byte>();
|
||||
|
||||
public byte[] toBytes() {
|
||||
byte[] bytes = new byte[byteContainer.size()];
|
||||
for (int i = 0; i < byteContainer.size(); i++) {
|
||||
bytes[i] = byteContainer.get(i);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
byte[] bytes = new byte[byteContainer.size()];
|
||||
for (int i = 0; i < byteContainer.size(); i++) {
|
||||
bytes[i] = byteContainer.get(i);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public ByteGroup addBytes(byte[] bytes) {
|
||||
for (byte b : bytes) {
|
||||
byteContainer.add(b);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public ByteGroup addBytes(byte[] bytes) {
|
||||
for (byte b : bytes) {
|
||||
byteContainer.add(b);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return byteContainer.size();
|
||||
}
|
||||
public int size() {
|
||||
return byteContainer.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 对公众平台发送给公众账号的消息加解密示例代码.
|
||||
*
|
||||
*
|
||||
* @copyright Copyright (c) 1998-2014 Tencent Inc.
|
||||
*/
|
||||
|
||||
@@ -16,53 +16,53 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class PKCS7Encoder {
|
||||
|
||||
private static final Charset CHARSET = Charset.forName("utf-8");
|
||||
private static final int BLOCK_SIZE = 32;
|
||||
private static final Charset CHARSET = Charset.forName("utf-8");
|
||||
private static final int BLOCK_SIZE = 32;
|
||||
|
||||
/**
|
||||
* 获得对明文进行补位填充的字节.
|
||||
*
|
||||
* @param count 需要进行填充补位操作的明文字节个数
|
||||
* @return 补齐用的字节数组
|
||||
*/
|
||||
public static byte[] encode(int count) {
|
||||
// 计算需要填充的位数
|
||||
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
|
||||
if (amountToPad == 0) {
|
||||
amountToPad = BLOCK_SIZE;
|
||||
}
|
||||
// 获得补位所用的字符
|
||||
char padChr = chr(amountToPad);
|
||||
String tmp = new String();
|
||||
for (int index = 0; index < amountToPad; index++) {
|
||||
tmp += padChr;
|
||||
}
|
||||
return tmp.getBytes(CHARSET);
|
||||
}
|
||||
/**
|
||||
* 获得对明文进行补位填充的字节.
|
||||
*
|
||||
* @param count 需要进行填充补位操作的明文字节个数
|
||||
* @return 补齐用的字节数组
|
||||
*/
|
||||
public static byte[] encode(int count) {
|
||||
// 计算需要填充的位数
|
||||
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
|
||||
if (amountToPad == 0) {
|
||||
amountToPad = BLOCK_SIZE;
|
||||
}
|
||||
// 获得补位所用的字符
|
||||
char padChr = chr(amountToPad);
|
||||
String tmp = new String();
|
||||
for (int index = 0; index < amountToPad; index++) {
|
||||
tmp += padChr;
|
||||
}
|
||||
return tmp.getBytes(CHARSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除解密后明文的补位字符
|
||||
*
|
||||
* @param decrypted 解密后的明文
|
||||
* @return 删除补位字符后的明文
|
||||
*/
|
||||
public static byte[] decode(byte[] decrypted) {
|
||||
int pad = (int) decrypted[decrypted.length - 1];
|
||||
if (pad < 1 || pad > 32) {
|
||||
pad = 0;
|
||||
}
|
||||
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
|
||||
}
|
||||
/**
|
||||
* 删除解密后明文的补位字符
|
||||
*
|
||||
* @param decrypted 解密后的明文
|
||||
* @return 删除补位字符后的明文
|
||||
*/
|
||||
public static byte[] decode(byte[] decrypted) {
|
||||
int pad = (int) decrypted[decrypted.length - 1];
|
||||
if (pad < 1 || pad > 32) {
|
||||
pad = 0;
|
||||
}
|
||||
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
|
||||
*
|
||||
* @param a 需要转化的数字
|
||||
* @return 转化得到的字符
|
||||
*/
|
||||
public static char chr(int a) {
|
||||
byte target = (byte) (a & 0xFF);
|
||||
return (char) target;
|
||||
}
|
||||
/**
|
||||
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
|
||||
*
|
||||
* @param a 需要转化的数字
|
||||
* @return 转化得到的字符
|
||||
*/
|
||||
public static char chr(int a) {
|
||||
byte target = (byte) (a & 0xFF);
|
||||
return (char) target;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
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.
|
||||
*/
|
||||
@@ -37,4 +37,4 @@ public class SHA1 {
|
||||
}
|
||||
return DigestUtils.sha1Hex(sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
* 对公众平台发送给公众账号的消息加解密示例代码.
|
||||
*
|
||||
* @copyright Copyright (c) 1998-2014 Tencent Inc.
|
||||
* <p>
|
||||
* 针对org.apache.commons.codec.binary.Base64,
|
||||
* 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
|
||||
* 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -62,12 +66,51 @@ public class WxCryptUtil {
|
||||
* @param appidOrCorpid 公众平台appid/corpid
|
||||
*/
|
||||
public WxCryptUtil(String token, String encodingAesKey,
|
||||
String appidOrCorpid) {
|
||||
String appidOrCorpid) {
|
||||
this.token = token;
|
||||
this.appidOrCorpid = appidOrCorpid;
|
||||
this.aesKey = Base64.decodeBase64(encodingAesKey + "=");
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信公众号支付签名算法(详见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3)
|
||||
* @param packageParams 原始参数
|
||||
* @param signKey 加密Key(即 商户Key)
|
||||
* @return 签名字符串
|
||||
*/
|
||||
public static String createSign(Map<String, String> packageParams,
|
||||
String signKey) {
|
||||
SortedMap<String, String> sortedMap = new TreeMap<String, String>();
|
||||
sortedMap.putAll(packageParams);
|
||||
|
||||
List<String> keys = new ArrayList<String>(packageParams.keySet());
|
||||
Collections.sort(keys);
|
||||
|
||||
StringBuffer toSign = new StringBuffer();
|
||||
for (String key : keys) {
|
||||
String value = packageParams.get(key);
|
||||
if (null != value && !"".equals(value) && !"sign".equals(key)
|
||||
&& !"key".equals(key)) {
|
||||
toSign.append(key + "=" + value + "&");
|
||||
}
|
||||
}
|
||||
toSign.append("key=" + signKey);
|
||||
String sign = DigestUtils.md5Hex(toSign.toString()).toUpperCase();
|
||||
return sign;
|
||||
}
|
||||
|
||||
static String extractEncryptPart(String xml) {
|
||||
try {
|
||||
DocumentBuilder db = builderLocal.get();
|
||||
Document document = db.parse(new InputSource(new StringReader(xml)));
|
||||
|
||||
Element root = document.getDocumentElement();
|
||||
return root.getElementsByTagName("Encrypt").item(0).getTextContent();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将公众平台回复用户的消息加密打包.
|
||||
* <ol>
|
||||
@@ -107,7 +150,7 @@ public class WxCryptUtil {
|
||||
byte[] randomStringBytes = randomStr.getBytes(CHARSET);
|
||||
byte[] plainTextBytes = plainText.getBytes(CHARSET);
|
||||
byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder(
|
||||
plainTextBytes.length);
|
||||
plainTextBytes.length);
|
||||
byte[] appIdBytes = appidOrCorpid.getBytes(CHARSET);
|
||||
|
||||
// randomStr + networkBytesOrder + text + appid
|
||||
@@ -157,7 +200,7 @@ public class WxCryptUtil {
|
||||
* @return 解密后的原文
|
||||
*/
|
||||
public String decrypt(String msgSignature, String timeStamp, String nonce,
|
||||
String encryptedXml) {
|
||||
String encryptedXml) {
|
||||
// 密钥,公众账号的app corpSecret
|
||||
// 提取密文
|
||||
String cipherText = extractEncryptPart(encryptedXml);
|
||||
@@ -190,7 +233,7 @@ public class WxCryptUtil {
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
|
||||
IvParameterSpec iv = new IvParameterSpec(
|
||||
Arrays.copyOfRange(aesKey, 0, 16));
|
||||
Arrays.copyOfRange(aesKey, 0, 16));
|
||||
cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
|
||||
|
||||
// 使用BASE64对密文进行解码
|
||||
@@ -213,9 +256,9 @@ public class WxCryptUtil {
|
||||
int xmlLength = bytesNetworkOrder2Number(networkOrder);
|
||||
|
||||
xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength),
|
||||
CHARSET);
|
||||
CHARSET);
|
||||
from_appid = new String(
|
||||
Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
|
||||
Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -229,33 +272,6 @@ public class WxCryptUtil {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信公众号支付签名算法(详见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3)
|
||||
* @param packageParams 原始参数
|
||||
* @param signKey 加密Key(即 商户Key)
|
||||
* @return 签名字符串
|
||||
*/
|
||||
public static String createSign(Map<String, String> packageParams,
|
||||
String signKey) {
|
||||
SortedMap<String, String> sortedMap = new TreeMap<String, String>();
|
||||
sortedMap.putAll(packageParams);
|
||||
|
||||
List<String> keys = new ArrayList<String>(packageParams.keySet());
|
||||
Collections.sort(keys);
|
||||
|
||||
StringBuffer toSign = new StringBuffer();
|
||||
for (String key : keys) {
|
||||
String value = packageParams.get(key);
|
||||
if (null != value && !"".equals(value) && !"sign".equals(key)
|
||||
&& !"key".equals(key)) {
|
||||
toSign.append(key + "=" + value + "&");
|
||||
}
|
||||
}
|
||||
toSign.append("key=" + signKey);
|
||||
String sign = DigestUtils.md5Hex(toSign.toString()).toUpperCase();
|
||||
return sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个数字转换成生成4个字节的网络字节序bytes数组
|
||||
*
|
||||
@@ -308,24 +324,12 @@ public class WxCryptUtil {
|
||||
* @return 生成的xml字符串
|
||||
*/
|
||||
private String generateXml(String encrypt, String signature, String timestamp,
|
||||
String nonce) {
|
||||
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"
|
||||
+ "</xml>";
|
||||
+ "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
|
||||
+ "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n"
|
||||
+ "</xml>";
|
||||
return String.format(format, encrypt, signature, timestamp, nonce);
|
||||
}
|
||||
|
||||
static String extractEncryptPart(String xml) {
|
||||
try {
|
||||
DocumentBuilder db = builderLocal.get();
|
||||
Document document = db.parse(new InputSource(new StringReader(xml)));
|
||||
|
||||
Element root = document.getDocumentElement();
|
||||
return root.getElementsByTagName("Encrypt").item(0).getTextContent();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,17 +10,18 @@ public class FileUtils {
|
||||
|
||||
/**
|
||||
* 创建临时文件
|
||||
*
|
||||
* @param inputStream
|
||||
* @param name 文件名
|
||||
* @param ext 扩展名
|
||||
* @param tmpDirFile 临时文件夹目录
|
||||
* @param name 文件名
|
||||
* @param ext 扩展名
|
||||
* @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);
|
||||
tmpFile = File.createTempFile(name, '.' + ext);
|
||||
} else {
|
||||
tmpFile = File.createTempFile(name, '.' + ext, tmpDirFile);
|
||||
}
|
||||
@@ -51,12 +52,13 @@ public class FileUtils {
|
||||
|
||||
/**
|
||||
* 创建临时文件
|
||||
*
|
||||
* @param inputStream
|
||||
* @param name 文件名
|
||||
* @param ext 扩展名
|
||||
* @param name 文件名
|
||||
* @param ext 扩展名
|
||||
*/
|
||||
public static File createTmpFile(InputStream inputStream, String name, String ext) throws IOException {
|
||||
return createTmpFile(inputStream, name, ext, null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,36 +10,42 @@ public interface ApacheHttpClientBuilder {
|
||||
|
||||
/**
|
||||
* 构建httpclient实例
|
||||
*
|
||||
* @return new instance of CloseableHttpClient
|
||||
*/
|
||||
CloseableHttpClient build();
|
||||
|
||||
/**
|
||||
* 代理服务器地址
|
||||
*
|
||||
* @param httpProxyHost
|
||||
*/
|
||||
ApacheHttpClientBuilder httpProxyHost(String httpProxyHost);
|
||||
|
||||
/**
|
||||
* 代理服务器端口
|
||||
*
|
||||
* @param httpProxyPort
|
||||
*/
|
||||
ApacheHttpClientBuilder httpProxyPort(int httpProxyPort);
|
||||
|
||||
/**
|
||||
* 代理服务器用户名
|
||||
*
|
||||
* @param httpProxyUsername
|
||||
*/
|
||||
ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername);
|
||||
|
||||
/**
|
||||
* 代理服务器密码
|
||||
*
|
||||
* @param httpProxyPassword
|
||||
*/
|
||||
ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword);
|
||||
|
||||
/**
|
||||
* ssl连接socket工厂
|
||||
*
|
||||
* @param sslConnectionSocketFactory
|
||||
*/
|
||||
ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory);
|
||||
|
||||
@@ -94,7 +94,7 @@ public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuild
|
||||
return this;
|
||||
}
|
||||
|
||||
public ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory){
|
||||
public ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory) {
|
||||
this.sslConnectionSocketFactory = sslConnectionSocketFactory;
|
||||
return this;
|
||||
}
|
||||
@@ -103,18 +103,18 @@ public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuild
|
||||
return idleConnectionMonitorThread;
|
||||
}
|
||||
|
||||
private void prepare(){
|
||||
private void prepare() {
|
||||
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", plainConnectionSocketFactory)
|
||||
.register("https", sslConnectionSocketFactory)
|
||||
.build();
|
||||
.register("http", plainConnectionSocketFactory)
|
||||
.register("https", sslConnectionSocketFactory)
|
||||
.build();
|
||||
connectionManager = new PoolingHttpClientConnectionManager(registry);
|
||||
connectionManager.setMaxTotal(maxTotalConn);
|
||||
connectionManager.setDefaultMaxPerRoute(maxConnPerHost);
|
||||
connectionManager.setDefaultSocketConfig(
|
||||
SocketConfig.copy(SocketConfig.DEFAULT)
|
||||
.setSoTimeout(soTimeout)
|
||||
.build()
|
||||
SocketConfig.copy(SocketConfig.DEFAULT)
|
||||
.setSoTimeout(soTimeout)
|
||||
.build()
|
||||
);
|
||||
|
||||
idleConnectionMonitorThread = new IdleConnectionMonitorThread(connectionManager, idleConnTimeout, checkWaitTime);
|
||||
@@ -122,22 +122,22 @@ public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuild
|
||||
idleConnectionMonitorThread.start();
|
||||
|
||||
httpClientBuilder = HttpClients.custom()
|
||||
.setConnectionManager(connectionManager)
|
||||
.setDefaultRequestConfig(
|
||||
RequestConfig.custom()
|
||||
.setSocketTimeout(soTimeout)
|
||||
.setConnectTimeout(connectionTimeout)
|
||||
.setConnectionRequestTimeout(connectionRequestTimeout)
|
||||
.build()
|
||||
)
|
||||
.setRetryHandler(httpRequestRetryHandler);
|
||||
.setConnectionManager(connectionManager)
|
||||
.setDefaultRequestConfig(
|
||||
RequestConfig.custom()
|
||||
.setSocketTimeout(soTimeout)
|
||||
.setConnectTimeout(connectionTimeout)
|
||||
.setConnectionRequestTimeout(connectionRequestTimeout)
|
||||
.build()
|
||||
)
|
||||
.setRetryHandler(httpRequestRetryHandler);
|
||||
|
||||
if (StringUtils.isNotBlank(httpProxyHost) && StringUtils.isNotBlank(httpProxyUsername)) {
|
||||
// 使用代理服务器 需要用户认证的代理服务器
|
||||
CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
||||
credsProvider.setCredentials(
|
||||
new AuthScope(httpProxyHost, httpProxyPort),
|
||||
new UsernamePasswordCredentials(httpProxyUsername, httpProxyPassword));
|
||||
new AuthScope(httpProxyHost, httpProxyPort),
|
||||
new UsernamePasswordCredentials(httpProxyUsername, httpProxyPassword));
|
||||
httpClientBuilder.setDefaultCredentialsProvider(credsProvider);
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuild
|
||||
}
|
||||
|
||||
public CloseableHttpClient build() {
|
||||
if(!prepared){
|
||||
if (!prepared) {
|
||||
prepare();
|
||||
prepared = true;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package me.chanjar.weixin.common.util.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.StatusLine;
|
||||
@@ -10,10 +7,13 @@ import org.apache.http.client.HttpResponseException;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class InputStreamResponseHandler implements ResponseHandler<InputStream> {
|
||||
|
||||
public static final ResponseHandler<InputStream> INSTANCE = new InputStreamResponseHandler();
|
||||
|
||||
|
||||
public InputStream handleResponse(final HttpResponse response) throws IOException {
|
||||
final StatusLine statusLine = response.getStatusLine();
|
||||
final HttpEntity entity = response.getEntity();
|
||||
|
||||
@@ -18,39 +18,39 @@ import java.io.IOException;
|
||||
*/
|
||||
public class JoddGetRequestExecutor implements RequestExecutor<String, String> {
|
||||
|
||||
@Override
|
||||
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
|
||||
String queryParam) throws WxErrorException, IOException {
|
||||
if (queryParam != null) {
|
||||
if (uri.indexOf('?') == -1) {
|
||||
uri += '?';
|
||||
}
|
||||
uri += uri.endsWith("?") ? queryParam : '&' + queryParam;
|
||||
}
|
||||
|
||||
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
|
||||
|
||||
if (httpProxy != null) {
|
||||
ProxyInfo proxyInfoObj = new ProxyInfo(
|
||||
ProxyInfo.ProxyType.HTTP,
|
||||
httpProxy.getHostName(),
|
||||
httpProxy.getPort(), "", "");
|
||||
provider.useProxy(proxyInfoObj);
|
||||
}
|
||||
|
||||
HttpRequest request = HttpRequest.get(uri);
|
||||
request.method("GET");
|
||||
request.charset("UTF-8");
|
||||
|
||||
HttpResponse response = request.open(provider).send();
|
||||
response.charset("UTF-8");
|
||||
String result = response.bodyText();
|
||||
|
||||
WxError error = WxError.fromJson(result);
|
||||
if (error.getErrorCode() != 0) {
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
return result;
|
||||
@Override
|
||||
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
|
||||
String queryParam) throws WxErrorException, IOException {
|
||||
if (queryParam != null) {
|
||||
if (uri.indexOf('?') == -1) {
|
||||
uri += '?';
|
||||
}
|
||||
uri += uri.endsWith("?") ? queryParam : '&' + queryParam;
|
||||
}
|
||||
|
||||
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
|
||||
|
||||
if (httpProxy != null) {
|
||||
ProxyInfo proxyInfoObj = new ProxyInfo(
|
||||
ProxyInfo.ProxyType.HTTP,
|
||||
httpProxy.getHostName(),
|
||||
httpProxy.getPort(), "", "");
|
||||
provider.useProxy(proxyInfoObj);
|
||||
}
|
||||
|
||||
HttpRequest request = HttpRequest.get(uri);
|
||||
request.method("GET");
|
||||
request.charset("UTF-8");
|
||||
|
||||
HttpResponse response = request.open(provider).send();
|
||||
response.charset("UTF-8");
|
||||
String result = response.bodyText();
|
||||
|
||||
WxError error = WxError.fromJson(result);
|
||||
if (error.getErrorCode() != 0) {
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,33 +18,33 @@ import java.io.IOException;
|
||||
*/
|
||||
public class JoddPostRequestExecutor implements RequestExecutor<String, String> {
|
||||
|
||||
@Override
|
||||
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
|
||||
String postEntity) throws WxErrorException, IOException {
|
||||
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
|
||||
@Override
|
||||
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
|
||||
String postEntity) throws WxErrorException, IOException {
|
||||
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
|
||||
|
||||
if (httpProxy != null) {
|
||||
ProxyInfo proxyInfoObj = new ProxyInfo(
|
||||
ProxyInfo.ProxyType.HTTP,
|
||||
httpProxy.getAddress().getHostAddress(),
|
||||
httpProxy.getPort(), "", "");
|
||||
provider.useProxy(proxyInfoObj);
|
||||
}
|
||||
|
||||
HttpRequest request = HttpRequest.get(uri);
|
||||
request.method("POST");
|
||||
request.charset("UTF-8");
|
||||
request.bodyText(postEntity);
|
||||
|
||||
HttpResponse response = request.open(provider).send();
|
||||
response.charset("UTF-8");
|
||||
String result = response.bodyText();
|
||||
|
||||
WxError error = WxError.fromJson(result);
|
||||
if (error.getErrorCode() != 0) {
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
return result;
|
||||
if (httpProxy != null) {
|
||||
ProxyInfo proxyInfoObj = new ProxyInfo(
|
||||
ProxyInfo.ProxyType.HTTP,
|
||||
httpProxy.getAddress().getHostAddress(),
|
||||
httpProxy.getPort(), "", "");
|
||||
provider.useProxy(proxyInfoObj);
|
||||
}
|
||||
|
||||
HttpRequest request = HttpRequest.get(uri);
|
||||
request.method("POST");
|
||||
request.charset("UTF-8");
|
||||
request.bodyText(postEntity);
|
||||
|
||||
HttpResponse response = request.open(provider).send();
|
||||
response.charset("UTF-8");
|
||||
String result = response.bodyText();
|
||||
|
||||
WxError error = WxError.fromJson(result);
|
||||
if (error.getErrorCode() != 0) {
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import me.chanjar.weixin.common.util.StringUtils;
|
||||
import me.chanjar.weixin.common.util.fs.FileUtils;
|
||||
import org.apache.http.Header;
|
||||
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;
|
||||
@@ -21,11 +20,11 @@ import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File
|
||||
* @author Daniel Qian
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*/
|
||||
public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> {
|
||||
|
||||
|
||||
private File tmpDirFile;
|
||||
|
||||
public MediaDownloadRequestExecutor() {
|
||||
@@ -36,7 +35,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin
|
||||
super();
|
||||
this.tmpDirFile = tmpDirFile;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException {
|
||||
@@ -46,7 +45,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin
|
||||
}
|
||||
uri += uri.endsWith("?") ? queryParam : '&' + queryParam;
|
||||
}
|
||||
|
||||
|
||||
HttpGet httpGet = new HttpGet(uri);
|
||||
if (httpProxy != null) {
|
||||
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
|
||||
@@ -74,7 +73,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin
|
||||
File localFile = FileUtils.createTmpFile(inputStream, name_ext[0], name_ext[1], tmpDirFile);
|
||||
return localFile;
|
||||
|
||||
}finally {
|
||||
} finally {
|
||||
httpGet.releaseConnection();
|
||||
}
|
||||
|
||||
@@ -88,5 +87,5 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin
|
||||
String fileName = m.group(1);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import org.apache.http.HttpEntity;
|
||||
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.HttpPost;
|
||||
@@ -19,8 +18,8 @@ import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 上传媒体文件请求执行器,请求的参数是File, 返回的结果是String
|
||||
* @author Daniel Qian
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*/
|
||||
public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, File> {
|
||||
|
||||
@@ -33,10 +32,10 @@ public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUpload
|
||||
}
|
||||
if (file != null) {
|
||||
HttpEntity entity = MultipartEntityBuilder
|
||||
.create()
|
||||
.addBinaryBody("media", file)
|
||||
.setMode(HttpMultipartMode.RFC6532)
|
||||
.build();
|
||||
.create()
|
||||
.addBinaryBody("media", file)
|
||||
.setMode(HttpMultipartMode.RFC6532)
|
||||
.build();
|
||||
httpPost.setEntity(entity);
|
||||
httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString());
|
||||
}
|
||||
@@ -47,7 +46,7 @@ public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUpload
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
return WxMediaUploadResult.fromJson(responseContent);
|
||||
}finally {
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package me.chanjar.weixin.common.util.http;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* http请求执行器
|
||||
@@ -17,11 +16,10 @@ import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
public interface RequestExecutor<T, E> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param httpclient 传入的httpClient
|
||||
* @param httpProxy http代理对象,如果没有配置代理则为空
|
||||
* @param uri uri
|
||||
* @param data 数据
|
||||
* @param httpProxy http代理对象,如果没有配置代理则为空
|
||||
* @param uri uri
|
||||
* @param data 数据
|
||||
* @throws WxErrorException
|
||||
* @throws ClientProtocolException
|
||||
* @throws IOException
|
||||
|
||||
@@ -3,7 +3,6 @@ package me.chanjar.weixin.common.util.http;
|
||||
import me.chanjar.weixin.common.bean.result.WxError;
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
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;
|
||||
@@ -13,8 +12,8 @@ import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 简单的GET请求执行器,请求的参数是String, 返回的结果也是String
|
||||
* @author Daniel Qian
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*/
|
||||
public class SimpleGetRequestExecutor implements RequestExecutor<String, String> {
|
||||
|
||||
@@ -39,7 +38,7 @@ public class SimpleGetRequestExecutor implements RequestExecutor<String, String>
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
return responseContent;
|
||||
}finally {
|
||||
} finally {
|
||||
httpGet.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import me.chanjar.weixin.common.bean.result.WxError;
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import org.apache.http.Consts;
|
||||
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.HttpPost;
|
||||
@@ -15,8 +14,8 @@ import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 简单的POST请求执行器,请求的参数是String, 返回的结果也是String
|
||||
* @author Daniel Qian
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*/
|
||||
public class SimplePostRequestExecutor implements RequestExecutor<String, String> {
|
||||
|
||||
@@ -40,7 +39,7 @@ public class SimplePostRequestExecutor implements RequestExecutor<String, String
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
return responseContent;
|
||||
}finally {
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package me.chanjar.weixin.common.util.http;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
@@ -10,15 +8,17 @@ import org.apache.http.client.HttpResponseException;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* copy from {@link org.apache.http.impl.client.BasicResponseHandler}
|
||||
* @author Daniel Qian
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*/
|
||||
public class Utf8ResponseHandler implements ResponseHandler<String> {
|
||||
|
||||
public static final ResponseHandler<String> INSTANCE = new Utf8ResponseHandler();
|
||||
|
||||
|
||||
public String handleResponse(final HttpResponse response) throws IOException {
|
||||
final StatusLine statusLine = response.getStatusLine();
|
||||
final HttpEntity entity = response.getEntity();
|
||||
|
||||
@@ -15,101 +15,101 @@ import com.google.gson.JsonObject;
|
||||
|
||||
public class GsonHelper {
|
||||
|
||||
public static boolean isNull(JsonElement element) {
|
||||
return element == null || element.isJsonNull();
|
||||
}
|
||||
|
||||
public static boolean isNotNull(JsonElement element) {
|
||||
return !isNull(element);
|
||||
}
|
||||
|
||||
public static Long getLong(JsonObject json, String property) {
|
||||
return getAsLong(json.get(property));
|
||||
}
|
||||
|
||||
public static long getPrimitiveLong(JsonObject json, String property) {
|
||||
return getAsPrimitiveLong(json.get(property));
|
||||
}
|
||||
public static boolean isNull(JsonElement element) {
|
||||
return element == null || element.isJsonNull();
|
||||
}
|
||||
|
||||
public static Integer getInteger(JsonObject json, String property) {
|
||||
return getAsInteger(json.get(property));
|
||||
}
|
||||
public static boolean isNotNull(JsonElement element) {
|
||||
return !isNull(element);
|
||||
}
|
||||
|
||||
public static int getPrimitiveInteger(JsonObject json, String property) {
|
||||
return getAsPrimitiveInt(json.get(property));
|
||||
}
|
||||
|
||||
public static Double getDouble(JsonObject json, String property) {
|
||||
return getAsDouble(json.get(property));
|
||||
}
|
||||
|
||||
public static double getPrimitiveDouble(JsonObject json, String property) {
|
||||
return getAsPrimitiveDouble(json.get(property));
|
||||
}
|
||||
|
||||
public static Float getFloat(JsonObject json, String property) {
|
||||
return getAsFloat(json.get(property));
|
||||
}
|
||||
|
||||
public static float getPrimitiveFloat(JsonObject json, String property) {
|
||||
return getAsPrimitiveFloat(json.get(property));
|
||||
}
|
||||
|
||||
public static Boolean getBoolean(JsonObject json, String property) {
|
||||
return getAsBoolean(json.get(property));
|
||||
}
|
||||
public static Long getLong(JsonObject json, String property) {
|
||||
return getAsLong(json.get(property));
|
||||
}
|
||||
|
||||
public static long getPrimitiveLong(JsonObject json, String property) {
|
||||
return getAsPrimitiveLong(json.get(property));
|
||||
}
|
||||
|
||||
public static Integer getInteger(JsonObject json, String property) {
|
||||
return getAsInteger(json.get(property));
|
||||
}
|
||||
|
||||
public static int getPrimitiveInteger(JsonObject json, String property) {
|
||||
return getAsPrimitiveInt(json.get(property));
|
||||
}
|
||||
|
||||
public static Double getDouble(JsonObject json, String property) {
|
||||
return getAsDouble(json.get(property));
|
||||
}
|
||||
|
||||
public static double getPrimitiveDouble(JsonObject json, String property) {
|
||||
return getAsPrimitiveDouble(json.get(property));
|
||||
}
|
||||
|
||||
public static Float getFloat(JsonObject json, String property) {
|
||||
return getAsFloat(json.get(property));
|
||||
}
|
||||
|
||||
public static float getPrimitiveFloat(JsonObject json, String property) {
|
||||
return getAsPrimitiveFloat(json.get(property));
|
||||
}
|
||||
|
||||
public static Boolean getBoolean(JsonObject json, String property) {
|
||||
return getAsBoolean(json.get(property));
|
||||
}
|
||||
|
||||
public static String getString(JsonObject json, String property) {
|
||||
return getAsString(json.get(property));
|
||||
}
|
||||
|
||||
public static String getAsString(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsString();
|
||||
}
|
||||
|
||||
public static Long getAsLong(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsLong();
|
||||
}
|
||||
|
||||
public static long getAsPrimitiveLong(JsonElement element) {
|
||||
Long r = getAsLong(element);
|
||||
return r == null ? 0l : r;
|
||||
}
|
||||
|
||||
public static Integer getAsInteger(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsInt();
|
||||
}
|
||||
|
||||
public static int getAsPrimitiveInt(JsonElement element) {
|
||||
Integer r = getAsInteger(element);
|
||||
return r == null ? 0 : r;
|
||||
}
|
||||
|
||||
public static Boolean getAsBoolean(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsBoolean();
|
||||
}
|
||||
|
||||
public static boolean getAsPrimitiveBool(JsonElement element) {
|
||||
Boolean r = getAsBoolean(element);
|
||||
return r != null && r.booleanValue();
|
||||
}
|
||||
|
||||
public static Double getAsDouble(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsDouble();
|
||||
}
|
||||
|
||||
public static double getAsPrimitiveDouble(JsonElement element) {
|
||||
Double r = getAsDouble(element);
|
||||
return r == null ? 0d : r;
|
||||
}
|
||||
|
||||
public static Float getAsFloat(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsFloat();
|
||||
}
|
||||
|
||||
public static float getAsPrimitiveFloat(JsonElement element) {
|
||||
Float r = getAsFloat(element);
|
||||
return r == null ? 0f : r;
|
||||
}
|
||||
|
||||
public static String getString(JsonObject json, String property) {
|
||||
return getAsString(json.get(property));
|
||||
}
|
||||
|
||||
public static String getAsString(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsString();
|
||||
}
|
||||
|
||||
public static Long getAsLong(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsLong();
|
||||
}
|
||||
|
||||
public static long getAsPrimitiveLong(JsonElement element) {
|
||||
Long r = getAsLong(element);
|
||||
return r == null ? 0l : r;
|
||||
}
|
||||
|
||||
public static Integer getAsInteger(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsInt();
|
||||
}
|
||||
|
||||
public static int getAsPrimitiveInt(JsonElement element) {
|
||||
Integer r = getAsInteger(element);
|
||||
return r == null ? 0 : r;
|
||||
}
|
||||
|
||||
public static Boolean getAsBoolean(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsBoolean();
|
||||
}
|
||||
|
||||
public static boolean getAsPrimitiveBool(JsonElement element) {
|
||||
Boolean r = getAsBoolean(element);
|
||||
return r != null && r.booleanValue();
|
||||
}
|
||||
|
||||
public static Double getAsDouble(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsDouble();
|
||||
}
|
||||
|
||||
public static double getAsPrimitiveDouble(JsonElement element) {
|
||||
Double r = getAsDouble(element);
|
||||
return r == null ? 0d : r;
|
||||
}
|
||||
|
||||
public static Float getAsFloat(JsonElement element) {
|
||||
return isNull(element) ? null : element.getAsFloat();
|
||||
}
|
||||
|
||||
public static float getAsPrimitiveFloat(JsonElement element) {
|
||||
Float r = getAsFloat(element);
|
||||
return r == null ? 0f : r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*
|
||||
*/
|
||||
public class WxAccessTokenAdapter implements JsonDeserializer<WxAccessToken> {
|
||||
|
||||
@@ -32,5 +30,5 @@ public class WxAccessTokenAdapter implements JsonDeserializer<WxAccessToken> {
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ import me.chanjar.weixin.common.bean.result.WxError;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*
|
||||
*/
|
||||
public class WxErrorAdapter implements JsonDeserializer<WxError> {
|
||||
|
||||
@@ -33,5 +31,5 @@ public class WxErrorAdapter implements JsonDeserializer<WxError> {
|
||||
wxError.setJson(json.toString());
|
||||
return wxError;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package me.chanjar.weixin.common.util.json;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.bean.WxMenu;
|
||||
import me.chanjar.weixin.common.bean.result.WxError;
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
|
||||
|
||||
public class WxGsonBuilder {
|
||||
|
||||
@@ -14,9 +14,7 @@ import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*
|
||||
*/
|
||||
public class WxMediaUploadResultAdapter implements JsonDeserializer<WxMediaUploadResult> {
|
||||
|
||||
@@ -38,5 +36,5 @@ public class WxMediaUploadResultAdapter implements JsonDeserializer<WxMediaUploa
|
||||
}
|
||||
return uploadResult;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,22 +8,13 @@
|
||||
*/
|
||||
package me.chanjar.weixin.common.util.json;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
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 com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.*;
|
||||
import me.chanjar.weixin.common.bean.WxMenu;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Daniel Qian
|
||||
*
|
||||
*/
|
||||
public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializer<WxMenu> {
|
||||
|
||||
@@ -36,11 +27,11 @@ public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializ
|
||||
buttonArray.add(buttonJson);
|
||||
}
|
||||
json.add("button", buttonArray);
|
||||
|
||||
|
||||
if (menu.getMatchRule() != null) {
|
||||
json.add("matchrule", convertToJson(menu.getMatchRule()));
|
||||
}
|
||||
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -60,15 +51,15 @@ public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializ
|
||||
return buttonJson;
|
||||
}
|
||||
|
||||
protected JsonObject convertToJson(WxMenu.WxMenuRule menuRule){
|
||||
protected JsonObject convertToJson(WxMenu.WxMenuRule menuRule) {
|
||||
JsonObject matchRule = new JsonObject();
|
||||
matchRule.addProperty("tag_id",menuRule.getTagId());
|
||||
matchRule.addProperty("sex",menuRule.getSex());
|
||||
matchRule.addProperty("country",menuRule.getCountry());
|
||||
matchRule.addProperty("province",menuRule.getProvince());
|
||||
matchRule.addProperty("city",menuRule.getCity());
|
||||
matchRule.addProperty("client_platform_type",menuRule.getClientPlatformType());
|
||||
matchRule.addProperty("language",menuRule.getLanguage());
|
||||
matchRule.addProperty("tag_id", menuRule.getTagId());
|
||||
matchRule.addProperty("sex", menuRule.getSex());
|
||||
matchRule.addProperty("country", menuRule.getCountry());
|
||||
matchRule.addProperty("province", menuRule.getProvince());
|
||||
matchRule.addProperty("city", menuRule.getCity());
|
||||
matchRule.addProperty("client_platform_type", menuRule.getClientPlatformType());
|
||||
matchRule.addProperty("language", menuRule.getLanguage());
|
||||
return matchRule;
|
||||
}
|
||||
|
||||
@@ -96,7 +87,7 @@ public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializ
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
protected WxMenu.WxMenuButton convertFromJson(JsonObject json) {
|
||||
WxMenu.WxMenuButton button = new WxMenu.WxMenuButton();
|
||||
button.setName(GsonHelper.getString(json, "name"));
|
||||
|
||||
@@ -18,30 +18,24 @@
|
||||
package me.chanjar.weixin.common.util.res;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An internationalization / localization helper class which reduces
|
||||
* the bother of handling ResourceBundles and takes care of the
|
||||
* common cases of message formating which otherwise require the
|
||||
* creation of Object arrays and such.
|
||||
*
|
||||
* <p>
|
||||
* <p>The StringManager operates on a package basis. One StringManager
|
||||
* per package can be created and accessed via the getManager method
|
||||
* call.
|
||||
*
|
||||
* <p>
|
||||
* <p>The StringManager will look for a ResourceBundle named by
|
||||
* the package name given plus the suffix of "LocalStrings". In
|
||||
* practice, this means that the localized information will be contained
|
||||
* in a LocalStrings.properties file located in the package
|
||||
* directory of the classpath.
|
||||
*
|
||||
* <p>
|
||||
* <p>Please see the documentation for java.util.ResourceBundle for
|
||||
* more information.
|
||||
*
|
||||
@@ -52,152 +46,80 @@ import java.util.ResourceBundle;
|
||||
*/
|
||||
public class StringManager {
|
||||
|
||||
private static int LOCALE_CACHE_SIZE = 10;
|
||||
private static final Map<String, Map<Locale, StringManager>> managers =
|
||||
new Hashtable<String, Map<Locale, StringManager>>();
|
||||
private static int LOCALE_CACHE_SIZE = 10;
|
||||
/**
|
||||
* The ResourceBundle for this StringManager.
|
||||
*/
|
||||
private final ResourceBundle bundle;
|
||||
private final Locale locale;
|
||||
|
||||
/**
|
||||
* The ResourceBundle for this StringManager.
|
||||
*/
|
||||
private final ResourceBundle bundle;
|
||||
private final Locale locale;
|
||||
|
||||
/**
|
||||
* Creates a new StringManager for a given package. This is a
|
||||
* private method and all access to it is arbitrated by the
|
||||
* static getManager method call so that only one StringManager
|
||||
* per package will be created.
|
||||
*
|
||||
* @param packageName Name of package to create StringManager for.
|
||||
*/
|
||||
private StringManager(String packageName, Locale locale) {
|
||||
String bundleName = packageName + ".LocalStrings";
|
||||
ResourceBundle bnd = null;
|
||||
/**
|
||||
* Creates a new StringManager for a given package. This is a
|
||||
* private method and all access to it is arbitrated by the
|
||||
* static getManager method call so that only one StringManager
|
||||
* per package will be created.
|
||||
*
|
||||
* @param packageName Name of package to create StringManager for.
|
||||
*/
|
||||
private StringManager(String packageName, Locale locale) {
|
||||
String bundleName = packageName + ".LocalStrings";
|
||||
ResourceBundle bnd = null;
|
||||
try {
|
||||
bnd = ResourceBundle.getBundle(bundleName, locale);
|
||||
} catch (MissingResourceException ex) {
|
||||
// Try from the current loader (that's the case for trusted apps)
|
||||
// Should only be required if using a TC5 style classloader structure
|
||||
// where common != shared != server
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
if (cl != null) {
|
||||
try {
|
||||
bnd = ResourceBundle.getBundle(bundleName, locale);
|
||||
} catch( MissingResourceException ex ) {
|
||||
// Try from the current loader (that's the case for trusted apps)
|
||||
// Should only be required if using a TC5 style classloader structure
|
||||
// where common != shared != server
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
if( cl != null ) {
|
||||
try {
|
||||
bnd = ResourceBundle.getBundle(bundleName, locale, cl);
|
||||
} catch(MissingResourceException ex2) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
bundle = bnd;
|
||||
// Get the actual locale, which may be different from the requested one
|
||||
if (bundle != null) {
|
||||
Locale bundleLocale = bundle.getLocale();
|
||||
if (bundleLocale.equals(Locale.ROOT)) {
|
||||
this.locale = Locale.ENGLISH;
|
||||
} else {
|
||||
this.locale = bundleLocale;
|
||||
}
|
||||
} else {
|
||||
this.locale = null;
|
||||
bnd = ResourceBundle.getBundle(bundleName, locale, cl);
|
||||
} catch (MissingResourceException ex2) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Get a string from the underlying resource bundle or return
|
||||
null if the String is not found.
|
||||
|
||||
@param key to desired resource String
|
||||
@return resource String matching <i>key</i> from underlying
|
||||
bundle or null if not found.
|
||||
@throws IllegalArgumentException if <i>key</i> is null.
|
||||
*/
|
||||
public String getString(String key) {
|
||||
if(key == null){
|
||||
String msg = "key may not have a null value";
|
||||
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
String str = null;
|
||||
|
||||
try {
|
||||
// Avoid NPE if bundle is null and treat it like an MRE
|
||||
if (bundle != null) {
|
||||
str = bundle.getString(key);
|
||||
}
|
||||
} catch(MissingResourceException mre) {
|
||||
//bad: shouldn't mask an exception the following way:
|
||||
// str = "[cannot find message associated with key '" + key +
|
||||
// "' due to " + mre + "]";
|
||||
// because it hides the fact that the String was missing
|
||||
// from the calling code.
|
||||
//good: could just throw the exception (or wrap it in another)
|
||||
// but that would probably cause much havoc on existing
|
||||
// code.
|
||||
//better: consistent with container pattern to
|
||||
// simply return null. Calling code can then do
|
||||
// a null check.
|
||||
str = null;
|
||||
}
|
||||
|
||||
return str;
|
||||
bundle = bnd;
|
||||
// Get the actual locale, which may be different from the requested one
|
||||
if (bundle != null) {
|
||||
Locale bundleLocale = bundle.getLocale();
|
||||
if (bundleLocale.equals(Locale.ROOT)) {
|
||||
this.locale = Locale.ENGLISH;
|
||||
} else {
|
||||
this.locale = bundleLocale;
|
||||
}
|
||||
} else {
|
||||
this.locale = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from the underlying resource bundle and format
|
||||
* it with the given set of arguments.
|
||||
*
|
||||
* @param key
|
||||
* @param args
|
||||
*/
|
||||
public String getString(final String key, final Object... args) {
|
||||
String value = getString(key);
|
||||
if (value == null) {
|
||||
value = key;
|
||||
}
|
||||
/**
|
||||
* Get the StringManager for a particular package. If a manager for
|
||||
* a package already exists, it will be reused, else a new
|
||||
* StringManager will be created and returned.
|
||||
*
|
||||
* @param packageName The package name
|
||||
*/
|
||||
public static final synchronized StringManager getManager(
|
||||
String packageName) {
|
||||
return getManager(packageName, Locale.getDefault());
|
||||
}
|
||||
|
||||
MessageFormat mf = new MessageFormat(value);
|
||||
mf.setLocale(locale);
|
||||
return mf.format(args, new StringBuffer(), null).toString();
|
||||
}
|
||||
/**
|
||||
* Get the StringManager for a particular package and Locale. If a manager
|
||||
* for a package/Locale combination already exists, it will be reused, else
|
||||
* a new StringManager will be created and returned.
|
||||
*
|
||||
* @param packageName The package name
|
||||
* @param locale The Locale
|
||||
*/
|
||||
public static final synchronized StringManager getManager(
|
||||
String packageName, Locale locale) {
|
||||
|
||||
/**
|
||||
* Identify the Locale this StringManager is associated with
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// STATIC SUPPORT METHODS
|
||||
// --------------------------------------------------------------
|
||||
|
||||
private static final Map<String, Map<Locale,StringManager>> managers =
|
||||
new Hashtable<String, Map<Locale,StringManager>>();
|
||||
|
||||
/**
|
||||
* Get the StringManager for a particular package. If a manager for
|
||||
* a package already exists, it will be reused, else a new
|
||||
* StringManager will be created and returned.
|
||||
*
|
||||
* @param packageName The package name
|
||||
*/
|
||||
public static final synchronized StringManager getManager(
|
||||
String packageName) {
|
||||
return getManager(packageName, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the StringManager for a particular package and Locale. If a manager
|
||||
* for a package/Locale combination already exists, it will be reused, else
|
||||
* a new StringManager will be created and returned.
|
||||
*
|
||||
* @param packageName The package name
|
||||
* @param locale The Locale
|
||||
*/
|
||||
public static final synchronized StringManager getManager(
|
||||
String packageName, Locale locale) {
|
||||
|
||||
Map<Locale,StringManager> map = managers.get(packageName);
|
||||
if (map == null) {
|
||||
Map<Locale, StringManager> map = managers.get(packageName);
|
||||
if (map == null) {
|
||||
/*
|
||||
* Don't want the HashMap to be expanded beyond LOCALE_CACHE_SIZE.
|
||||
* Expansion occurs when size() exceeds capacity. Therefore keep
|
||||
@@ -206,43 +128,113 @@ public class StringManager {
|
||||
* for removal needs to use one less than the maximum desired size
|
||||
*
|
||||
*/
|
||||
map = new LinkedHashMap<Locale,StringManager>(LOCALE_CACHE_SIZE, 1, true) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
protected boolean removeEldestEntry(
|
||||
Map.Entry<Locale,StringManager> eldest) {
|
||||
return size() > (LOCALE_CACHE_SIZE - 1);
|
||||
}
|
||||
};
|
||||
managers.put(packageName, map);
|
||||
}
|
||||
map = new LinkedHashMap<Locale, StringManager>(LOCALE_CACHE_SIZE, 1, true) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
StringManager mgr = map.get(locale);
|
||||
if (mgr == null) {
|
||||
mgr = new StringManager(packageName, locale);
|
||||
map.put(locale, mgr);
|
||||
@Override
|
||||
protected boolean removeEldestEntry(
|
||||
Map.Entry<Locale, StringManager> eldest) {
|
||||
return size() > (LOCALE_CACHE_SIZE - 1);
|
||||
}
|
||||
return mgr;
|
||||
};
|
||||
managers.put(packageName, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the StringManager for a list of Locales. The first StringManager
|
||||
* found will be returned.
|
||||
*
|
||||
* @param requestedLocales the list of Locales
|
||||
*
|
||||
* @return the found StringManager or the default StringManager
|
||||
*/
|
||||
public static StringManager getManager(String packageName,
|
||||
Enumeration<Locale> requestedLocales) {
|
||||
while (requestedLocales.hasMoreElements()) {
|
||||
Locale locale = requestedLocales.nextElement();
|
||||
StringManager result = getManager(packageName, locale);
|
||||
if (result.getLocale().equals(locale)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Return the default
|
||||
return getManager(packageName);
|
||||
StringManager mgr = map.get(locale);
|
||||
if (mgr == null) {
|
||||
mgr = new StringManager(packageName, locale);
|
||||
map.put(locale, mgr);
|
||||
}
|
||||
return mgr;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// STATIC SUPPORT METHODS
|
||||
// --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Retrieve the StringManager for a list of Locales. The first StringManager
|
||||
* found will be returned.
|
||||
*
|
||||
* @param requestedLocales the list of Locales
|
||||
* @return the found StringManager or the default StringManager
|
||||
*/
|
||||
public static StringManager getManager(String packageName,
|
||||
Enumeration<Locale> requestedLocales) {
|
||||
while (requestedLocales.hasMoreElements()) {
|
||||
Locale locale = requestedLocales.nextElement();
|
||||
StringManager result = getManager(packageName, locale);
|
||||
if (result.getLocale().equals(locale)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Return the default
|
||||
return getManager(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from the underlying resource bundle or return
|
||||
* null if the String is not found.
|
||||
*
|
||||
* @param key to desired resource String
|
||||
* @return resource String matching <i>key</i> from underlying
|
||||
* bundle or null if not found.
|
||||
* @throws IllegalArgumentException if <i>key</i> is null.
|
||||
*/
|
||||
public String getString(String key) {
|
||||
if (key == null) {
|
||||
String msg = "key may not have a null value";
|
||||
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
String str = null;
|
||||
|
||||
try {
|
||||
// Avoid NPE if bundle is null and treat it like an MRE
|
||||
if (bundle != null) {
|
||||
str = bundle.getString(key);
|
||||
}
|
||||
} catch (MissingResourceException mre) {
|
||||
//bad: shouldn't mask an exception the following way:
|
||||
// str = "[cannot find message associated with key '" + key +
|
||||
// "' due to " + mre + "]";
|
||||
// because it hides the fact that the String was missing
|
||||
// from the calling code.
|
||||
//good: could just throw the exception (or wrap it in another)
|
||||
// but that would probably cause much havoc on existing
|
||||
// code.
|
||||
//better: consistent with container pattern to
|
||||
// simply return null. Calling code can then do
|
||||
// a null check.
|
||||
str = null;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from the underlying resource bundle and format
|
||||
* it with the given set of arguments.
|
||||
*
|
||||
* @param key
|
||||
* @param args
|
||||
*/
|
||||
public String getString(final String key, final Object... args) {
|
||||
String value = getString(key);
|
||||
if (value == null) {
|
||||
value = key;
|
||||
}
|
||||
|
||||
MessageFormat mf = new MessageFormat(value);
|
||||
mf.setLocale(locale);
|
||||
return mf.format(args, new StringBuffer(), null).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify the Locale this StringManager is associated with
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package me.chanjar.weixin.common.util.xml;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.core.util.QuickWriter;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||
@@ -10,6 +8,8 @@ import com.thoughtworks.xstream.io.xml.XppDriver;
|
||||
import com.thoughtworks.xstream.security.NullPermission;
|
||||
import com.thoughtworks.xstream.security.PrimitiveTypePermission;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
public class XStreamInitializer {
|
||||
|
||||
public static XStream getInstance() {
|
||||
@@ -22,6 +22,7 @@ public class XStreamInitializer {
|
||||
protected String SUFFIX_CDATA = "]]>";
|
||||
protected String PREFIX_MEDIA_ID = "<MediaId>";
|
||||
protected String SUFFIX_MEDIA_ID = "</MediaId>";
|
||||
|
||||
@Override
|
||||
protected void writeText(QuickWriter writer, String text) {
|
||||
if (text.startsWith(PREFIX_CDATA) && text.endsWith(SUFFIX_CDATA)) {
|
||||
|
||||
Reference in New Issue
Block a user