This commit is contained in:
tanghc
2019-02-27 12:37:14 +08:00
parent 85d61d2f1e
commit 46a546f1da
196 changed files with 13210 additions and 47 deletions

102
sop-test/pom.xml Normal file
View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sop-parent</artifactId>
<groupId>com.gitee.sop</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sop-test</artifactId>
<name>sop-test</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

3
sop-test/readme.md Normal file
View File

@@ -0,0 +1,3 @@
# 测试
查看测试用例

View File

@@ -0,0 +1,13 @@
package com.gitee.sop;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}

View File

@@ -0,0 +1,49 @@
/**
* Alipay.com Inc.
* Copyright (c) 2004-2012 All Rights Reserved.
*/
package com.gitee.sop.alipay;
/**
*
* @author runzhi
*/
public class AlipayApiException extends Exception {
private static final long serialVersionUID = -238091758285157331L;
private String errCode;
private String errMsg;
public AlipayApiException() {
super();
}
public AlipayApiException(String message, Throwable cause) {
super(message, cause);
}
public AlipayApiException(String message) {
super(message);
}
public AlipayApiException(Throwable cause) {
super(cause);
}
public AlipayApiException(String errCode, String errMsg) {
super(errCode + ":" + errMsg);
this.errCode = errCode;
this.errMsg = errMsg;
}
public String getErrCode() {
return this.errCode;
}
public String getErrMsg() {
return this.errMsg;
}
}

View File

@@ -0,0 +1,97 @@
/**
* Alipay.com Inc.
* Copyright (c) 2004-2012 All Rights Reserved.
*/
package com.gitee.sop.alipay;
/**
*
* @author runzhi
*/
public class AlipayConstants {
public static final String SIGN_TYPE = "sign_type";
public static final String SIGN_TYPE_RSA = "RSA";
/**
* sha256WithRsa 算法请求类型
*/
public static final String SIGN_TYPE_RSA2 = "RSA2";
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
public static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
public static final String ENCRYPT_TYPE_AES = "AES";
public static final String APP_ID = "app_id";
public static final String FORMAT = "format";
public static final String METHOD = "method";
public static final String TIMESTAMP = "timestamp";
public static final String VERSION = "version";
public static final String SIGN = "sign";
public static final String ALIPAY_SDK = "alipay_sdk";
public static final String ACCESS_TOKEN = "auth_token";
public static final String APP_AUTH_TOKEN = "app_auth_token";
public static final String TERMINAL_TYPE = "terminal_type";
public static final String TERMINAL_INFO = "terminal_info";
public static final String CHARSET = "charset";
public static final String NOTIFY_URL = "notify_url";
public static final String RETURN_URL = "return_url";
public static final String ENCRYPT_TYPE = "encrypt_type";
//-----===-------///
public static final String BIZ_CONTENT_KEY = "biz_content";
/** 默认时间格式 **/
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
/** Date默认时区 **/
public static final String DATE_TIMEZONE = "GMT+8";
/** UTF-8字符集 **/
public static final String CHARSET_UTF8 = "UTF-8";
/** GBK字符集 **/
public static final String CHARSET_GBK = "GBK";
/** JSON 应格式 */
public static final String FORMAT_JSON = "json";
/** XML 应格式 */
public static final String FORMAT_XML = "xml";
/** SDK版本号 */
public static final String SDK_VERSION = "alipay-sdk-java-3.6.0.ALL";
public static final String PROD_CODE = "prod_code";
/** 老版本失败节点 */
public static final String ERROR_RESPONSE = "error_response";
/** 新版本节点后缀 */
public static final String RESPONSE_SUFFIX = "_response";
/** 加密后XML返回报文的节点名字 */
public static final String RESPONSE_XML_ENCRYPT_NODE_NAME = "response_encrypted";
/** 批量请求id **/
public static final String BATCH_REQUEST_ID = "batch_request_id";
}

View File

@@ -0,0 +1,611 @@
/**
* Alipay.com Inc.
* Copyright (c) 2004-2012 All Rights Reserved.
*/
package com.gitee.sop.alipay;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
*
* @author runzhi
*/
public class AlipaySignature {
/** RSA最大加密明文大小 */
private static final int MAX_ENCRYPT_BLOCK = 117;
/** RSA最大解密密文大小 */
private static final int MAX_DECRYPT_BLOCK = 128;
/**
*
* @param sortedParams
* @return
*/
public static String getSignContent(Map<String, String> sortedParams) {
StringBuffer content = new StringBuffer();
List<String> keys = new ArrayList<String>(sortedParams.keySet());
Collections.sort(keys);
int index = 0;
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = sortedParams.get(key);
if (StringUtils.areNotEmpty(key, value)) {
content.append((index == 0 ? "" : "&") + key + "=" + value);
index++;
}
}
return content.toString();
}
/**
* rsa内容签名
*
* @param content
* @param privateKey
* @param charset
* @return
* @throws AlipayApiException
*/
public static String rsaSign(String content, String privateKey, String charset,
String signType) throws AlipayApiException {
if (AlipayConstants.SIGN_TYPE_RSA.equals(signType)) {
return rsaSign(content, privateKey, charset);
} else if (AlipayConstants.SIGN_TYPE_RSA2.equals(signType)) {
return rsa256Sign(content, privateKey, charset);
} else {
throw new AlipayApiException("Sign Type is Not Support : signType=" + signType);
}
}
/**
* sha256WithRsa 加签
*
* @param content
* @param privateKey
* @param charset
* @return
* @throws AlipayApiException
*/
public static String rsa256Sign(String content, String privateKey,
String charset) throws AlipayApiException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(AlipayConstants.SIGN_TYPE_RSA,
new ByteArrayInputStream(privateKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(AlipayConstants.SIGN_SHA256RSA_ALGORITHMS);
signature.initSign(priKey);
if (StringUtils.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed));
} catch (Exception e) {
throw new AlipayApiException("RSAcontent = " + content + "; charset = " + charset, e);
}
}
/**
* sha1WithRsa 加签
*
* @param content
* @param privateKey
* @param charset
* @return
* @throws AlipayApiException
*/
public static String rsaSign(String content, String privateKey,
String charset) throws AlipayApiException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(AlipayConstants.SIGN_TYPE_RSA,
new ByteArrayInputStream(privateKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(AlipayConstants.SIGN_ALGORITHMS);
signature.initSign(priKey);
if (StringUtils.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed));
} catch (InvalidKeySpecException ie) {
throw new AlipayApiException("RSA私钥格式不正确请检查是否正确配置了PKCS8格式的私钥", ie);
} catch (Exception e) {
throw new AlipayApiException("RSAcontent = " + content + "; charset = " + charset, e);
}
}
public static String rsaSign(Map<String, String> params, String privateKey,
String charset) throws AlipayApiException {
String signContent = getSignContent(params);
return rsaSign(signContent, privateKey, charset);
}
public static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
InputStream ins) throws Exception {
if (ins == null || StringUtils.isEmpty(algorithm)) {
return null;
}
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
byte[] encodedKey = StreamUtil.readText(ins).getBytes();
encodedKey = Base64.decodeBase64(encodedKey);
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
}
public static String getSignCheckContentV1(Map<String, String> params) {
if (params == null) {
return null;
}
params.remove("sign");
params.remove("sign_type");
StringBuffer content = new StringBuffer();
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
content.append((i == 0 ? "" : "&") + key + "=" + value);
}
return content.toString();
}
public static String getSignCheckContentV2(Map<String, String> params) {
if (params == null) {
return null;
}
params.remove("sign");
StringBuffer content = new StringBuffer();
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
content.append((i == 0 ? "" : "&") + key + "=" + value);
}
return content.toString();
}
public static boolean rsaCheckV1(Map<String, String> params, String publicKey,
String charset) throws AlipayApiException {
String sign = params.get("sign");
String content = getSignCheckContentV1(params);
return rsaCheckContent(content, sign, publicKey, charset);
}
public static boolean rsaCheckV1(Map<String, String> params, String publicKey,
String charset,String signType) throws AlipayApiException {
String sign = params.get("sign");
String content = getSignCheckContentV1(params);
return rsaCheck(content, sign, publicKey, charset,signType);
}
public static boolean rsaCheckV2(Map<String, String> params, String publicKey,
String charset) throws AlipayApiException {
String sign = params.get("sign");
String content = getSignCheckContentV2(params);
return rsaCheckContent(content, sign, publicKey, charset);
}
public static boolean rsaCheckV2(Map<String, String> params, String publicKey,
String charset,String signType) throws AlipayApiException {
String sign = params.get("sign");
String content = getSignCheckContentV2(params);
return rsaCheck(content, sign, publicKey, charset,signType);
}
public static boolean rsaCheck(String content, String sign, String publicKey, String charset,
String signType) throws AlipayApiException {
if (AlipayConstants.SIGN_TYPE_RSA.equals(signType)) {
return rsaCheckContent(content, sign, publicKey, charset);
} else if (AlipayConstants.SIGN_TYPE_RSA2.equals(signType)) {
return rsa256CheckContent(content, sign, publicKey, charset);
} else {
throw new AlipayApiException("Sign Type is Not Support : signType=" + signType);
}
}
public static boolean rsa256CheckContent(String content, String sign, String publicKey,
String charset) throws AlipayApiException {
try {
PublicKey pubKey = getPublicKeyFromX509("RSA",
new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(AlipayConstants.SIGN_SHA256RSA_ALGORITHMS);
signature.initVerify(pubKey);
if (StringUtils.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64.decodeBase64(sign.getBytes()));
} catch (Exception e) {
throw new AlipayApiException(
"RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);
}
}
public static boolean rsaCheckContent(String content, String sign, String publicKey,
String charset) throws AlipayApiException {
try {
PublicKey pubKey = getPublicKeyFromX509("RSA",
new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(AlipayConstants.SIGN_ALGORITHMS);
signature.initVerify(pubKey);
if (StringUtils.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64.decodeBase64(sign.getBytes()));
} catch (Exception e) {
throw new AlipayApiException(
"RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);
}
}
public static PublicKey getPublicKeyFromX509(String algorithm,
InputStream ins) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
StringWriter writer = new StringWriter();
StreamUtil.io(new InputStreamReader(ins), writer);
byte[] encodedKey = writer.toString().getBytes();
encodedKey = Base64.decodeBase64(encodedKey);
return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
}
/**
* 验签并解密
* <p>
* <b>目前适用于公众号</b><br>
* params参数示例
* <br>{
* <br>biz_content=M0qGiGz+8kIpxe8aF4geWJdBn0aBTuJRQItLHo9R7o5JGhpic/MIUjvXo2BLB++BbkSq2OsJCEQFDZ0zK5AJYwvBgeRX30gvEj6eXqXRt16/IkB9HzAccEqKmRHrZJ7PjQWE0KfvDAHsJqFIeMvEYk1Zei2QkwSQPlso7K0oheo/iT+HYE8aTATnkqD/ByD9iNDtGg38pCa2xnnns63abKsKoV8h0DfHWgPH62urGY7Pye3r9FCOXA2Ykm8X4/Bl1bWFN/PFCEJHWe/HXj8KJKjWMO6ttsoV0xRGfeyUO8agu6t587Dl5ux5zD/s8Lbg5QXygaOwo3Fz1G8EqmGhi4+soEIQb8DBYanQOS3X+m46tVqBGMw8Oe+hsyIMpsjwF4HaPKMr37zpW3fe7xOMuimbZ0wq53YP/jhQv6XWodjT3mL0H5ACqcsSn727B5ztquzCPiwrqyjUHjJQQefFTzOse8snaWNQTUsQS7aLsHq0FveGpSBYORyA90qPdiTjXIkVP7mAiYiAIWW9pCEC7F3XtViKTZ8FRMM9ySicfuAlf3jtap6v2KPMtQv70X+hlmzO/IXB6W0Ep8DovkF5rB4r/BJYJLw/6AS0LZM9w5JfnAZhfGM2rKzpfNsgpOgEZS1WleG4I2hoQC0nxg9IcP0Hs+nWIPkEUcYNaiXqeBc=,
* <br>sign=rlqgA8O+RzHBVYLyHmrbODVSANWPXf3pSrr82OCO/bm3upZiXSYrX5fZr6UBmG6BZRAydEyTIguEW6VRuAKjnaO/sOiR9BsSrOdXbD5Rhos/Xt7/mGUWbTOt/F+3W0/XLuDNmuYg1yIC/6hzkg44kgtdSTsQbOC9gWM7ayB4J4c=,
* sign_type=RSA,
* <br>charset=UTF-8
* <br>}
* </p>
* @param params
* @param alipayPublicKey 支付宝公钥
* @param cusPrivateKey 商户私钥
* @param isCheckSign 是否验签
* @param isDecrypt 是否解密
* @return 解密后明文,验签失败则异常抛出
* @throws AlipayApiException
*/
public static String checkSignAndDecrypt(Map<String, String> params, String alipayPublicKey,
String cusPrivateKey, boolean isCheckSign,
boolean isDecrypt) throws AlipayApiException {
String charset = params.get("charset");
String bizContent = params.get("biz_content");
if (isCheckSign) {
if (!rsaCheckV2(params, alipayPublicKey, charset)) {
throw new AlipayApiException("rsaCheck failure:rsaParams=" + params);
}
}
if (isDecrypt) {
return rsaDecrypt(bizContent, cusPrivateKey, charset);
}
return bizContent;
}
/**
* 验签并解密
* <p>
* <b>目前适用于公众号</b><br>
* params参数示例
* <br>{
* <br>biz_content=M0qGiGz+8kIpxe8aF4geWJdBn0aBTuJRQItLHo9R7o5JGhpic/MIUjvXo2BLB++BbkSq2OsJCEQFDZ0zK5AJYwvBgeRX30gvEj6eXqXRt16/IkB9HzAccEqKmRHrZJ7PjQWE0KfvDAHsJqFIeMvEYk1Zei2QkwSQPlso7K0oheo/iT+HYE8aTATnkqD/ByD9iNDtGg38pCa2xnnns63abKsKoV8h0DfHWgPH62urGY7Pye3r9FCOXA2Ykm8X4/Bl1bWFN/PFCEJHWe/HXj8KJKjWMO6ttsoV0xRGfeyUO8agu6t587Dl5ux5zD/s8Lbg5QXygaOwo3Fz1G8EqmGhi4+soEIQb8DBYanQOS3X+m46tVqBGMw8Oe+hsyIMpsjwF4HaPKMr37zpW3fe7xOMuimbZ0wq53YP/jhQv6XWodjT3mL0H5ACqcsSn727B5ztquzCPiwrqyjUHjJQQefFTzOse8snaWNQTUsQS7aLsHq0FveGpSBYORyA90qPdiTjXIkVP7mAiYiAIWW9pCEC7F3XtViKTZ8FRMM9ySicfuAlf3jtap6v2KPMtQv70X+hlmzO/IXB6W0Ep8DovkF5rB4r/BJYJLw/6AS0LZM9w5JfnAZhfGM2rKzpfNsgpOgEZS1WleG4I2hoQC0nxg9IcP0Hs+nWIPkEUcYNaiXqeBc=,
* <br>sign=rlqgA8O+RzHBVYLyHmrbODVSANWPXf3pSrr82OCO/bm3upZiXSYrX5fZr6UBmG6BZRAydEyTIguEW6VRuAKjnaO/sOiR9BsSrOdXbD5Rhos/Xt7/mGUWbTOt/F+3W0/XLuDNmuYg1yIC/6hzkg44kgtdSTsQbOC9gWM7ayB4J4c=,
* sign_type=RSA,
* <br>charset=UTF-8
* <br>}
* </p>
* @param params
* @param alipayPublicKey 支付宝公钥
* @param cusPrivateKey 商户私钥
* @param isCheckSign 是否验签
* @param isDecrypt 是否解密
* @return 解密后明文,验签失败则异常抛出
* @throws AlipayApiException
*/
public static String checkSignAndDecrypt(Map<String, String> params, String alipayPublicKey,
String cusPrivateKey, boolean isCheckSign,
boolean isDecrypt, String signType) throws AlipayApiException {
String charset = params.get("charset");
String bizContent = params.get("biz_content");
if (isCheckSign) {
if (!rsaCheckV2(params, alipayPublicKey, charset,signType)) {
throw new AlipayApiException("rsaCheck failure:rsaParams=" + params);
}
}
if (isDecrypt) {
return rsaDecrypt(bizContent, cusPrivateKey, charset);
}
return bizContent;
}
/**
* 加密并签名<br>
* <b>目前适用于公众号</b>
* @param bizContent 待加密、签名内容
* @param alipayPublicKey 支付宝公钥
* @param cusPrivateKey 商户私钥
* @param charset 字符集如UTF-8, GBK, GB2312
* @param isEncrypt 是否加密true-加密 false-不加密
* @param isSign 是否签名true-签名 false-不签名
* @return 加密、签名后xml内容字符串
* <p>
* 返回示例:
* <alipay>
* <response>密文</response>
* <encryption_type>RSA</encryption_type>
* <sign>sign</sign>
* <sign_type>RSA</sign_type>
* </alipay>
* </p>
* @throws AlipayApiException
*/
public static String encryptAndSign(String bizContent, String alipayPublicKey,
String cusPrivateKey, String charset, boolean isEncrypt,
boolean isSign) throws AlipayApiException {
StringBuilder sb = new StringBuilder();
if (StringUtils.isEmpty(charset)) {
charset = AlipayConstants.CHARSET_GBK;
}
sb.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>");
if (isEncrypt) {// 加密
sb.append("<alipay>");
String encrypted = rsaEncrypt(bizContent, alipayPublicKey, charset);
sb.append("<response>" + encrypted + "</response>");
sb.append("<encryption_type>RSA</encryption_type>");
if (isSign) {
String sign = rsaSign(encrypted, cusPrivateKey, charset);
sb.append("<sign>" + sign + "</sign>");
sb.append("<sign_type>RSA</sign_type>");
}
sb.append("</alipay>");
} else if (isSign) {// 不加密,但需要签名
sb.append("<alipay>");
sb.append("<response>" + bizContent + "</response>");
String sign = rsaSign(bizContent, cusPrivateKey, charset);
sb.append("<sign>" + sign + "</sign>");
sb.append("<sign_type>RSA</sign_type>");
sb.append("</alipay>");
} else {// 不加密,不加签
sb.append(bizContent);
}
return sb.toString();
}
/**
* 加密并签名<br>
* <b>目前适用于公众号</b>
* @param bizContent 待加密、签名内容
* @param alipayPublicKey 支付宝公钥
* @param cusPrivateKey 商户私钥
* @param charset 字符集如UTF-8, GBK, GB2312
* @param isEncrypt 是否加密true-加密 false-不加密
* @param isSign 是否签名true-签名 false-不签名
* @return 加密、签名后xml内容字符串
* <p>
* 返回示例:
* <alipay>
* <response>密文</response>
* <encryption_type>RSA</encryption_type>
* <sign>sign</sign>
* <sign_type>RSA</sign_type>
* </alipay>
* </p>
* @throws AlipayApiException
*/
public static String encryptAndSign(String bizContent, String alipayPublicKey,
String cusPrivateKey, String charset, boolean isEncrypt,
boolean isSign,String signType) throws AlipayApiException {
StringBuilder sb = new StringBuilder();
if (StringUtils.isEmpty(charset)) {
charset = AlipayConstants.CHARSET_GBK;
}
sb.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>");
if (isEncrypt) {// 加密
sb.append("<alipay>");
String encrypted = rsaEncrypt(bizContent, alipayPublicKey, charset);
sb.append("<response>" + encrypted + "</response>");
sb.append("<encryption_type>RSA</encryption_type>");
if (isSign) {
String sign = rsaSign(encrypted, cusPrivateKey, charset, signType);
sb.append("<sign>" + sign + "</sign>");
sb.append("<sign_type>");
sb.append(signType);
sb.append("</sign_type>");
}
sb.append("</alipay>");
} else if (isSign) {// 不加密,但需要签名
sb.append("<alipay>");
sb.append("<response>" + bizContent + "</response>");
String sign = rsaSign(bizContent, cusPrivateKey, charset, signType);
sb.append("<sign>" + sign + "</sign>");
sb.append("<sign_type>");
sb.append(signType);
sb.append("</sign_type>");
sb.append("</alipay>");
} else {// 不加密,不加签
sb.append(bizContent);
}
return sb.toString();
}
/**
* 公钥加密
*
* @param content 待加密内容
* @param publicKey 公钥
* @param charset 字符集如UTF-8, GBK, GB2312
* @return 密文内容
* @throws AlipayApiException
*/
public static String rsaEncrypt(String content, String publicKey,
String charset) throws AlipayApiException {
try {
PublicKey pubKey = getPublicKeyFromX509(AlipayConstants.SIGN_TYPE_RSA,
new ByteArrayInputStream(publicKey.getBytes()));
Cipher cipher = Cipher.getInstance(AlipayConstants.SIGN_TYPE_RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] data = StringUtils.isEmpty(charset) ? content.getBytes()
: content.getBytes(charset);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = Base64.encodeBase64(out.toByteArray());
out.close();
return StringUtils.isEmpty(charset) ? new String(encryptedData)
: new String(encryptedData, charset);
} catch (Exception e) {
throw new AlipayApiException("EncryptContent = " + content + ",charset = " + charset,
e);
}
}
/**
* 私钥解密
*
* @param content 待解密内容
* @param privateKey 私钥
* @param charset 字符集如UTF-8, GBK, GB2312
* @return 明文内容
* @throws AlipayApiException
*/
public static String rsaDecrypt(String content, String privateKey,
String charset) throws AlipayApiException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(AlipayConstants.SIGN_TYPE_RSA,
new ByteArrayInputStream(privateKey.getBytes()));
Cipher cipher = Cipher.getInstance(AlipayConstants.SIGN_TYPE_RSA);
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] encryptedData = StringUtils.isEmpty(charset)
? Base64.decodeBase64(content.getBytes())
: Base64.decodeBase64(content.getBytes(charset));
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return StringUtils.isEmpty(charset) ? new String(decryptedData)
: new String(decryptedData, charset);
} catch (Exception e) {
throw new AlipayApiException("EncodeContent = " + content + ",charset = " + charset, e);
}
}
}

View File

@@ -0,0 +1,134 @@
/**
* Alipay.com Inc.
* Copyright (c) 2004-2012 All Rights Reserved.
*/
package com.gitee.sop.alipay;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
/**
*
* @author runzhi
*/
public class StreamUtil {
private static final int DEFAULT_BUFFER_SIZE = 8192;
public static void io(InputStream in, OutputStream out) throws IOException {
io(in, out, -1);
}
public static void io(InputStream in, OutputStream out, int bufferSize) throws IOException {
if (bufferSize == -1) {
bufferSize = DEFAULT_BUFFER_SIZE;
}
byte[] buffer = new byte[bufferSize];
int amount;
while ((amount = in.read(buffer)) >= 0) {
out.write(buffer, 0, amount);
}
}
public static void io(Reader in, Writer out) throws IOException {
io(in, out, -1);
}
public static void io(Reader in, Writer out, int bufferSize) throws IOException {
if (bufferSize == -1) {
bufferSize = DEFAULT_BUFFER_SIZE >> 1;
}
char[] buffer = new char[bufferSize];
int amount;
while ((amount = in.read(buffer)) >= 0) {
out.write(buffer, 0, amount);
}
}
public static OutputStream synchronizedOutputStream(OutputStream out) {
return new SynchronizedOutputStream(out);
}
public static OutputStream synchronizedOutputStream(OutputStream out, Object lock) {
return new SynchronizedOutputStream(out, lock);
}
public static String readText(InputStream in) throws IOException {
return readText(in, null, -1);
}
public static String readText(InputStream in, String encoding) throws IOException {
return readText(in, encoding, -1);
}
public static String readText(InputStream in, String encoding, int bufferSize)
throws IOException {
Reader reader = (encoding == null) ? new InputStreamReader(in) : new InputStreamReader(in,
encoding);
return readText(reader, bufferSize);
}
public static String readText(Reader reader) throws IOException {
return readText(reader, -1);
}
public static String readText(Reader reader, int bufferSize) throws IOException {
StringWriter writer = new StringWriter();
io(reader, writer, bufferSize);
return writer.toString();
}
private static class SynchronizedOutputStream extends OutputStream {
private OutputStream out;
private Object lock;
SynchronizedOutputStream(OutputStream out) {
this(out, out);
}
SynchronizedOutputStream(OutputStream out, Object lock) {
this.out = out;
this.lock = lock;
}
public void write(int datum) throws IOException {
synchronized (lock) {
out.write(datum);
}
}
public void write(byte[] data) throws IOException {
synchronized (lock) {
out.write(data);
}
}
public void write(byte[] data, int offset, int length) throws IOException {
synchronized (lock) {
out.write(data, offset, length);
}
}
public void flush() throws IOException {
synchronized (lock) {
out.flush();
}
}
public void close() throws IOException {
synchronized (lock) {
out.close();
}
}
}
}

View File

@@ -0,0 +1,167 @@
package com.gitee.sop.alipay;
/**
* 字符串工具类。
*
* @author carver.gu
* @since 1.0, Sep 12, 2009
*/
public abstract class StringUtils {
private StringUtils() {}
/**
* 检查指定的字符串是否为空。
* <ul>
* <li>SysUtils.isEmpty(null) = true</li>
* <li>SysUtils.isEmpty("") = true</li>
* <li>SysUtils.isEmpty(" ") = true</li>
* <li>SysUtils.isEmpty("abc") = false</li>
* </ul>
*
* @param value 待检查的字符串
* @return true/false
*/
public static boolean isEmpty(String value) {
int strLen;
if (value == null || (strLen = value.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(value.charAt(i)) == false)) {
return false;
}
}
return true;
}
/**
* 检查对象是否为数字型字符串,包含负数开头的。
*/
public static boolean isNumeric(Object obj) {
if (obj == null) {
return false;
}
char[] chars = obj.toString().toCharArray();
int length = chars.length;
if(length < 1)
return false;
int i = 0;
if(length > 1 && chars[0] == '-')
i = 1;
for (; i < length; i++) {
if (!Character.isDigit(chars[i])) {
return false;
}
}
return true;
}
/**
* 检查指定的字符串列表是否不为空。
*/
public static boolean areNotEmpty(String... values) {
boolean result = true;
if (values == null || values.length == 0) {
result = false;
} else {
for (String value : values) {
result &= !isEmpty(value);
}
}
return result;
}
/**
* 把通用字符编码的字符串转化为汉字编码。
*/
public static String unicodeToChinese(String unicode) {
StringBuilder out = new StringBuilder();
if (!isEmpty(unicode)) {
for (int i = 0; i < unicode.length(); i++) {
out.append(unicode.charAt(i));
}
}
return out.toString();
}
/**
* 过滤不可见字符
*/
public static String stripNonValidXMLCharacters(String input) {
if (input == null || ("".equals(input)))
return "";
StringBuilder out = new StringBuilder();
char current;
for (int i = 0; i < input.length(); i++) {
current = input.charAt(i);
if ((current == 0x9) || (current == 0xA) || (current == 0xD)
|| ((current >= 0x20) && (current <= 0xD7FF))
|| ((current >= 0xE000) && (current <= 0xFFFD))
|| ((current >= 0x10000) && (current <= 0x10FFFF)))
out.append(current);
}
return out.toString();
}
public static String leftPad(String str, int size, char padChar) {
if (str == null) {
return null;
} else {
int pads = size - str.length();
if (pads <= 0) {
return str;
} else {
return pads > 8192 ? leftPad(str, size, String.valueOf(padChar)) : padding(pads, padChar).concat(str);
}
}
}
public static String leftPad(String str, int size, String padStr) {
if (str == null) {
return null;
} else {
if (isEmpty(padStr)) {
padStr = " ";
}
int padLen = padStr.length();
int strLen = str.length();
int pads = size - strLen;
if (pads <= 0) {
return str;
} else if (padLen == 1 && pads <= 8192) {
return leftPad(str, size, padStr.charAt(0));
} else if (pads == padLen) {
return padStr.concat(str);
} else if (pads < padLen) {
return padStr.substring(0, pads).concat(str);
} else {
char[] padding = new char[pads];
char[] padChars = padStr.toCharArray();
for(int i = 0; i < pads; ++i) {
padding[i] = padChars[i % padLen];
}
return (new String(padding)).concat(str);
}
}
}
private static String padding(int repeat, char padChar) throws IndexOutOfBoundsException {
if (repeat < 0) {
throw new IndexOutOfBoundsException("Cannot pad a negative amount: " + repeat);
} else {
char[] buf = new char[repeat];
for(int i = 0; i < buf.length; ++i) {
buf[i] = padChar;
}
return new String(buf);
}
}
}

View File

@@ -0,0 +1,10 @@
package com.gitee.sop.taobao;
/**
* @author tanghc
*/
public class Constants {
public static final String SIGN_METHOD_HMAC = "hmac";
public static final String SIGN_METHOD_MD5 = "md5";
public static final String CHARSET_UTF8 = "UTF-8";
}

View File

@@ -0,0 +1,95 @@
package com.gitee.sop.taobao;
import com.gitee.sop.alipay.StringUtils;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;
/**
* @author tanghc
*/
public class TaobaoSignature {
public static String signTopRequest(Map<String, String> params, String secret, String signMethod) throws IOException {
String content = getSignContent(params);
return doSign(content, secret, signMethod);
}
public static String getSignContent(Map<String, String> params) {
// 第一步:检查参数是否已经排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
for (String key : keys) {
String value = params.get(key);
if (StringUtils.areNotEmpty(key, value)) {
query.append(key).append(value);
}
}
return query.toString();
}
public static String doSign(String content,String secret, String signMethod) throws IOException {
// 第三步使用MD5/HMAC加密
byte[] bytes;
if (Constants.SIGN_METHOD_HMAC.equals(signMethod)) {
bytes = encryptHMAC(content, secret);
} else {
bytes = encryptMD5(secret + content + secret);
}
// 第四步:把二进制转化为大写的十六进制(正确签名应该为32大写字符串此方法需要时使用)
return byte2hex(bytes);
}
public static byte[] encryptHMAC(String data, String secret) throws IOException {
byte[] bytes = null;
try {
SecretKey secretKey = new SecretKeySpec(secret.getBytes(Constants.CHARSET_UTF8), "HmacMD5");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
bytes = mac.doFinal(data.getBytes(Constants.CHARSET_UTF8));
} catch (GeneralSecurityException gse) {
throw new IOException(gse.toString());
}
return bytes;
}
public static byte[] encryptMD5(String data) throws IOException {
return encryptMD5(data.getBytes(Constants.CHARSET_UTF8));
}
public static byte[] encryptMD5(byte[] data) {
try {
MessageDigest digest = MessageDigest.getInstance(Constants.SIGN_METHOD_MD5);
return digest.digest(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
}

View File

@@ -0,0 +1,87 @@
package com.gitee.sop;
import com.alibaba.fastjson.JSON;
import com.gitee.sop.alipay.AlipaySignature;
import org.junit.Test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 模仿支付宝客户端请求接口
*/
public class AlipayClientPostTest extends TestBase {
String url = "http://localhost:8081/api";
String appId = "alipay_test";
// 支付宝私钥
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
/*
参数 类型 是否必填 最大长度 描述 示例值
app_id String 是 32 支付宝分配给开发者的应用ID 2014072300007148
method String 是 128 接口名称 alipay.trade.fastpay.refund.query
format String 否 40 仅支持JSON JSON
charset String 是 10 请求使用的编码格式如utf-8,gbk,gb2312等 utf-8
sign_type String 是 10 商户生成签名字符串所使用的签名算法类型目前支持RSA2和RSA推荐使用RSA2 RSA2
sign String 是 344 商户请求参数的签名串,详见签名 详见示例
timestamp String 是 19 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss" 2014-07-24 03:07:50
version String 是 3 调用的接口版本固定为1.0 1.0
app_auth_token String 否 40 详见应用授权概述
biz_content String 是 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档
*/
@Test
public void testPost() throws Exception {
// 公共请求参数
Map<String, String> params = new HashMap<String, String>();
params.put("app_id", appId);
params.put("method", "alipay.story.get");
params.put("format", "json");
params.put("charset", "utf-8");
params.put("sign_type", "RSA2");
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
params.put("version", "1.0");
// 业务参数
Map<String, String> bizContent = new HashMap<>();
bizContent.put("id", "1");
bizContent.put("name", "葫芦娃");
// bizContent.put("name", "葫芦娃1234567890葫芦娃1234567890"); // 超出长度
params.put("biz_content", JSON.toJSONString(bizContent));
System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey);
String content = AlipaySignature.getSignContent(params);
System.out.println("待签名内容:" + content);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
System.out.println("签名(sign)" + sign);
params.put("sign", sign);
System.out.println("----------- 返回结果 -----------");
String responseData = post(url, params);// 发送请求
System.out.println(responseData);
}
private String buildParamQuery(Map<String, String> params) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append("&").append(entry.getKey()).append("=").append(entry.getValue());
}
return sb.toString().substring(1);
}
}

View File

@@ -0,0 +1,77 @@
package com.gitee.sop;
import com.alibaba.fastjson.JSON;
import com.gitee.sop.taobao.TaobaoSignature;
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 模仿淘宝客户端请求接口
*/
public class TaobaoClientPostTest extends TestBase {
String url = "http://localhost:8081/api";
String appId = "taobao_test";
// 支付宝私钥
String secret = "G9w0BAQEFAAOCAQ8AMIIBCgKCA";
/*
参数名称 参数类型 是否必须 参数描述
method String 是 API接口名称。
app_key String 是 TOP分配给应用的AppKey。这里要注意正式环境和沙箱环境的AppKey是不同的包括AppSecret使用时要注意区分进入开放平台控制台“应用管理-概览” 和 “应用管理-沙箱环境管理”可分别查看正式环境及沙箱环境的AppKey、AppSecret
session String 否 用户登录授权成功后TOP颁发给应用的授权信息详细介绍请点击这里。当此API文档的标签上注明“需要授权”则此参数必传“不需要授权”则此参数不需要传“可选授权”则此参数为可选。
timestamp String 是 时间戳格式为yyyy-MM-dd HH:mm:ss时区为GMT+8例如2016-01-01 12:00:00。淘宝API服务端允许客户端请求最大时间误差为10分钟。
format String 否 响应格式。默认为xml格式可选值xmljson。
v String 是 API协议版本可选值2.0。
partner_id String 否 合作伙伴身份标识。
target_app_key String 否 被调用的目标AppKey仅当被调用的API为第三方ISV提供时有效。
simplify Boolean 否 是否采用精简JSON返回格式仅当format=json时有效默认值为false。
sign_method String 是 签名的摘要算法可选值为hmacmd5。
sign String 是 API输入参数签名结果签名算法参照下面的介绍。
*/
@Test
public void testPost() throws Exception {
// 公共请求参数
Map<String, String> params = new HashMap<String, String>();
params.put("app_key", appId);
params.put("method", "alipay.story.get");
params.put("format", "json");
params.put("sign_method", "md5");
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
params.put("v", "");
// 业务参数
params.put("id", "1");
params.put("name", "葫芦娃");
// bizContent.put("name", "葫芦娃1234567890葫芦娃1234567890"); // 超出长度
System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + secret);
String content = TaobaoSignature.getSignContent(params);
System.out.println("待签名内容:" + content);
String sign = TaobaoSignature.doSign(content, secret, "md5");
System.out.println("签名(sign)" + sign);
params.put("sign", sign);
System.out.println("----------- 返回结果 -----------");
String responseData = post(url, params);// 发送请求
System.out.println(responseData);
}
private String buildParamQuery(Map<String, String> params) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append("&").append(entry.getKey()).append("=").append(entry.getValue());
}
return sb.toString().substring(1);
}
}

View File

@@ -0,0 +1,100 @@
package com.gitee.sop;
import junit.framework.TestCase;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author tanghc
*/
public class TestBase extends TestCase {
public void post(String url, String postJson) throws IOException {
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
// 构造消息头
post.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
// 构建消息实体
StringEntity entity = new StringEntity(postJson, Charset.forName("UTF-8"));
entity.setContentEncoding("UTF-8");
// 发送Json格式的数据请求
entity.setContentType("application/json");
post.setEntity(entity);
HttpResponse response = httpClient.execute(post);
HttpEntity responseEntity = response.getEntity();
String content = IOUtils.toString(responseEntity.getContent(), "UTF-8");
System.out.println(content);
}
/**
* 发送POST请求
* @param url
* @return JSON或者字符串
* @throws Exception
*/
public static String post(String url, Map<String, String> params) throws Exception{
CloseableHttpClient client = null;
CloseableHttpResponse response = null;
try{
/**
* 创建一个httpclient对象
*/
client = HttpClients.createDefault();
/**
* 创建一个post对象
*/
HttpPost post = new HttpPost(url);
List<NameValuePair> nameValuePairs = params.entrySet().stream().map(entry -> {
return new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue()));
}).collect(Collectors.toList());
/**
* 包装成一个Entity对象
*/
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nameValuePairs, "UTF-8");
/**
* 设置请求的内容
*/
post.setEntity(entity);
/**
* 设置请求的报文头部的编码
*/
post.setHeader(new BasicHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"));
/**
* 执行post请求
*/
response = client.execute(post);
/**
* 通过EntityUitls获取返回内容
*/
return EntityUtils.toString(response.getEntity(),"UTF-8");
}catch (Exception e){
e.printStackTrace();
}finally {
IOUtils.closeQuietly(client);
IOUtils.closeQuietly(response);
}
return null;
}
}