Commit 50e9202a authored by zhangc's avatar zhangc

commit gatway代码

parent 4bee7acb
<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"> <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">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>com.jz.dm</groupId> <groupId>com.jz.dm</groupId>
...@@ -8,4 +9,68 @@ ...@@ -8,4 +9,68 @@
<artifactId>jz-dm-apigateway</artifactId> <artifactId>jz-dm-apigateway</artifactId>
<name>jz-dm-apigateway</name> <name>jz-dm-apigateway</name>
<description>jz-dm-apigateway</description> <description>jz-dm-apigateway</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.5.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<!--<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.3.0.RELEASE</version>
<scope>compile</scope>
</dependency>-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<dependency>
<groupId>com.jz.common</groupId>
<artifactId>jz-dm-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project> </project>
\ No newline at end of file
package com.jz.dm.gateway;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
* @author key
*/
@SpringBootApplication
@ComponentScan(basePackages = {"com.jz.dm"})
@MapperScan("com.jz.dm.mapper")
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
package com.jz.dm.gateway.common;
/**
* 常量
*
*/
public class Constants {
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_TYPE = "sign_type";
public static final String SIGN = "sign";
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 PARAMS = "params";
public static final String RESPONSE = "response";
public static final String SUCCESS = "SUCCESS";
public static final String BUSINESS_ID = "business_id";
public static final String NOTIFY_TYPE = "notify_type";
public static final String NOTIFY_TIME = "notify_time";
/** 默认时间格式 **/
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";
/** 默认版本 */
public static final String DEFAULT_VERSION = "1.0.0";
public static final int FILTER_ORDER_0 = 0;
public static final int FILTER_ORDER_1 = 1;
public static final int FILTER_ORDER_2 = 2;
public static final int FILTER_ORDER_3 = 3;
public static final int FILTER_ORDER_4 = 4;
public static final int FILTER_ORDER_5 = 5;
public static final int FILTER_ORDER_6 = 6;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
package com.jz.dm.gateway.common.exception;
import com.jz.dm.gateway.common.util.ResultCode;
/**
* 网关异常
*
*/
public class GatewayException extends OpenApiException {
/** 序列号 */
private static final long serialVersionUID = 3391018902219700916L;
/**
* 构造函数
*
* @param resultCode
*/
public GatewayException(ResultCode resultCode) {
super(resultCode);
}
/**
* 构造函数
*
* @param resultCode
* @param cause
*/
public GatewayException(ResultCode resultCode, Throwable cause) {
super(resultCode, cause);
}
/**
* 构造函数
*
* @param resultCode
* @param detailMessage
*/
public GatewayException(ResultCode resultCode, String detailMessage) {
super(resultCode, detailMessage);
}
/**
* 构造函数
*
* @param code
* @param msg
*/
public GatewayException(String code, String msg) {
this(code, msg, (Throwable) null);
}
/**
* 构造函数
*
* @param code
* @param msg
* @param cause
*/
public GatewayException(String code, String msg, Throwable cause) {
super(code, msg, cause);
}
/**
* 构造函数
*
* @param code
* @param msg
* @param detailMessage
*/
public GatewayException(String code, String msg, String detailMessage) {
super(code, msg, detailMessage);
}
}
\ No newline at end of file
package com.jz.dm.gateway.common.exception;
import com.jz.dm.gateway.common.util.ResultCode;
/**
* 信息摘要异常
*
*/
public class MessageDigestException extends OpenApiException {
private static final long serialVersionUID = 477249046784548217L;
/**
* 构造函数
* @param resultCode
*/
public MessageDigestException(ResultCode resultCode) {
super(resultCode);
}
/**
* 构造函数
* @param resultCode
* @param detailMessage
*/
public MessageDigestException(ResultCode resultCode, String detailMessage) {
super(resultCode, detailMessage);
}
/**
* 构造函数
* @param resultCode
* @param cause
*/
public MessageDigestException(ResultCode resultCode, Throwable cause) {
super(resultCode, cause);
}
/**
* 构造函数
* @param resultCode
* @param detailMessage
* @param cause
*/
public MessageDigestException(ResultCode resultCode, String detailMessage, Throwable cause) {
super(resultCode, detailMessage, cause);
}
}
package com.jz.dm.gateway.common.exception;
import com.jz.dm.gateway.common.util.ResultCode;
/**
* 通知异常
*
*/
public class NotifyException extends OpenApiException {
/** 序列号 */
private static final long serialVersionUID = 3391018902219700916L;
/**
* 构造函数
*
* @param resultCode
*/
public NotifyException(ResultCode resultCode) {
super(resultCode);
}
/**
* 构造函数
*
* @param resultCode
* @param cause
*/
public NotifyException(ResultCode resultCode, Throwable cause) {
super(resultCode, cause);
}
/**
* 构造函数
*
* @param resultCode
* @param detailMessage
*/
public NotifyException(ResultCode resultCode, String detailMessage) {
super(resultCode, detailMessage);
}
/**
* 构造函数
*
* @param code
* @param msg
*/
public NotifyException(String code, String msg) {
this(code, msg, (Throwable) null);
}
/**
* 构造函数
*
* @param code
* @param msg
* @param cause
*/
public NotifyException(String code, String msg, Throwable cause) {
super(code, msg, cause);
}
/**
* 构造函数
*
* @param code
* @param msg
* @param detailMessage
*/
public NotifyException(String code, String msg, String detailMessage) {
super(code, msg, detailMessage);
}
}
\ No newline at end of file
package com.jz.dm.gateway.common.exception;
import com.jz.dm.gateway.common.util.ResultCode;
/**
* openapi异常
*
*/
public class OpenApiException extends RuntimeException {
private static final long serialVersionUID = -3963657380514719229L;
/**
* 结果码
*/
private ResultCode resultCode;
/**
* 构造函数
*
* @param resultCode
*/
public OpenApiException(ResultCode resultCode) {
this.resultCode = new ResultCodeImpl(resultCode);
}
/**
* 构造函数
*
* @param resultCode
* @param cause
*/
public OpenApiException(ResultCode resultCode, Throwable cause) {
super(cause);
this.resultCode = new ResultCodeImpl(resultCode);
}
/**
* 构造函数
*
* @param resultCode
* @param detailMessage
*/
public OpenApiException(ResultCode resultCode, String detailMessage) {
super(detailMessage);
this.resultCode = new ResultCodeImpl(resultCode);
}
/**
* 构造函数
*
* @param resultCode
* @param detailMessage
* @param cause
*/
public OpenApiException(ResultCode resultCode, String detailMessage, Throwable cause) {
super(detailMessage, cause);
this.resultCode = new ResultCodeImpl(resultCode);
}
/**
* 构造函数
*
* @param code
* @param msg
*/
public OpenApiException(String code, String msg) {
this(new ResultCodeImpl(code, msg));
}
/**
* 构造函数
*
* @param code
* @param msg
* @param cause
*/
public OpenApiException(String code, String msg, Throwable cause) {
this(new ResultCodeImpl(code, msg), cause);
}
/**
* 构造函数
*
* @param code
* @param msg
* @param detailMessage
*/
public OpenApiException(String code, String msg, String detailMessage) {
this(new ResultCodeImpl(code, msg), detailMessage);
}
/**
* Getter method for property <tt>resultCode</tt>.
*
* @return property value of resultCode
*/
public ResultCode getResultCode() {
return resultCode;
}
public static class ResultCodeImpl implements ResultCode {
private String code;
private String msg;
public ResultCodeImpl(ResultCode resultCode) {
this.code = resultCode.getCode();
this.msg = resultCode.getMsg();
}
public ResultCodeImpl(String code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public String getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
}
}
package com.jz.dm.gateway.common.exception;
import com.jz.dm.gateway.common.util.ResultCode;
/**
* 加密异常
*
*/
public class SecretException extends OpenApiException {
private static final long serialVersionUID = -8597436175649786898L;
/**
* 构造函数
* @param resultCode
*/
public SecretException(ResultCode resultCode) {
super(resultCode);
}
/**
* 构造函数
* @param resultCode
* @param detailMessage
*/
public SecretException(ResultCode resultCode, String detailMessage) {
super(resultCode, detailMessage);
}
/**
* 构造函数
* @param resultCode
* @param cause
*/
public SecretException(ResultCode resultCode, Throwable cause) {
super(resultCode, cause);
}
/**
* 构造函数
* @param resultCode
* @param detailMessage
* @param cause
*/
public SecretException(ResultCode resultCode, String detailMessage, Throwable cause) {
super(resultCode, detailMessage, cause);
}
}
package com.jz.dm.gateway.common.exception;
import com.jz.dm.gateway.common.util.ResultCode;
/**
* 签名异常
*
*/
public class SignatureException extends OpenApiException {
private static final long serialVersionUID = 6551962245794846748L;
/**
* 构造函数
*
* @param resultCode
*/
public SignatureException(ResultCode resultCode) {
super(resultCode);
}
/**
* 构造函数
* @param resultCode
* @param detailMessage
*/
public SignatureException(ResultCode resultCode, String detailMessage) {
super(resultCode, detailMessage);
}
/**
* 构造函数
* @param resultCode
* @param cause
*/
public SignatureException(ResultCode resultCode, Throwable cause) {
super(resultCode, cause);
}
/**
* 构造函数
* @param resultCode
* @param detailMessage
* @param cause
*/
public SignatureException(ResultCode resultCode, String detailMessage, Throwable cause) {
super(resultCode, detailMessage, cause);
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jz.dm.gateway.common.util;
import org.apache.commons.codec.BinaryDecoder;
import org.apache.commons.codec.BinaryEncoder;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.EncoderException;
/**
* Provides Base64 encoding and decoding as defined by RFC 2045.
*
* <p>This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite>
* from RFC 2045 <cite>Multipurpose Internet Mail Extensions (MIME) Part One:
* Format of Internet Message Bodies</cite> by Freed and Borenstein.</p>
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
* @author Apache Software Foundation
* @since 1.0-dev
* @version $Id: Base64.java,v 1.20 2004/05/24 00:21:24 ggregory Exp $
*/
public class Base64 implements BinaryEncoder, BinaryDecoder {
/**
* Chunk size per RFC 2045 section 6.8.
*
* <p>The {@value} character limit does not count the trailing CRLF, but counts
* all other characters, including any equal signs.</p>
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a>
*/
static final int CHUNK_SIZE = 76;
/**
* Chunk separator per RFC 2045 section 2.1.
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
*/
static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes();
/**
* The base length.
*/
static final int BASELENGTH = 255;
/**
* Lookup length.
*/
static final int LOOKUPLENGTH = 64;
/**
* Used to calculate the number of bits in a byte.
*/
static final int EIGHTBIT = 8;
/**
* Used when encoding something which has fewer than 24 bits.
*/
static final int SIXTEENBIT = 16;
/**
* Used to determine how many bits data contains.
*/
static final int TWENTYFOURBITGROUP = 24;
/**
* Used to get the number of Quadruples.
*/
static final int FOURBYTE = 4;
/**
* Used to test the sign of a byte.
*/
static final int SIGN = -128;
/**
* Byte used to pad output.
*/
static final byte PAD = (byte) '=';
// Create arrays to hold the base64 characters and a
// lookup for base64 chars
private static byte[] base64Alphabet = new byte[BASELENGTH];
private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
// Populating the lookup and character arrays
static {
for (int i = 0; i < BASELENGTH; i++) {
base64Alphabet[i] = (byte) -1;
}
for (int i = 'Z'; i >= 'A'; i--) {
base64Alphabet[i] = (byte) (i - 'A');
}
for (int i = 'z'; i >= 'a'; i--) {
base64Alphabet[i] = (byte) (i - 'a' + 26);
}
for (int i = '9'; i >= '0'; i--) {
base64Alphabet[i] = (byte) (i - '0' + 52);
}
base64Alphabet['+'] = 62;
base64Alphabet['/'] = 63;
for (int i = 0; i <= 25; i++) {
lookUpBase64Alphabet[i] = (byte) ('A' + i);
}
for (int i = 26, j = 0; i <= 51; i++, j++) {
lookUpBase64Alphabet[i] = (byte) ('a' + j);
}
for (int i = 52, j = 0; i <= 61; i++, j++) {
lookUpBase64Alphabet[i] = (byte) ('0' + j);
}
lookUpBase64Alphabet[62] = (byte) '+';
lookUpBase64Alphabet[63] = (byte) '/';
}
private static boolean isBase64(byte octect) {
if (octect == PAD) {
return true;
} else if (base64Alphabet[octect] == -1) {
return false;
} else {
return true;
}
}
/**
* Tests a given byte array to see if it contains
* only valid characters within the Base64 alphabet.
*
* @param arrayOctect byte array to test
* @return true if all bytes are valid characters in the Base64
* alphabet or if the byte array is empty; false, otherwise
*/
public static boolean isArrayByteBase64(byte[] arrayOctect) {
arrayOctect = discardWhitespace(arrayOctect);
int length = arrayOctect.length;
if (length == 0) {
// shouldn't a 0 length array be valid base64 data?
// return false;
return true;
}
for (int i = 0; i < length; i++) {
if (!isBase64(arrayOctect[i])) {
return false;
}
}
return true;
}
/**
* Encodes binary data using the base64 algorithm but
* does not chunk the output.
*
* @param binaryData binary data to encode
* @return Base64 characters
*/
public static byte[] encodeBase64(byte[] binaryData) {
return encodeBase64(binaryData, false);
}
/**
* Encodes binary data using the base64 algorithm and chunks
* the encoded output into 76 character blocks
*
* @param binaryData binary data to encode
* @return Base64 characters chunked in 76 character blocks
*/
public static byte[] encodeBase64Chunked(byte[] binaryData) {
return encodeBase64(binaryData, true);
}
/**
* Decodes an Object using the base64 algorithm. This method
* is provided in order to satisfy the requirements of the
* Decoder interface, and will throw a DecoderException if the
* supplied object is not of type byte[].
*
* @param pObject Object to decode
* @return An object (of type byte[]) containing the
* binary data which corresponds to the byte[] supplied.
* @throws DecoderException if the parameter supplied is not
* of type byte[]
*/
@Override
public Object decode(Object pObject) throws DecoderException {
if (!(pObject instanceof byte[])) {
throw new DecoderException("Parameter supplied to Base64 decode is not a byte[]");
}
return decode((byte[]) pObject);
}
/**
* Decodes a byte[] containing containing
* characters in the Base64 alphabet.
*
* @param pArray A byte array containing Base64 character data
* @return a byte array containing binary data
*/
@Override
public byte[] decode(byte[] pArray) {
return decodeBase64(pArray);
}
/**
* Encodes binary data using the base64 algorithm, optionally
* chunking the output into 76 character blocks.
*
* @param binaryData Array containing binary data to encode.
* @param isChunked if isChunked is true this encoder will chunk
* the base64 output into 76 character blocks
* @return Base64-encoded data.
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
int lengthDataBits = binaryData.length * EIGHTBIT;
int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
byte encodedData[] = null;
int encodedDataLength = 0;
int nbrChunks = 0;
if (fewerThan24bits != 0) {
//data not divisible by 24 bit
encodedDataLength = (numberTriplets + 1) * 4;
} else {
// 16 or 8 bit
encodedDataLength = numberTriplets * 4;
}
// If the output is to be "chunked" into 76 character sections,
// for compliance with RFC 2045 MIME, then it is important to
// allow for extra length to account for the separator(s)
if (isChunked) {
nbrChunks =
(CHUNK_SEPARATOR.length == 0 ? 0 : (int) Math.ceil((float) encodedDataLength / CHUNK_SIZE));
encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length;
}
encodedData = new byte[encodedDataLength];
byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
int encodedIndex = 0;
int dataIndex = 0;
int i = 0;
int nextSeparatorIndex = CHUNK_SIZE;
int chunksSoFar = 0;
//log.debug("number of triplets = " + numberTriplets);
for (i = 0; i < numberTriplets; i++) {
dataIndex = i * 3;
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1];
b3 = binaryData[dataIndex + 2];
//log.debug("b1= " + b1 +", b2= " + b2 + ", b3= " + b3);
l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03);
byte val1 =
((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
byte val2 =
((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
byte val3 =
((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
//log.debug( "val2 = " + val2 );
//log.debug( "k4 = " + (k<<4) );
//log.debug( "vak = " + (val2 | (k<<4)) );
encodedData[encodedIndex + 1] =
lookUpBase64Alphabet[val2 | (k << 4)];
encodedData[encodedIndex + 2] =
lookUpBase64Alphabet[(l << 2) | val3];
encodedData[encodedIndex + 3] = lookUpBase64Alphabet[b3 & 0x3f];
encodedIndex += 4;
// If we are chunking, let's put a chunk separator down.
if (isChunked) {
// this assumes that CHUNK_SIZE % 4 == 0
if (encodedIndex == nextSeparatorIndex) {
System.arraycopy(
CHUNK_SEPARATOR,
0,
encodedData,
encodedIndex,
CHUNK_SEPARATOR.length);
chunksSoFar++;
nextSeparatorIndex =
(CHUNK_SIZE * (chunksSoFar + 1)) +
(chunksSoFar * CHUNK_SEPARATOR.length);
encodedIndex += CHUNK_SEPARATOR.length;
}
}
}
// form integral number of 6-bit groups
dataIndex = i * 3;
if (fewerThan24bits == EIGHTBIT) {
b1 = binaryData[dataIndex];
k = (byte) (b1 & 0x03);
//log.debug("b1=" + b1);
//log.debug("b1<<2 = " + (b1>>2) );
byte val1 =
((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex + 1] = lookUpBase64Alphabet[k << 4];
encodedData[encodedIndex + 2] = PAD;
encodedData[encodedIndex + 3] = PAD;
} else if (fewerThan24bits == SIXTEENBIT) {
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1];
l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03);
byte val1 =
((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
byte val2 =
((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex + 1] =
lookUpBase64Alphabet[val2 | (k << 4)];
encodedData[encodedIndex + 2] = lookUpBase64Alphabet[l << 2];
encodedData[encodedIndex + 3] = PAD;
}
if (isChunked) {
// we also add a separator to the end of the final chunk.
if (chunksSoFar < nbrChunks) {
System.arraycopy(
CHUNK_SEPARATOR,
0,
encodedData,
encodedDataLength - CHUNK_SEPARATOR.length,
CHUNK_SEPARATOR.length);
}
}
return encodedData;
}
/**
* Decodes Base64 data into octects
*
* @param base64Data Byte array containing Base64 data
* @return Array containing decoded data.
*/
public static byte[] decodeBase64(byte[] base64Data) {
// RFC 2045 requires that we discard ALL non-Base64 characters
base64Data = discardNonBase64(base64Data);
// handle the edge case, so we don't have to worry about it later
if (base64Data.length == 0) {
return new byte[0];
}
int numberQuadruple = base64Data.length / FOURBYTE;
byte decodedData[] = null;
byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
// Throw away anything not in base64Data
int encodedIndex = 0;
int dataIndex = 0;
{
// this sizes the output array properly - rlw
int lastData = base64Data.length;
// ignore the '=' padding
while (base64Data[lastData - 1] == PAD) {
if (--lastData == 0) {
return new byte[0];
}
}
decodedData = new byte[lastData - numberQuadruple];
}
for (int i = 0; i < numberQuadruple; i++) {
dataIndex = i * 4;
marker0 = base64Data[dataIndex + 2];
marker1 = base64Data[dataIndex + 3];
b1 = base64Alphabet[base64Data[dataIndex]];
b2 = base64Alphabet[base64Data[dataIndex + 1]];
if (marker0 != PAD && marker1 != PAD) {
//No PAD e.g 3cQl
b3 = base64Alphabet[marker0];
b4 = base64Alphabet[marker1];
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex + 1] =
(byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
} else if (marker0 == PAD) {
//Two PAD e.g. 3c[Pad][Pad]
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
} else if (marker1 == PAD) {
//One PAD e.g. 3cQ[Pad]
b3 = base64Alphabet[marker0];
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex + 1] =
(byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
}
encodedIndex += 3;
}
return decodedData;
}
/**
* Discards any whitespace from a base-64 encoded block.
*
* @param data The base-64 encoded data to discard the whitespace
* from.
* @return The data, less whitespace (see RFC 2045).
*/
static byte[] discardWhitespace(byte[] data) {
byte groomedData[] = new byte[data.length];
int bytesCopied = 0;
for (int i = 0; i < data.length; i++) {
switch (data[i]) {
case (byte) ' ' :
case (byte) '\n' :
case (byte) '\r' :
case (byte) '\t' :
break;
default:
groomedData[bytesCopied++] = data[i];
}
}
byte packedData[] = new byte[bytesCopied];
System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
return packedData;
}
/**
* Discards any characters outside of the base64 alphabet, per
* the requirements on page 25 of RFC 2045 - "Any characters
* outside of the base64 alphabet are to be ignored in base64
* encoded data."
*
* @param data The base-64 encoded data to groom
* @return The data, less non-base64 characters (see RFC 2045).
*/
static byte[] discardNonBase64(byte[] data) {
byte groomedData[] = new byte[data.length];
int bytesCopied = 0;
for (int i = 0; i < data.length; i++) {
if (isBase64(data[i])) {
groomedData[bytesCopied++] = data[i];
}
}
byte packedData[] = new byte[bytesCopied];
System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
return packedData;
}
// Implementation of the Encoder Interface
/**
* Encodes an Object using the base64 algorithm. This method
* is provided in order to satisfy the requirements of the
* Encoder interface, and will throw an EncoderException if the
* supplied object is not of type byte[].
*
* @param pObject Object to encode
* @return An object (of type byte[]) containing the
* base64 encoded data which corresponds to the byte[] supplied.
* @throws EncoderException if the parameter supplied is not
* of type byte[]
*/
@Override
public Object encode(Object pObject) throws EncoderException {
if (!(pObject instanceof byte[])) {
throw new EncoderException(
"Parameter supplied to Base64 encode is not a byte[]");
}
return encode((byte[]) pObject);
}
/**
* Encodes a byte[] containing binary data, into a byte[] containing
* characters in the Base64 alphabet.
*
* @param pArray a byte array containing binary data
* @return A byte array containing only Base64 character data
*/
@Override
public byte[] encode(byte[] pArray) {
return encodeBase64(pArray, false);
}
public static void main(String[] args) throws EncoderException, DecoderException {
// aGVsbG8gd29ybGQ=
// aGVsbG8gd29ybGQ=
System.out.println(new Base64().encode("hello world".getBytes()).getClass());
System.out.println(new String(new Base64().encode("hello world".getBytes())));
System.out.println(new String(new Base64().decode("aGVsbG8gd29ybGQ=".getBytes())));
}
}
package com.jz.dm.gateway.common.util;
import com.jz.dm.gateway.common.StringUtil;
import java.lang.reflect.Array;
import java.util.*;
/**
* <code>Class</code> 处理工具类
*
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ClassUtil {
/** 资源文件的分隔符: <code>'/'</code>。 */
public static final char RESOURCE_SEPARATOR_CHAR = '/';
/** Java类名的分隔符: <code>'.'</code>。 */
public static final char PACKAGE_SEPARATOR_CHAR = '.';
/** Java类名的分隔符: <code>"."</code>。 */
public static final String PACKAGE_SEPARATOR = String.valueOf(PACKAGE_SEPARATOR_CHAR);
/** 内联类的分隔符: <code>'$'</code>。 */
public static final char INNER_CLASS_SEPARATOR_CHAR = '$';
/** 内联类的分隔符: <code>"$"</code>。 */
public static final String INNER_CLASS_SEPARATOR = String
.valueOf(INNER_CLASS_SEPARATOR_CHAR);
/** 所有类的信息表,包括父类, 接口, 数组的维数等信息。 */
private static Map TYPE_MAP = Collections
.synchronizedMap(new WeakHashMap());
/* ============================================================================ */
/* 取得类名和package名的方法。 */
/* ============================================================================ */
/**
* 取得对象所属的类的直观类名。
*
* <p>
* 相当于 <code>object.getClass().getName()</code> ,但不同的是,该方法用更直观的方式显示数组类型。 例如:
* <pre>
* int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
*
* Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
* </pre>
* </p>
*
* <p>
* 对于非数组的类型,该方法等效于 <code>Class.getName()</code> 方法。
* </p>
*
* <p>
* 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 <code>Class.forName</code> 操作。
* </p>
*
* @param object 要显示类名的对象
*
* @return 用于显示的直观类名,如果原类名为空或非法,则返回 <code>null</code>
*/
public static String getClassNameForObject(Object object) {
if (object == null) {
return null;
}
return getClassName(object.getClass().getName(), true);
}
/**
* 取得直观的类名。
*
* <p>
* 相当于 <code>clazz.getName()</code> ,但不同的是,该方法用更直观的方式显示数组类型。 例如:
* <pre>
* int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
*
* Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
* </pre>
* </p>
*
* <p>
* 对于非数组的类型,该方法等效于 <code>Class.getName()</code> 方法。
* </p>
*
* <p>
* 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 <code>Class.forName</code> 操作。
* </p>
*
* @param clazz 要显示类名的类
*
* @return 用于显示的直观类名,如果原始类为 <code>null</code> ,则返回 <code>null</code>
*/
public static String getClassName(Class clazz) {
if (clazz == null) {
return null;
}
return getClassName(clazz.getName(), true);
}
/**
* 取得直观的类名。
*
* <p>
* <code>className</code> 必须是从 <code>clazz.getName()</code> 所返回的合法类名。该方法用更直观的方式显示数组类型。 例如:
* <pre>
* int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
*
* Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
* </pre>
* </p>
*
* <p>
* 对于非数组的类型,该方法等效于 <code>Class.getName()</code> 方法。
* </p>
*
* <p>
* 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 <code>Class.forName</code> 操作。
* </p>
*
* @param className 要显示的类名
*
* @return 用于显示的直观类名,如果原类名为 <code>null</code> ,则返回 <code>null</code> ,如果原类名是非法的,则返回原类名
*/
public static String getClassName(String className) {
return getClassName(className, true);
}
/**
* 取得直观的类名。
*
* @param className 类名
* @param processInnerClass 是否将内联类分隔符 <code>'$'</code> 转换成 <code>'.'</code>
*
* @return 直观的类名,或 <code>null</code>
*/
private static String getClassName(String className, boolean processInnerClass) {
if (StringUtil.isEmpty(className)) {
return className;
}
if (processInnerClass) {
className = className.replace(INNER_CLASS_SEPARATOR_CHAR, PACKAGE_SEPARATOR_CHAR);
}
int length = className.length();
int dimension = 0;
// 取得数组的维数,如果不是数组,维数为0
for (int i = 0; i < length; i++, dimension++) {
if (className.charAt(i) != '[') {
break;
}
}
// 如果不是数组,则直接返回
if (dimension == 0) {
return className;
}
// 确保类名合法
if (length <= dimension) {
return className; // 非法类名
}
// 处理数组
StringBuffer componentTypeName = new StringBuffer();
switch (className.charAt(dimension)) {
case 'Z':
componentTypeName.append("boolean");
break;
case 'B':
componentTypeName.append("byte");
break;
case 'C':
componentTypeName.append("char");
break;
case 'D':
componentTypeName.append("double");
break;
case 'F':
componentTypeName.append("float");
break;
case 'I':
componentTypeName.append("int");
break;
case 'J':
componentTypeName.append("long");
break;
case 'S':
componentTypeName.append("short");
break;
case 'L':
if ((className.charAt(length - 1) != ';') || (length <= (dimension + 2))) {
return className; // 非法类名
}
componentTypeName.append(className.substring(dimension + 1, length - 1));
break;
default:
return className; // 非法类名
}
for (int i = 0; i < dimension; i++) {
componentTypeName.append("[]");
}
return componentTypeName.toString();
}
/**
* 取得指定对象所属的类的短类名,不包括package名。
*
* <p>
* 此方法可以正确显示数组和内联类的名称。
* </p>
*
* <p>
* 例如:
* <pre>
* ClassUtil.getShortClassNameForObject(Boolean.TRUE) = "Boolean" ClassUtil.getShortClassNameForObject(new Boolean[10]) = "Boolean[]" ClassUtil.getShortClassNameForObject(new int[1][2]) = "int[][]"
* </pre>
* </p>
*
* @param object 要查看的对象
*
* @return 短类名,如果对象为 <code>null</code> ,则返回 <code>null</code>
*/
public static String getShortClassNameForObject(Object object) {
if (object == null) {
return null;
}
return getShortClassName(object.getClass().getName());
}
/**
* 取得短类名,不包括package名。
*
* <p>
* 此方法可以正确显示数组和内联类的名称。
* </p>
*
* <p>
* 例如:
* <pre>
* ClassUtil.getShortClassName(Boolean.class) = "Boolean" ClassUtil.getShortClassName(Boolean[].class) = "Boolean[]" ClassUtil.getShortClassName(int[][].class) = "int[][]" ClassUtil.getShortClassName(Map.Entry.class) = "Map.Entry"
* </pre>
* </p>
*
* @param clazz 要查看的类
*
* @return 短类名,如果类为 <code>null</code> ,则返回 <code>null</code>
*/
public static String getShortClassName(Class clazz) {
if (clazz == null) {
return null;
}
return getShortClassName(clazz.getName());
}
/**
* 取得类名,不包括package名。
*
* <p>
* 此方法可以正确显示数组和内联类的名称。
* </p>
*
* <p>
* 例如:
* <pre>
* ClassUtil.getShortClassName(Boolean.class.getName()) = "Boolean" ClassUtil.getShortClassName(Boolean[].class.getName()) = "Boolean[]" ClassUtil.getShortClassName(int[][].class.getName()) = "int[][]" ClassUtil.getShortClassName(Map.Entry.class.getName()) = "Map.Entry"
* </pre>
* </p>
*
* @param className 要查看的类名
*
* @return 短类名,如果类名为空,则返回 <code>null</code>
*/
public static String getShortClassName(String className) {
if (StringUtil.isEmpty(className)) {
return className;
}
// 转换成直观的类名
className = getClassName(className, false);
char[] chars = className.toCharArray();
int lastDot = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == PACKAGE_SEPARATOR_CHAR) {
lastDot = i + 1;
} else if (chars[i] == INNER_CLASS_SEPARATOR_CHAR) {
chars[i] = PACKAGE_SEPARATOR_CHAR;
}
}
return new String(chars, lastDot, chars.length - lastDot);
}
/**
* 取得指定对象所属的类的package名。
*
* <p>
* 对于数组,此方法返回的是数组元素类型的package名。
* </p>
*
* @param object 要查看的对象
*
* @return package名,如果对象为 <code>null</code> ,则返回 <code>null</code>
*/
public static String getPackageNameForObject(Object object) {
if (object == null) {
return null;
}
return getPackageName(object.getClass().getName());
}
/**
* 取得指定类的package名。
*
* <p>
* 对于数组,此方法返回的是数组元素类型的package名。
* </p>
*
* @param clazz 要查看的类
*
* @return package名,如果类为 <code>null</code> ,则返回 <code>null</code>
*/
public static String getPackageName(Class clazz) {
if (clazz == null) {
return null;
}
return getPackageName(clazz.getName());
}
/**
* 取得指定类名的package名。
*
* <p>
* 对于数组,此方法返回的是数组元素类型的package名。
* </p>
*
* @param className 要查看的类名
*
* @return package名,如果类名为空,则返回 <code>null</code>
*/
public static String getPackageName(String className) {
if (StringUtil.isEmpty(className)) {
return null;
}
// 转换成直观的类名
className = getClassName(className, false);
int i = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR);
if (i == -1) {
return "";
}
return className.substring(0, i);
}
/* ============================================================================ */
/* 取得类名和package名的resource名的方法。 */
/* */
/* 和类名、package名不同的是,resource名符合文件名命名规范,例如: */
/* java/lang/String.class */
/* com/alibaba/commons/lang */
/* etc. */
/* ============================================================================ */
/**
* 取得对象所属的类的资源名。
*
* <p>
* 例如:
* <pre>
* ClassUtil.getClassNameForObjectAsResource("This is a string") = "java/lang/String.class"
* </pre>
* </p>
*
* @param object 要显示类名的对象
*
* @return 指定对象所属类的资源名,如果对象为空,则返回<code>null</code>
*/
public static String getClassNameForObjectAsResource(Object object) {
if (object == null) {
return null;
}
return object.getClass().getName().replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR)
+ ".class";
}
/**
* 取得指定类的资源名。
*
* <p>
* 例如:
* <pre>
* ClassUtil.getClassNameAsResource(String.class) = "java/lang/String.class"
* </pre>
* </p>
*
* @param clazz 要显示类名的类
*
* @return 指定类的资源名,如果指定类为空,则返回<code>null</code>
*/
public static String getClassNameAsResource(Class clazz) {
if (clazz == null) {
return null;
}
return clazz.getName().replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR) + ".class";
}
/**
* 取得指定类的资源名。
*
* <p>
* 例如:
* <pre>
* ClassUtil.getClassNameAsResource("java.lang.String") = "java/lang/String.class"
* </pre>
* </p>
*
* @param className 要显示的类名
*
* @return 指定类名对应的资源名,如果指定类名为空,则返回<code>null</code>
*/
public static String getClassNameAsResource(String className) {
if (className == null) {
return null;
}
return className.replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR) + ".class";
}
/**
* 取得指定对象所属的类的package名的资源名。
*
* <p>
* 对于数组,此方法返回的是数组元素类型的package名。
* </p>
*
* @param object 要查看的对象
*
* @return package名,如果对象为 <code>null</code> ,则返回 <code>null</code>
*/
public static String getPackageNameForObjectAsResource(Object object) {
if (object == null) {
return null;
}
return getPackageNameForObject(object).replace(PACKAGE_SEPARATOR_CHAR,
RESOURCE_SEPARATOR_CHAR);
}
/**
* 取得指定类的package名的资源名。
*
* <p>
* 对于数组,此方法返回的是数组元素类型的package名。
* </p>
*
* @param clazz 要查看的类
*
* @return package名,如果类为 <code>null</code> ,则返回 <code>null</code>
*/
public static String getPackageNameAsResource(Class clazz) {
if (clazz == null) {
return null;
}
return getPackageName(clazz).replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR);
}
/**
* 取得指定类名的package名的资源名。
*
* <p>
* 对于数组,此方法返回的是数组元素类型的package名。
* </p>
*
* @param className 要查看的类名
*
* @return package名,如果类名为空,则返回 <code>null</code>
*/
public static String getPackageNameAsResource(String className) {
if (className == null) {
return null;
}
return getPackageName(className).replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR);
}
/* ============================================================================ */
/* 取得类的信息,如父类, 接口, 数组的维数等。 */
/* ============================================================================ */
/**
* 取得指定维数的 <code>Array</code>类.
*
* @param componentType 数组的基类
* @param dimension 维数,如果小于 <code>0</code> 则看作 <code>0</code>
*
* @return 如果维数为0, 则返回基类本身, 否则返回数组类,如果数组的基类为 <code>null</code> ,则返回 <code>null</code>
*/
public static Class getArrayClass(Class componentType, int dimension) {
if (dimension <= 0) {
return componentType;
}
if (componentType == null) {
return null;
}
return Array.newInstance(componentType, new int[dimension]).getClass();
}
/**
* 取得数组元素的类型。
*
* @param type 要查找的类
*
* @return 如果是数组, 则返回数组元素的类型, 否则返回 <code>null</code>
*/
public static Class getArrayComponentType(Class type) {
if (type == null) {
return null;
}
return getTypeInfo(type).getArrayComponentType();
}
/**
* 取得数组的维数。
*
* @param clazz 要查找的类
*
* @return 数组的维数. 如果不是数组, 则返回 <code>0</code> ,如果数组为 <code>null</code> ,是返回 <code>-1</code>
*/
public static int getArrayDimension(Class clazz) {
if (clazz == null) {
return -1;
}
return getTypeInfo(clazz).getArrayDimension();
}
/**
* 取得指定类的所有父类。
*
* <p>
* 对于一个 <code>Class</code> 实例,如果它不是接口,也不是数组,此方法依次列出从该类的父类开始直到 <code>Object</code> 的所有类。
* </p>
*
* <p>
* 例如 <code>ClassUtil.getSuperclasses(java.util.ArrayList.class)</code> 返回以下列表:
*
* <ol>
* <li>
* <code>java.util.AbstractList</code>
* </li>
* <li>
* <code>java.util.AbstractCollection</code>
* </li>
* <li>
* <code>java.lang.Object</code>
* </li>
* </ol>
* </p>
*
* <p>
* 对于一个接口,此方法返回一个空列表。
* </p>
*
* <p>
* 例如<code>ClassUtil.getSuperclasses(java.util.List.class)</code>将返回一个空列表。
* </p>
*
* <p>
* 对于一个数组,此方法返回一个列表,列出所有component类型的父类的相同维数的数组类型。 例如:
* <code>ClassUtil.getSuperclasses(java.util.ArrayList[][].class)</code> 返回以下列表:
*
* <ol>
* <li>
* <code>java.util.AbstractList[][]</code>
* </li>
* <li>
* <code>java.util.AbstractCollection[][]</code>
* </li>
* <li>
* <code>java.lang.Object[][]</code>
* </li>
* <li>
* <code>java.lang.Object[]</code>
* </li>
* <li>
* <code>java.lang.Object</code>
* </li>
* </ol>
*
* 注意,原子类型及其数组,将被转换成相应的包装类来处理。 例如: <code>ClassUtil.getSuperclasses(int[][].class)</code>
* 返回以下列表:
*
* <ol>
* <li>
* <code>java.lang.Number[][]</code>
* </li>
* <li>
* <code>java.lang.Object[][]</code>
* </li>
* <li>
* <code>java.lang.Object[]</code>
* </li>
* <li>
* <code>java.lang.Object</code>
* </li>
* </ol>
* </p>
*
* @param clazz 要查找的类
*
* @return 所有父类的列表,如果指定类为 <code>null</code> ,则返回 <code>null</code>
*/
public static List getSuperclasses(Class clazz) {
if (clazz == null) {
return null;
}
return getTypeInfo(clazz).getSuperclasses();
}
/**
* 取得指定类的所有接口。
*
* <p>
* 对于一个 <code>Class</code> 实例,如果它不是接口,也不是数组,此方法依次列出从该类的父类开始直到 <code>Object</code> 的所有类。
* </p>
*
* <p>
* 例如 <code>ClassUtil.getInterfaces(java.util.ArrayList.class)</code> 返回以下列表:
*
* <ol>
* <li>
* <code>java.util.List</code>
* </li>
* <li>
* <code>java.util.Collection</code>
* </li>
* <li>
* <code>java.util.RandomAccess</code>
* </li>
* <li>
* <code>java.lang.Cloneable</code>
* </li>
* <li>
* <code>java.io.Serializable</code>
* </li>
* </ol>
* </p>
*
* <p>
* 对于一个数组,此方法返回一个列表,列出所有component类型的接口的相同维数的数组类型。 例如:
* <code>ClassUtil.getInterfaces(java.util.ArrayList[][].class)</code> 返回以下列表:
*
* <ol>
* <li>
* <code>java.util.List[][]</code>
* </li>
* <li>
* <code>java.util.Collection[][]</code>
* </li>
* <li>
* <code>java.util.RandomAccess[][]</code>
* </li>
* <li>
* <code>java.lang.Cloneable[][]</code>
* </li>
* <li>
* <code>java.io.Serializable[][]</code>
* </li>
* </ol>
* </p>
*
* <p>
* 注意,原子类型及其数组,将被转换成相应的包装类来处理。 例如: <code>ClassUtil.getInterfaces(int[][].class)</code> 返回以下列表:
*
* <ol>
* <li>
* <code>java.lang.Comparable[][]</code>
* </li>
* <li>
* <code>java.io.Serializable[][]</code>
* </li>
* </ol>
* </p>
*
* @param clazz 要查找的类
*
* @return 所有接口的列表,如果指定类为 <code>null</code> ,则返回 <code>null</code>
*/
public static List getInterfaces(Class clazz) {
if (clazz == null) {
return null;
}
return getTypeInfo(clazz).getInterfaces();
}
/**
* 判断指定类是否为内联类。
*
* @param clazz 要查找的类
*
* @return 如果是,则返回 <code>true</code>
*/
public static boolean isInnerClass(Class clazz) {
if (clazz == null) {
return false;
}
return StringUtil.contains(clazz.getName(), INNER_CLASS_SEPARATOR_CHAR);
}
/**
* 检查一组指定类型 <code>fromClasses</code> 的对象是否可以赋值给另一组类型 <code>classes</code>。
*
* <p>
* 此方法可以用来确定指定类型的参数 <code>object1, object2, ...</code> 是否可以用来调用确定参数类型为 <code>class1, class2,
* ...</code> 的方法。
* </p>
*
* <p>
* 对于 <code>fromClasses</code> 的每个元素 <code>fromClass</code> 和 <code>classes</code> 的每个元素
* <code>clazz</code>, 按照如下规则:
*
* <ol>
* <li>
* 如果目标类 <code>clazz</code> 为 <code>null</code> ,总是返回 <code>false</code>。
* </li>
* <li>
* 如果参数类型 <code>fromClass</code> 为 <code>null</code> ,并且目标类型 <code>clazz</code> 为非原子类型,则返回
* <code>true</code>。 因为 <code>null</code> 可以被赋给任何引用类型。
* </li>
* <li>
* 调用 <code>Class.isAssignableFrom</code> 方法来确定目标类 <code>clazz</code> 是否和参数类
* <code>fromClass</code> 相同或是其父类、接口,如果是,则返回 <code>true</code>。
* </li>
* <li>
* 如果目标类型 <code>clazz</code> 为原子类型,那么根据 <a href="http://java.sun.com/docs/books/jls/">The Java
* Language Specification</a> ,sections 5.1.1, 5.1.2, 5.1.4定义的Widening Primitive
* Conversion规则,参数类型 <code>fromClass</code> 可以是任何能扩展成该目标类型的原子类型及其包装类。 例如, <code>clazz</code> 为
* <code>long</code> ,那么参数类型可以是 <code>byte</code>、
* <code>short</code>、<code>int</code>、<code>long</code>、<code>char</code> 及其包装类
* <code>java.lang.Byte</code>、<code>java.lang.Short</code>、<code>java.lang.Integer</code>、
* <code>java.lang.Long</code> 和 <code>java.lang.Character</code> 。如果满足这个条件,则返回
* <code>true</code>。
* </li>
* <li>
* 不满足上述所有条件,则返回 <code>false</code>。
* </li>
* </ol>
* </p>
*
* @param classes 目标类型列表,如果是 <code>null</code> 总是返回 <code>false</code>
* @param fromClasses 参数类型列表, <code>null</code> 表示可赋值给任意非原子类型
*
* @return 如果可以被赋值,则返回 <code>true</code>
*/
public static boolean isAssignable(Class[] classes, Class[] fromClasses) {
if (!ArrayUtil.isSameLength(fromClasses, classes)) {
return false;
}
if (fromClasses == null) {
fromClasses = ArrayUtil.EMPTY_CLASS_ARRAY;
}
if (classes == null) {
classes = ArrayUtil.EMPTY_CLASS_ARRAY;
}
for (int i = 0; i < fromClasses.length; i++) {
if (isAssignable(classes[i], fromClasses[i]) == false) {
return false;
}
}
return true;
}
/**
* 检查指定类型 <code>fromClass</code> 的对象是否可以赋值给另一种类型 <code>clazz</code>。
*
* <p>
* 此方法可以用来确定指定类型的参数 <code>object1, object2, ...</code> 是否可以用来调用确定参数类型 <code>class1, class2,
* ...</code> 的方法。
* </p>
*
* <p>
* 按照如下规则:
*
* <ol>
* <li>
* 如果目标类 <code>clazz</code> 为 <code>null</code> ,总是返回 <code>false</code>。
* </li>
* <li>
* 如果参数类型 <code>fromClass</code> 为 <code>null</code> ,并且目标类型 <code>clazz</code> 为非原子类型,则返回
* <code>true</code>。 因为 <code>null</code> 可以被赋给任何引用类型。
* </li>
* <li>
* 调用 <code>Class.isAssignableFrom</code> 方法来确定目标类 <code>clazz</code> 是否和参数类
* <code>fromClass</code> 相同或是其父类、接口,如果是,则返回 <code>true</code>。
* </li>
* <li>
* 如果目标类型 <code>clazz</code> 为原子类型,那么根据 <a href="http://java.sun.com/docs/books/jls/">The Java
* Language Specification</a> ,sections 5.1.1, 5.1.2, 5.1.4定义的Widening Primitive
* Conversion规则,参数类型 <code>fromClass</code> 可以是任何能扩展成该目标类型的原子类型及其包装类。 例如, <code>clazz</code> 为
* <code>long</code> ,那么参数类型可以是 <code>byte</code>、
* <code>short</code>、<code>int</code>、<code>long</code>、<code>char</code> 及其包装类
* <code>java.lang.Byte</code>、<code>java.lang.Short</code>、<code>java.lang.Integer</code>、
* <code>java.lang.Long</code> 和 <code>java.lang.Character</code> 。如果满足这个条件,则返回
* <code>true</code>。
* </li>
* <li>
* 不满足上述所有条件,则返回 <code>false</code>。
* </li>
* </ol>
* </p>
*
* @param clazz 目标类型,如果是 <code>null</code> 总是返回 <code>false</code>
* @param fromClass 参数类型, <code>null</code> 表示可赋值给任意非原子类型
*
* @return 如果可以被赋值,则返回 <code>null</code>
*/
public static boolean isAssignable(Class clazz, Class fromClass) {
if (clazz == null) {
return false;
}
// 如果fromClass是null,只要clazz不是原子类型如int,就一定可以赋值
if (fromClass == null) {
return !clazz.isPrimitive();
}
// 如果类相同或有父子关系,当然可以赋值
if (clazz.isAssignableFrom(fromClass)) {
return true;
}
// 对于原子类型,根据JLS的规则进行扩展
// 目标class为原子类型时,fromClass可以为原子类型和原子类型的包装类型。
if (clazz.isPrimitive()) {
// boolean可以接受:boolean
if (Boolean.TYPE.equals(clazz)) {
return Boolean.class.equals(fromClass);
}
// byte可以接受:byte
if (Byte.TYPE.equals(clazz)) {
return Byte.class.equals(fromClass);
}
// char可以接受:char
if (Character.TYPE.equals(clazz)) {
return Character.class.equals(fromClass);
}
// short可以接受:short, byte
if (Short.TYPE.equals(clazz)) {
return Short.class.equals(fromClass) || Byte.TYPE.equals(fromClass)
|| Byte.class.equals(fromClass);
}
// int可以接受:int、byte、short、char
if (Integer.TYPE.equals(clazz)) {
return Integer.class.equals(fromClass) || Byte.TYPE.equals(fromClass)
|| Byte.class.equals(fromClass) || Short.TYPE.equals(fromClass)
|| Short.class.equals(fromClass) || Character.TYPE.equals(fromClass)
|| Character.class.equals((fromClass));
}
// long可以接受:long、int、byte、short、char
if (Long.TYPE.equals(clazz)) {
return Long.class.equals(fromClass) || Integer.TYPE.equals(fromClass)
|| Integer.class.equals(fromClass) || Byte.TYPE.equals(fromClass)
|| Byte.class.equals(fromClass) || Short.TYPE.equals(fromClass)
|| Short.class.equals(fromClass) || Character.TYPE.equals(fromClass)
|| Character.class.equals((fromClass));
}
// float可以接受:float, long, int, byte, short, char
if (Float.TYPE.equals(clazz)) {
return Float.class.equals(fromClass) || Long.TYPE.equals(fromClass)
|| Long.class.equals(fromClass) || Integer.TYPE.equals(fromClass)
|| Integer.class.equals(fromClass) || Byte.TYPE.equals(fromClass)
|| Byte.class.equals(fromClass) || Short.TYPE.equals(fromClass)
|| Short.class.equals(fromClass) || Character.TYPE.equals(fromClass)
|| Character.class.equals((fromClass));
}
// double可以接受:double, float, long, int, byte, short, char
if (Double.TYPE.equals(clazz)) {
return Double.class.equals(fromClass) || Float.TYPE.equals(fromClass)
|| Float.class.equals(fromClass) || Long.TYPE.equals(fromClass)
|| Long.class.equals(fromClass) || Integer.TYPE.equals(fromClass)
|| Integer.class.equals(fromClass) || Byte.TYPE.equals(fromClass)
|| Byte.class.equals(fromClass) || Short.TYPE.equals(fromClass)
|| Short.class.equals(fromClass) || Character.TYPE.equals(fromClass)
|| Character.class.equals((fromClass));
}
}
return false;
}
/**
* 取得指定类的 <code>TypeInfo</code>。
*
* @param type 指定类或接口
*
* @return <code>TypeInfo</code> 对象.
*/
protected static TypeInfo getTypeInfo(Class type) {
if (type == null) {
throw new IllegalArgumentException("Parameter clazz should not be null");
}
TypeInfo classInfo;
synchronized (TYPE_MAP) {
classInfo = (TypeInfo) TYPE_MAP.get(type);
if (classInfo == null) {
classInfo = new TypeInfo(type);
TYPE_MAP.put(type, classInfo);
}
}
return classInfo;
}
/**
* 代表一个类的信息, 包括父类, 接口, 数组的维数等.
*/
protected static class TypeInfo {
private Class type;
private Class componentType;
private int dimension;
private List superclasses = new ArrayList(2);
private List interfaces = new ArrayList(2);
/**
* 创建 <code>TypeInfo</code>。
*
* @param type 创建指定类的 <code>TypeInfo</code>
*/
private TypeInfo(Class type) {
this.type = type;
// 如果是array, 设置componentType和dimension
Class componentType = null;
if (type.isArray()) {
componentType = type;
do {
componentType = componentType.getComponentType();
dimension++;
} while (componentType.isArray());
}
this.componentType = componentType;
// 取得所有superclass
if (dimension > 0) {
// 将primitive类型转换成对应的包装类
componentType = getNonPrimitiveType(componentType);
Class superComponentType = componentType.getSuperclass();
// 如果是primitive, interface, 则设置其基类为Object.
if ((superComponentType == null) && !Object.class.equals(componentType)) {
superComponentType = Object.class;
}
if (superComponentType != null) {
Class superclass = getArrayClass(superComponentType, dimension);
superclasses.add(superclass);
superclasses.addAll(getTypeInfo(superclass).superclasses);
} else {
for (int i = dimension - 1; i >= 0; i--) {
superclasses.add(getArrayClass(Object.class, i));
}
}
} else {
// 将primitive类型转换成对应的包装类
type = getNonPrimitiveType(type);
Class superclass = type.getSuperclass();
if (superclass != null) {
superclasses.add(superclass);
superclasses.addAll(getTypeInfo(superclass).superclasses);
}
}
// 取得所有interface
if (dimension == 0) {
Class[] typeInterfaces = type.getInterfaces();
List set = new ArrayList();
for (int i = 0; i < typeInterfaces.length; i++) {
Class typeInterface = typeInterfaces[i];
set.add(typeInterface);
set.addAll(getTypeInfo(typeInterface).interfaces);
}
for (Iterator i = superclasses.iterator(); i.hasNext();) {
Class typeInterface = (Class) i.next();
set.addAll(getTypeInfo(typeInterface).interfaces);
}
for (Iterator i = set.iterator(); i.hasNext();) {
Class interfaceClass = (Class) i.next();
if (!interfaces.contains(interfaceClass)) {
interfaces.add(interfaceClass);
}
}
} else {
for (Iterator i = getTypeInfo(componentType).interfaces.iterator(); i.hasNext();) {
Class componentInterface = (Class) i.next();
interfaces.add(getArrayClass(componentInterface, dimension));
}
}
}
/**
* 将所有的原子类型转换成对应的包装类,其它类型不变。
*
* @param type 要转换的类型
*
* @return 非原子类型
*/
private Class getNonPrimitiveType(Class type) {
if (type.isPrimitive()) {
if (Integer.TYPE.equals(type)) {
type = Integer.class;
} else if (Long.TYPE.equals(type)) {
type = Long.class;
} else if (Short.TYPE.equals(type)) {
type = Short.class;
} else if (Byte.TYPE.equals(type)) {
type = Byte.class;
} else if (Float.TYPE.equals(type)) {
type = Float.class;
} else if (Double.TYPE.equals(type)) {
type = Double.class;
} else if (Boolean.TYPE.equals(type)) {
type = Boolean.class;
} else if (Character.TYPE.equals(type)) {
type = Character.class;
}
}
return type;
}
/**
* 取得 <code>TypeInfo</code> 所代表的java类。
*
* @return <code>TypeInfo</code> 所代表的java类
*/
public Class getType() {
return type;
}
/**
* 取得数组元素的类型。
*
* @return 如果是数组, 则返回数组元素的类型, 否则返回 <code>null</code>
*/
public Class getArrayComponentType() {
return componentType;
}
/**
* 取得数组的维数。
*
* @return 数组的维数. 如果不是数组, 则返回 <code>0</code>
*/
public int getArrayDimension() {
return dimension;
}
/**
* 取得所有的父类。
*
* @return 所有的父类
*/
public List getSuperclasses() {
return Collections.unmodifiableList(superclasses);
}
/**
* 取得所有的接口。
*
* @return 所有的接口
*/
public List getInterfaces() {
return Collections.unmodifiableList(interfaces);
}
}
/* ============================================================================ */
/* 有关primitive类型的方法。 */
/* ============================================================================ */
/**
* 返回指定类型所对应的primitive类型。
*
* @param clazz 要检查的类型
*
* @return 如果指定类型为<code>null</code>或不是primitive类型的包装类,则返回<code>null</code>,否则返回相应的primitive类型。
*/
public static Class<?> getPrimitiveType(Class<?> clazz) {
if (clazz == null) {
return null;
}
if (clazz.isPrimitive()) {
return clazz;
}
if (clazz.equals(Long.class)) {
return long.class;
}
if (clazz.equals(Integer.class)) {
return int.class;
}
if (clazz.equals(Short.class)) {
return short.class;
}
if (clazz.equals(Byte.class)) {
return byte.class;
}
if (clazz.equals(Double.class)) {
return double.class;
}
if (clazz.equals(Float.class)) {
return float.class;
}
if (clazz.equals(Boolean.class)) {
return boolean.class;
}
if (clazz.equals(Character.class)) {
return char.class;
}
return null;
}
/**
* 返回指定类型所对应的非primitive类型。
*
* @param clazz 要检查的类型
*
* @return 如果指定类型为<code>null</code>,则返回<code>null</code>,如果是primitive类型,则返回相应的包装类,否则返回原始的类型。
*/
public static Class<?> getNonPrimitiveType(Class<?> clazz) {
if (clazz == null) {
return null;
}
if (!clazz.isPrimitive()) {
return clazz;
}
if (clazz.equals(long.class)) {
return Long.class;
}
if (clazz.equals(int.class)) {
return Integer.class;
}
if (clazz.equals(short.class)) {
return Short.class;
}
if (clazz.equals(byte.class)) {
return Byte.class;
}
if (clazz.equals(double.class)) {
return Double.class;
}
if (clazz.equals(float.class)) {
return Float.class;
}
if (clazz.equals(boolean.class)) {
return Boolean.class;
}
if (clazz.equals(char.class)) {
return Character.class;
}
return null;
}
}
/**
* Copyright (c) 2011-2014 All Rights Reserved.
*/
package com.jz.dm.gateway.common.util;
/**
* @author Admin
* @version $Id: Constants.java 2014年9月3日 下午9:03:44 $
*/
public class Constants {
/**
* 默认时间格式
**/
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_FORMAT = "yyyyMMdd";
/**
* 密码的正则表达式
*/
public static final String PASSWORD_EXG = "^(?![^a-zA-Z]+$)(?!\\D+$).{8,30}$";
/**
* UTF-8字符集
**/
public static final String CHARSET_UTF8 = "UTF-8";
/**
* Date默认时区
**/
public static final String DATE_TIMEZONE = "GMT+8";
public static final String PRINCIPAL_NAME_ATTRIBUTE_OMSNAME = ".OMS_PRINCIPAL_NAME_ATTRIBUTE_NAME";
public static final String PRINCIPAL_NAME_ATTRIBUTE_MCHNAME = ".MCH_PRINCIPAL_NAME_ATTRIBUTE_NAME";
public static final String PRINCIPAL_NAME_ATTRIBUTE_PROXYNAME = ".PROXY_PRINCIPAL_NAME_ATTRIBUTE_NAME";
public static final String PRINCIPAL_NAME_ATTRIBUTE_SUPNAME = ".SUPPLIER_PRINCIPAL_NAME_ATTRIBUTE_NAME";
public static final String PERMISSIONS = "permissions";
/**
* 登录成功后,继续跳转URL
*/
public static final String GOTO_KEY = "to";
/**
* 记录密码控件的密钥key
*/
public final static String TOKEN = "token_%s";
// http请求头UA参数
public static final String UA = "user-agent";
//缓存名称
public static final String MEMBER_CACHE_NAME = "data:members";
public static final String MERCHANT_CACHE_NAME = "data:merchants";
public static final String SECRET_CACHE_NAME = "data:secret_keys";
public static final String ADDR_CACHE_NAME = "data:addrs";
public static final String PRODUCT_CACHE_NAME = "data:products";
public static final String API_WHITE_CACHE_NAME = "data:apiwhite";
//数据库序列名称
public static final String SEQ_ACCOUNT = "ids:accounts";
public static final String SEQ_ACCOUNT_WATER = "ids:accounts:water";
//public static final String SEQ_MEMBER = "ids:members";
public static final String SEQ_RECHARGE = "ids:recharges:loop:7";
public static final String SEQ_TRADE_ORDER = "ids:tradeorders:loop:7";
public static final String SEQ_PAYMENT = "ids:payment:loop:7";
public static final String SEQ_WITHDRAW = "ids:withdraws:loop:7";
public static final String SEQ_TRANSFER = "ids:transfer:loop:7";
/**
* key = 产线名:服务名:用途:数据类型:key
*/
public static final String VALID_CODE_KEY_PREFIX = "data:merchants:valid:string:";
public static final String VALID_CODE_KEY_COUNT_PREFIX = "data:merchants:valid:long:";
/** 短信签约缓存名称 **/
public static final String SMS_SIGN_KEY_PREFIX = "data:smssign:shortcode:string:";
public static final String SMS_SIGN_VALID_CODE_PREFIX = "data:smssign:validcode:string:";
public static final String SMS_SIGN_VALID_CODE_LIMIT_PREFIX = "data:smssign:validlimit:string:";
public static final String SMS_BROKER_VALID_CODE_PREFIX = "data:smsbroker:valid:string:";
/**
* 发送短信验证
*/
public static final String SEND_PAY_VALID_CODE = "sendPayValidCode";
public static final String SEND_EDIT_PASSWORD_VALID_CODE = "sendPasswordValidCode";
public static final String SEND_SIGN_VALID_CODE = "sendSignValidCode";
public static final String SMS_BROKER_VALID_CODE_TEMPLATE = "sendBrokerValidCode";
/**
* 代理商分润汇总key
*/
public static final String PROXY_ALL_FEE_SUMMARY = "PROXY_ALL_FEE_SUMMARY";
public static final String PROXYER_Fee = "PROXYER_Fee";
public static final String MERCHANT_Fee = "MERCHANT_Fee";
}
package com.jz.dm.gateway.common.util;
import com.jz.dm.gateway.common.StringUtil;
import java.util.HashMap;
import java.util.Map;
/**
* HDD HashMap
*
*/
public class HddHashMap extends HashMap<String, String> {
private static final long serialVersionUID = -3440305725602261736L;
public HddHashMap() {
super();
}
public HddHashMap(Map<? extends String, ? extends String> map) {
super(map);
}
/**
* if key or value is null, not put into hash map
*
* @see HashMap#put(Object, Object)
*/
@Override
public String put(String key, String value) {
if (StringUtil.isNotEmpty(key, value)) {
return super.put(key, value);
} else {
return null;
}
}
}
package com.jz.dm.gateway.common.util;
import com.jz.dm.gateway.common.util.Constants;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.CharacterIterator;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.StringCharacterIterator;
import java.util.*;
public class JSONWriter {
private StringBuffer buf = new StringBuffer();
private Stack<Object> calls = new Stack<Object>();
private boolean emitClassName = true;
private DateFormat format;
public JSONWriter(boolean emitClassName) {
this.emitClassName = emitClassName;
}
public JSONWriter() {
this(false);
}
public JSONWriter(DateFormat format) {
this(false);
this.format = format;
}
public String write(Object object) {
buf.setLength(0);
value(object);
return buf.toString();
}
public String write(long n) {
return String.valueOf(n);
}
public String write(double d) {
return String.valueOf(d);
}
public String write(char c) {
return "\"" + c + "\"";
}
public String write(boolean b) {
return String.valueOf(b);
}
private void value(Object object) {
if (object == null || cyclic(object)) {
add(null);
} else {
calls.push(object);
if (object instanceof Class<?>) string(object);
else if (object instanceof Boolean) bool(((Boolean) object).booleanValue());
else if (object instanceof Number) add(object);
else if (object instanceof String) string(object);
else if (object instanceof Character) string(object);
else if (object instanceof Map<?, ?>) map((Map<?, ?>)object);
else if (object.getClass().isArray()) array(object);
else if (object instanceof Iterator<?>) array((Iterator<?>)object);
else if (object instanceof Collection<?>) array(((Collection<?>)object).iterator());
else if (object instanceof Date) date((Date)object);
else bean(object);
calls.pop();
}
}
private boolean cyclic(Object object) {
Iterator<Object> it = calls.iterator();
while (it.hasNext()) {
Object called = it.next();
if (object == called) return true;
}
return false;
}
private void bean(Object object) {
add("{");
BeanInfo info;
boolean addedSomething = false;
try {
info = Introspector.getBeanInfo(object.getClass());
PropertyDescriptor[] props = info.getPropertyDescriptors();
for (int i = 0; i < props.length; ++i) {
PropertyDescriptor prop = props[i];
String name = prop.getName();
Method accessor = prop.getReadMethod();
if ((emitClassName || !"class".equals(name)) && accessor != null) {
if (!accessor.isAccessible()) accessor.setAccessible(true);
Object value = accessor.invoke(object, (Object[])null);
if (value == null) continue;
if (addedSomething) add(',');
add(name, value);
addedSomething = true;
}
}
} catch (IllegalAccessException iae) {
} catch (InvocationTargetException ite) {
} catch (IntrospectionException ie) {
}
add("}");
}
private void add(String name, Object value) {
add('"');
add(name);
add("\":");
value(value);
}
private void map(Map<?, ?> map) {
add("{");
Iterator<?> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<?, ?> e = (Map.Entry<?, ?>) it.next();
value(e.getKey());
add(":");
value(e.getValue());
if (it.hasNext()) add(',');
}
add("}");
}
private void array(Iterator<?> it) {
add("[");
while (it.hasNext()) {
value(it.next());
if (it.hasNext()) add(",");
}
add("]");
}
private void array(Object object) {
add("[");
int length = Array.getLength(object);
for (int i = 0; i < length; ++i) {
value(Array.get(object, i));
if (i < length - 1) add(',');
}
add("]");
}
private void bool(boolean b) {
add(b ? "true" : "false");
}
private void date(Date date) {
if (this.format == null) {
this.format = new SimpleDateFormat(Constants.DATE_TIME_FORMAT);
this.format.setTimeZone(TimeZone.getTimeZone(Constants.DATE_TIMEZONE));
}
add("\"");
add(format.format(date));
add("\"");
}
private void string(Object obj) {
add('"');
CharacterIterator it = new StringCharacterIterator(obj.toString());
for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
if (c == '"') add("\\\"");
else if (c == '\\') add("\\\\");
else if (c == '/') add("\\/");
else if (c == '\b') add("\\b");
else if (c == '\f') add("\\f");
else if (c == '\n') add("\\n");
else if (c == '\r') add("\\r");
else if (c == '\t') add("\\t");
else if (Character.isISOControl(c)) {
unicode(c);
} else {
add(c);
}
}
add('"');
}
private void add(Object obj) {
buf.append(obj);
}
private void add(char c) {
buf.append(c);
}
static char[] hex = "0123456789ABCDEF".toCharArray();
private void unicode(char c) {
add("\\u");
int n = c;
for (int i = 0; i < 4; ++i) {
int digit = (n & 0xf000) >> 12;
add(hex[digit]);
n <<= 4;
}
}
}
package com.jz.dm.gateway.common.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.NameFilter;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Map;
/**
* Json工具类
*/
public class JsonUtil {
private static final ParserConfig PARSER_CONFIG = new ParserConfig();
static {
PARSER_CONFIG.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
}
private static final Map<PropertyNamingStrategy, NameFilter> NAME_FILTERS = new HashMap<PropertyNamingStrategy, NameFilter>();
static {
NAME_FILTERS.put(PropertyNamingStrategy.SnakeCase, new SnakeNameFilter());
NAME_FILTERS.put(PropertyNamingStrategy.CamelCase, new CamelNameFilter());
NAME_FILTERS.put(PropertyNamingStrategy.PascalCase, new PascalNameFilter());
NAME_FILTERS.put(PropertyNamingStrategy.KebabCase, new KebabNameFilter());
}
public static class SnakeNameFilter implements NameFilter {
/**
* @see NameFilter#process(Object, String, Object)
*/
@Override
public String process(Object object, String name, Object value) {
return PropertyNamingStrategy.SnakeCase.translate(name);
}
}
public static class CamelNameFilter implements NameFilter {
/**
* @see NameFilter#process(Object, String, Object)
*/
@Override
public String process(Object object, String name, Object value) {
return PropertyNamingStrategy.CamelCase.translate(name);
}
}
public static class PascalNameFilter implements NameFilter {
/**
* @see NameFilter#process(Object, String, Object)
*/
@Override
public String process(Object object, String name, Object value) {
return PropertyNamingStrategy.PascalCase.translate(name);
}
}
public static class KebabNameFilter implements NameFilter {
/**
* @see NameFilter#process(Object, String, Object)
*/
@Override
public String process(Object object, String name, Object value) {
return PropertyNamingStrategy.KebabCase.translate(name);
}
}
/**
* object serialize to string
*
* @param object
* @param strategy
* @return
*/
public static String toJSONString(Object object, PropertyNamingStrategy strategy) {
if (object == null) {
return null;
}
if (strategy == null) {
return JSON.toJSONString(object);
}
NameFilter nameFilter = NAME_FILTERS.get(strategy);
if (nameFilter == null) {
return JSON.toJSONString(object);
} else {
return JSON.toJSONString(object, nameFilter);
}
}
/**
* String转换为JSONObject对象
*
* @param data
* @return
*/
public static JSONObject stringToJsonObject(String data) {
if (StringUtils.isNotEmpty(data)) {
return JSONObject.parseObject(data);
}
return null;
}
}
package com.jz.dm.gateway.common.util;
import org.slf4j.Logger;
/**
* 日志打印工具
*
*/
public class LogUtil {
/** 摘要日志的内容分隔符 */
public static final String SEP = ",";
/** 修饰符 */
private static final char RIGHT_TAG = ']';
/** 修饰符 */
private static final char LEFT_TAG = '[';
/**
* 日志信息
*
*/
public interface LogInfo {
/**
* 获取日志信息
*
* @return 日志信息
*/
String getLogInfo();
}
/**
* 打印info日志。
*
* @param logger 日志对象
* @param objs 任意个要输出到日志的参数
*/
public static void info(Logger logger, Object... objs) {
if (logger.isInfoEnabled()) {
logger.info(getLogString(objs));
}
}
/**
* 打印info级别日志
*
* @param logger 日志对象
* @param logInfo 日志信息
*/
public static void info(Logger logger, LogInfo logInfo) {
if (logger.isInfoEnabled()) {
logger.info(logInfo.getLogInfo());
}
}
/**
* 打印info级别日志
*
* @param logger 日志对象
* @param e 异常信息
* @param objs 任意个要输出到日志的参数
*/
public static void info(Logger logger, Throwable e, Object... objs) {
if (logger.isInfoEnabled()) {
logger.info(getLogString(objs), e);
}
}
/**
* 打印warn级别日志
*
* @param logger 日志对象
* @param objs 任意个要输出到日志的参数
*/
public static void warn(Logger logger, Object... objs) {
logger.warn(getLogString(objs));
}
/**
* 打印warn级别日志
*
* @param logger 日志对象
* @param e 异常信息
* @param objs 任意个要输出到日志的参数
*/
public static void warn(Logger logger, Throwable e, Object... objs) {
logger.warn(getLogString(objs), e);
}
/**
* 打印error级别日志
*
* @param logger 日志对象
* @param e 异常信息
* @param objs 任意个要输出到日志的参数
*/
public static void error(Logger logger, Throwable e, Object... objs) {
logger.error(getLogString(objs), e);
}
/**
* 打印error级别日志
*
* @param logger 日志对象
* @param objs 任意个要输出到日志的参数
*/
public static void error(Logger logger, Object... objs) {
logger.error(getLogString(objs));
}
/**
* 打印debug日志。
*
* @param logger 日志对象
* @param objs 任意个要输出到日志的参数
*/
public static void debug(Logger logger, Object... objs) {
if (logger.isDebugEnabled()) {
logger.debug(getLogString(objs));
}
}
/**
* 打印debug日志。
*
* @param logger 日志对象
* @param e 异常信息
* @param objs 任意个要输出到日志的参数
*/
public static void debug(Logger logger, Throwable e, Object... objs) {
if (logger.isDebugEnabled()) {
logger.debug(getLogString(objs), e);
}
}
/**
* 生成输出到日志的字符串
*
* @param objs 任意个要输出到日志的参数
* @return 日志字符串
*/
public static String getLogString(Object... objs) {
StringBuilder log = new StringBuilder();
log.append(LEFT_TAG).append(getThreadId()).append(RIGHT_TAG);
for (Object o : objs) {
log.append(o).append(SEP);
}
return log.toString();
}
/**
* 获取线程id。
*
* @return 线程id
*/
public static String getThreadId() {
return String.valueOf(Thread.currentThread().getId());
}
}
package com.jz.dm.gateway.common.util;
import java.util.HashMap;
import java.util.Map;
/**
* 结果码
*
*/
public enum NotifyResultCode implements ResultCode {
/** 处理成功 */
SUCCESS("SUCCESS", "处理成功"),
/** 处理失败 */
FAILED("FAILED", "处理失败"),
/** 未知异常 */
UNKNOWN_EXCEPTION("UNKNOWN_EXCEPTION", "未知异常"),
/** 数据库异常 */
DATABASE_EXCEPTION("DATABASE_EXCEPTION", "数据库异常"),
/** IO异常 */
IO_EXCEPTION("IO_EXCEPTION", "IO异常"),
/** 参数不能为空 */
PARAM_CAN_NOT_NULL("PARAM_CAN_NOT_NULL", "参数不能为空"),
/** 参数不能为空 */
PARAM_CAN_NOT_EMPTY("PARAM_CAN_NOT_EMPTY", "参数不能为空"),
/** 重复发送 */
RETRANSMISSION("RETRANSMISSION", "重复发送"),
/** 无效参数 */
ILLEGAL_ARGUMENT("ILLEGAL_ARGUMENT", "无效参数"),
/** 时间格式不合法*/
ILLEGAL_DATE_FORMAT("ILLEGAL_DATE_FORMAT", "时间格式不合法"),
;
/**
* 初始化保存到map里方便根据code获取
*/
private static Map<String, NotifyResultCode> RESULT_CODES = new HashMap<String, NotifyResultCode>();
static {
for (NotifyResultCode resultCode : NotifyResultCode.values()) {
RESULT_CODES.put(resultCode.code, resultCode);
}
}
/** 结果码 */
private String code;
/** 结果码信息 */
private String msg;
/** 结果分类 */
private NotifyResultCode classification;
/**
* 构造函数
*
* @param code 结果码
* @param msg 结果码信息
*/
private NotifyResultCode(String code, String message) {
this(code, message, null);
}
/**
* 构造函数
*
* @param code 结果码
* @param msg 结果码信息
* @param classification 结果分组
*/
private NotifyResultCode(String code, String msg, NotifyResultCode classification) {
this.code = code;
this.msg = msg;
this.classification = classification;
}
/**
* 通过枚举<code>code</code>获得枚举
*
* @param code 结果码
* @return 枚举
*/
public static NotifyResultCode getResultCode(String code) {
return RESULT_CODES.get(code);
}
/**
* Getter method for property <tt>code</tt>.
*
* @return property value of code
*/
@Override
public String getCode() {
return code;
}
/**
* Setter method for property <tt>code</tt>.
*
* @param code value to be assigned to property code
*/
public void setCode(String code) {
this.code = code;
}
/**
* Getter method for property <tt>msg</tt>.
*
* @return property value of msg
*/
@Override
public String getMsg() {
return msg;
}
/**
* Setter method for property <tt>msg</tt>.
*
* @param msg value to be assigned to property msg
*/
public void setMsg(String msg) {
this.msg = msg;
}
/**
* Getter method for property <tt>classification</tt>.
*
* @return property value of classification
*/
public NotifyResultCode getClassification() {
return classification;
}
/**
* Setter method for property <tt>classification</tt>.
*
* @param classification value to be assigned to property classification
*/
public void setClassification(NotifyResultCode classification) {
this.classification = classification;
}
}
package com.jz.dm.gateway.common.util;
import com.jz.dm.gateway.common.StringUtil;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* <code>Object</code>处理工具类。
*
*/
public class ObjectUtil {
/**
* 用于表示<code>null</code>的常量。
*
* <p>
* 例如,<code>HashMap.get(Object)</code>方法返回<code>null</code>有两种可能:
* 值不存在或值为<code>null</code>。而这个singleton可用来区别这两种情形。
* </p>
*
* <p>
* 另一个例子是,<code>Hashtable</code>的值不能为<code>null</code>。
* </p>
*/
public static final Object NULL = new Serializable() {
private static final long serialVersionUID = 7092611880189329093L;
private Object readResolve() {
return NULL;
}
};
/* ============================================================================ */
/* 默认值函数。 */
/* */
/* 当对象为null时,将对象转换成指定的默认对象。 */
/* ============================================================================ */
/**
* 如果对象为<code>null</code>,则返回指定默认对象,否则返回对象本身。
* <pre>
* ObjectUtil.defaultIfNull(null, null) = null
* ObjectUtil.defaultIfNull(null, "") = ""
* ObjectUtil.defaultIfNull(null, "zz") = "zz"
* ObjectUtil.defaultIfNull("abc", *) = "abc"
* ObjectUtil.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
* </pre>
*
* @param object 要测试的对象
* @param defaultValue 默认值
*
* @return 对象本身或默认对象
*/
public static Object defaultIfNull(Object object, Object defaultValue) {
return (object != null) ? object : defaultValue;
}
/* ============================================================================ */
/* 比较函数。 */
/* */
/* 以下方法用来比较两个对象是否相同。 */
/* ============================================================================ */
/**
* 比较两个对象是否完全相等。
*
* <p>
* 此方法可以正确地比较多维数组。
* <pre>
* ObjectUtil.equals(null, null) = true
* ObjectUtil.equals(null, "") = false
* ObjectUtil.equals("", null) = false
* ObjectUtil.equals("", "") = true
* ObjectUtil.equals(Boolean.TRUE, null) = false
* ObjectUtil.equals(Boolean.TRUE, "true") = false
* ObjectUtil.equals(Boolean.TRUE, Boolean.TRUE) = true
* ObjectUtil.equals(Boolean.TRUE, Boolean.FALSE) = false
* </pre>
* </p>
*
* @param object1 对象1
* @param object2 对象2
*
* @return 如果相等, 则返回<code>true</code>
*/
public static boolean equals(Object object1, Object object2) {
return ArrayUtil.equals(object1, object2);
}
/* ============================================================================ */
/* Hashcode函数。 */
/* */
/* 以下方法用来取得对象的hash code。 */
/* ============================================================================ */
/**
* 取得对象的hash值, 如果对象为<code>null</code>, 则返回<code>0</code>。
*
* <p>
* 此方法可以正确地处理多维数组。
* </p>
*
* @param object 对象
*
* @return hash值
*/
public static int hashCode(Object object) {
return ArrayUtil.hashCode(object);
}
/**
* 取得对象的原始的hash值, 如果对象为<code>null</code>, 则返回<code>0</code>。
*
* <p>
* 该方法使用<code>System.identityHashCode</code>来取得hash值,该值不受对象本身的<code>hashCode</code>方法的影响。
* </p>
*
* @param object 对象
*
* @return hash值
*/
public static int identityHashCode(Object object) {
return (object == null) ? 0 : System.identityHashCode(object);
}
/* ============================================================================ */
/* 取得对象的identity。 */
/* ============================================================================ */
/**
* 取得对象自身的identity,如同对象没有覆盖<code>toString()</code>方法时,<code>Object.toString()</code>的原始输出。
* <pre>
* ObjectUtil.identityToString(null) = null
* ObjectUtil.identityToString("") = "java.lang.String@1e23"
* ObjectUtil.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
* ObjectUtil.identityToString(new int[0]) = "int[]@7fa"
* ObjectUtil.identityToString(new Object[0]) = "java.lang.Object[]@7fa"
* </pre>
*
* @param object 对象
*
* @return 对象的identity,如果对象是<code>null</code>,则返回<code>null</code>
*/
public static String identityToString(Object object) {
if (object == null) {
return null;
}
return appendIdentityToString(null, object).toString();
}
/**
* 取得对象自身的identity,如同对象没有覆盖<code>toString()</code>方法时,<code>Object.toString()</code>的原始输出。
* <pre>
* ObjectUtil.identityToString(null, "NULL") = "NULL"
* ObjectUtil.identityToString("", "NULL") = "java.lang.String@1e23"
* ObjectUtil.identityToString(Boolean.TRUE, "NULL") = "java.lang.Boolean@7fa"
* ObjectUtil.identityToString(new int[0], "NULL") = "int[]@7fa"
* ObjectUtil.identityToString(new Object[0], "NULL") = "java.lang.Object[]@7fa"
* </pre>
*
* @param object 对象
* @param nullStr 如果对象为<code>null</code>,则返回该字符串
*
* @return 对象的identity,如果对象是<code>null</code>,则返回指定字符串
*/
public static String identityToString(Object object, String nullStr) {
if (object == null) {
return nullStr;
}
return appendIdentityToString(null, object).toString();
}
/**
* 将对象自身的identity——如同对象没有覆盖<code>toString()</code>方法时,<code>Object.toString()</code>的原始输出——追加到<code>StringBuffer</code>中。
* <pre>
* ObjectUtil.appendIdentityToString(*, null) = null
* ObjectUtil.appendIdentityToString(null, "") = "java.lang.String@1e23"
* ObjectUtil.appendIdentityToString(null, Boolean.TRUE) = "java.lang.Boolean@7fa"
* ObjectUtil.appendIdentityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa")
* ObjectUtil.appendIdentityToString(buf, new int[0]) = buf.append("int[]@7fa")
* ObjectUtil.appendIdentityToString(buf, new Object[0]) = buf.append("java.lang.Object[]@7fa")
* </pre>
*
* @param buffer <code>StringBuffer</code>对象,如果是<code>null</code>,则创建新的
* @param object 对象
*
* @return <code>StringBuffer</code>对象,如果对象为<code>null</code>,则返回<code>null</code>
*/
public static StringBuffer appendIdentityToString(StringBuffer buffer, Object object) {
if (object == null) {
return null;
}
if (buffer == null) {
buffer = new StringBuffer();
}
buffer.append(ClassUtil.getClassNameForObject(object));
return buffer.append('@').append(Integer.toHexString(identityHashCode(object)));
}
/* ============================================================================ */
/* Clone函数。 */
/* */
/* 以下方法调用Object.clone方法,默认是“浅复制”(shallow copy)。 */
/* ============================================================================ */
/**
* 复制一个对象。如果对象为<code>null</code>,则返回<code>null</code>。
*
* <p>
* 此方法调用<code>Object.clone</code>方法,默认只进行“浅复制”。 对于数组,调用<code>ArrayUtil.clone</code>方法更高效。
* </p>
*
* @param array 要复制的数组
*
* @return 数组的复本,如果原始数组为<code>null</code>,则返回<code>null</code>
*/
public static Object clone(Object array) {
if (array == null) {
return null;
}
// 对数组特殊处理
if (array instanceof Object[]) {
return ArrayUtil.clone((Object[]) array);
}
if (array instanceof long[]) {
return ArrayUtil.clone((long[]) array);
}
if (array instanceof int[]) {
return ArrayUtil.clone((int[]) array);
}
if (array instanceof short[]) {
return ArrayUtil.clone((short[]) array);
}
if (array instanceof byte[]) {
return ArrayUtil.clone((byte[]) array);
}
if (array instanceof double[]) {
return ArrayUtil.clone((double[]) array);
}
if (array instanceof float[]) {
return ArrayUtil.clone((float[]) array);
}
if (array instanceof boolean[]) {
return ArrayUtil.clone((boolean[]) array);
}
if (array instanceof char[]) {
return ArrayUtil.clone((char[]) array);
}
// Not cloneable
if (!(array instanceof Cloneable)) {
throw new RuntimeException(
"Object of class " + array.getClass().getName() + " is not Cloneable");
}
// 用reflection调用clone方法
Class<?> clazz = array.getClass();
try {
Method cloneMethod = clazz.getMethod("clone", ArrayUtil.EMPTY_CLASS_ARRAY);
return cloneMethod.invoke(array, ArrayUtil.EMPTY_OBJECT_ARRAY);
} catch (Exception e) {
throw new RuntimeException("Object clone exception.", e);
}
}
/* ============================================================================ */
/* 比较对象的类型。 */
/* ============================================================================ */
/**
* 检查两个对象是否属于相同类型。<code>null</code>将被看作任意类型。
*
* @param object1 对象1
* @param object2 对象2
*
* @return 如果两个对象有相同的类型,则返回<code>true</code>
*/
public static boolean isSameType(Object object1, Object object2) {
if ((object1 == null) || (object2 == null)) {
return true;
}
return object1.getClass().equals(object2.getClass());
}
/* ============================================================================ */
/* toString方法。 */
/* ============================================================================ */
/**
* 取得对象的<code>toString()</code>的值,如果对象为<code>null</code>,则返回空字符串<code>""</code>。
* <pre>
* ObjectUtil.toString(null) = ""
* ObjectUtil.toString("") = ""
* ObjectUtil.toString("bat") = "bat"
* ObjectUtil.toString(Boolean.TRUE) = "true"
* ObjectUtil.toString([1, 2, 3]) = "[1, 2, 3]"
* </pre>
*
* @param object 对象
*
* @return 对象的<code>toString()</code>的返回值,或空字符串<code>""</code>
*/
public static String toString(Object object) {
return (object == null) ? StringUtil.EMPTY_STRING
: (object.getClass().isArray() ? ArrayUtil.toString(object) : object.toString());
}
/**
* 取得对象的<code>toString()</code>的值,如果对象为<code>null</code>,则返回指定字符串。
* <pre>
* ObjectUtil.toString(null, null) = null
* ObjectUtil.toString(null, "null") = "null"
* ObjectUtil.toString("", "null") = ""
* ObjectUtil.toString("bat", "null") = "bat"
* ObjectUtil.toString(Boolean.TRUE, "null") = "true"
* ObjectUtil.toString([1, 2, 3], "null") = "[1, 2, 3]"
* </pre>
*
* @param object 对象
* @param nullStr 如果对象为<code>null</code>,则返回该字符串
*
* @return 对象的<code>toString()</code>的返回值,或指定字符串
*/
public static String toString(Object object, String nullStr) {
return (object == null) ? nullStr
: (object.getClass().isArray() ? ArrayUtil.toString(object) : object.toString());
}
}
package com.jz.dm.gateway.common.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jz.dm.gateway.common.exception.OpenApiException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* openapi请求
*
*/
public class OpenApiRequest {
private String appId;
private String openApiParams;
private JSONObject parameters;
private Object parameterObject;
private Map<String, Object> extAttributes = new HashMap<String, Object>();
public OpenApiRequest(String openApiParams) {
setOpenApiParams(openApiParams);
}
private void setOpenApiParams(String openApiParams) {
this.openApiParams = openApiParams;
try {
parameters = JSON.parseObject(openApiParams, JSONObject.class);
} catch (Exception ex) {
throw new OpenApiException(OpenApiResultCode.ILLEGAL_ARGUMENT,
"parse openapi params error, openApiParams=" + openApiParams, ex);
}
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
@SuppressWarnings("unchecked")
public <T> T getObject(Class<?> clazz) {
if (parameterObject != null) {
return (T) parameterObject;
}
try {
this.parameterObject = JSON.parseObject(openApiParams, clazz);
} catch (Exception ex) {
throw new OpenApiException(OpenApiResultCode.ILLEGAL_ARGUMENT, ex);
}
return (T) parameterObject;
}
public String getOpenApiParams() {
return this.openApiParams;
}
@SuppressWarnings("unchecked")
@Deprecated
public <T> T getParameter(String key) {
return (T) parameters.get(key);
}
public <T> T getObject(String key, Class<T> clazz) {
return parameters.getObject(key, clazz);
}
public byte[] getBytes(String key) {
return parameters.getBytes(key);
}
public Boolean getBoolean(String key) {
return parameters.getBoolean(key);
}
public boolean getBooleanValue(String key) {
return parameters.getBooleanValue(key);
}
public Byte getByte(String key) {
return parameters.getByte(key);
}
public byte getByteValue(String key) {
return parameters.getByteValue(key);
}
public Short getShort(String key) {
return parameters.getShortValue(key);
}
public short getShortValue(String key) {
return parameters.getShortValue(key);
}
public Integer getInteger(String key) {
return parameters.getInteger(key);
}
public int getIntValue(String key) {
return parameters.getIntValue(key);
}
public Long getLong(String key) {
return parameters.getLong(key);
}
public long getLongValue(String key) {
return parameters.getLongValue(key);
}
public Float getFloat(String key) {
return parameters.getFloat(key);
}
public float getFloatValue(String key) {
return parameters.getFloatValue(key);
}
public Double getDouble(String key) {
return parameters.getDouble(key);
}
public double getDoubleValue(String key) {
return parameters.getDoubleValue(key);
}
public BigDecimal getBigDecimal(String key) {
return parameters.getBigDecimal(key);
}
public BigInteger getBigInteger(String key) {
return parameters.getBigInteger(key);
}
public String getString(String key) {
return parameters.getString(key);
}
public Date getDate(String key) {
return parameters.getDate(key);
}
/**
* Get Extend Attribute
*
* @param attributeName
* @return
*/
@SuppressWarnings("unchecked")
public <T> T getExtAttribute(String attributeName) {
return (T) extAttributes.get(attributeName);
}
/**
* Set Extend Attribute
*
* @param attributeName
* @param attributeValue
*/
public void setExtAttribute(String attributeName, String attributeValue) {
this.extAttributes.put(attributeName, attributeValue);
}
/**
* Getter method for property <tt>extAttributes</tt>.
*
* @return property value of extAttributes
*/
public Map<String, Object> getExtAttributes() {
return extAttributes;
}
/**
* Setter method for property <tt>extAttributes</tt>.
*
* @param extAttributes value to be assigned to property extAttributes
*/
public void setExtAttributes(Map<String, Object> extAttributes) {
this.extAttributes = extAttributes;
}
}
package com.jz.dm.gateway.common.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;
/**
* openapi响应
*
*/
public class OpenApiResponse {
/**
* 结果码
*/
private static final String ATTRIBUTE_NAME_CODE = "code";
/**
* 结果消息
*/
private static final String ATTRIBUTE_NAME_MSG = "msg";
/**
* 属性
*/
private final Map<String, Object> attributes = new HashMap<String, Object>();
/**
* 获取结果码
*
* @return
*/
public String getCode() {
return (String) attributes.get(ATTRIBUTE_NAME_CODE);
}
/**
* 设置结果码
*
* @param code
*/
public void setCode(String code) {
attributes.put(ATTRIBUTE_NAME_CODE, code);
}
/**
* 获取结果信息
*
* @return
*/
public String getMsg() {
return (String) attributes.get(ATTRIBUTE_NAME_MSG);
}
/**
* 设置结果信息
*
* @param msg
*/
public void setMsg(String msg) {
attributes.put(ATTRIBUTE_NAME_MSG, msg);
}
/**
* 获取属性
*
* @param attributeName
* @return
*/
@SuppressWarnings("unchecked")
public <T> T getAttribute(String attributeName) {
return (T) attributes.get(attributeName);
}
/**
* 设置属性
*
* @param attributeName
* @param attributeValue
*/
public void setAttribute(String attributeName, Object attributeValue) {
attributes.put(attributeName, attributeValue);
}
/**
* 设置对象属性
*
* @param object
*/
public void setAttribute(Object object) {
Object jsonObject = JSON.toJSON(object);
if (!(jsonObject instanceof JSONObject)) {
throw new IllegalArgumentException("object must be a javabean.");
}
attributes.putAll((JSONObject) jsonObject);
}
/**
* 获取所有属性
*
* @return
*/
public Map<String, Object> getAttributes() {
return attributes;
}
}
package com.jz.dm.gateway.common.util;
import java.util.HashMap;
import java.util.Map;
/**
* 结果码
*
*/
public enum OpenApiResultCode implements ResultCode {
/** 处理成功 */
SUCCESS("SUCCESS", "处理成功"),
/** 未知异常 */
UNKNOWN_EXCEPTION("UNKNOWN_EXCEPTION", "未知异常"),
/** 无效接口 */
ILLEGAL_INTERFACE("ILLEGAL_INTERFACE", "无效接口"),
/** 无效参数 */
ILLEGAL_ARGUMENT("ILLEGAL_ARGUMENT", "无效参数"),
/** 名类型不支持 */
SIGN_TYPE_NOT_SUPPORT("SIGN_TYPE_NOT_SUPPORT", "签名类型不支持"),
/** 数据签名错误 */
DATA_SIGN_ERROR("DATA_SIGN_ERROR", "数据签名错误"),
/** 公钥格式错误 */
PUBLIC_KEY_FORMAT_ERROR("PUBLIC_KEY_FORMAT_ERROR", "公钥格式错误"),
/** 私钥格式错误 */
PRIVATE_KEY_FORMAT_ERROR("PRIVATE_KEY_FORMAT_ERROR", "私钥格式错误"),
/** 响应数据格式错误 */
RESPONSE_DATA_FORMAT_ERROR("RESPONSE_DATA_FORMAT_ERROR", "响应数据格式错误"),
/** 签名校验错误 */
SIGN_VERIFY_ERROR("SIGN_VERIFY_ERROR", "签名校验错误"),
/** 不支持该信息摘要算法 */
NO_SUCH_MD_ALGORITHM("NO_SUCH_MD_ALGORITHM", "不支持该信息摘要算法"),
/** 信息摘要错误 */
MESSAGE_DIGEST_ERROR("MESSAGE_DIGEST_ERROR", "信息摘要错误"),
/** 数据加密错误 */
DATA_ENCRYPTION_ERROR("DATA_ENCRYPTION_ERROR", "数据加密错误"),;
/**
* 初始化保存到map里方便根据code获取
*/
private static Map<String, OpenApiResultCode> RESULT_CODES = new HashMap<String, OpenApiResultCode>();
static {
for (OpenApiResultCode openApiCode : OpenApiResultCode.values()) {
RESULT_CODES.put(openApiCode.code, openApiCode);
}
}
/** 结果码 */
private String code;
/** 结果码信息 */
private String msg;
/**
* 构造函数
*
* @param code 结果码
* @param msg 结果码信息
*/
private OpenApiResultCode(String code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 通过枚举<code>code</code>获得枚举
*
* @param code 结果码
* @return 枚举
*/
public static OpenApiResultCode getOpenApiResultCode(String code) {
return RESULT_CODES.get(code);
}
/**
* Getter method for property <tt>code</tt>.
*
* @return property value of code
*/
@Override
public String getCode() {
return code;
}
/**
* Setter method for property <tt>code</tt>.
*
* @param code value to be assigned to property code
*/
public void setCode(String code) {
this.code = code;
}
/**
* Getter method for property <tt>msg</tt>.
*
* @return property value of msg
*/
@Override
public String getMsg() {
return msg;
}
/**
* Setter method for property <tt>msg</tt>.
*
* @param msg value to be assigned to property msg
*/
public void setMsg(String msg) {
this.msg = msg;
}
}
package com.jz.dm.gateway.common.util;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
*
* <p>RSA签名,加解密处理核心文件,注意:密钥长度1024</p>
* @author leelun
* @version $Id: RSA.java, v 0.1 2013-11-15 下午2:33:53 lilun Exp $
*/
public class RSA {
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
private static Logger logger = LoggerFactory.getLogger(RSA.class);
/**
* <p>
* 生成密钥对(公钥和私钥)
* </p>
*
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 签名字符串
*
* @param text
* 需要签名的字符串
* @param privateKey 私钥(BASE64编码)
*
* @param input_charset
* 编码格式
* @return 签名结果(BASE64编码)
*/
public static String sign(String text, String privateKey, String charset) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(getContentBytes(text, charset));
byte[] result = signature.sign();
return Base64.encodeBase64String(result);
}
/**
* 签名字符串
*
* @param text
* 需要签名的字符串
* @param sign
* 客户签名结果
* @param publicKey
* 公钥(BASE64编码)
* @param input_charset
* 编码格式
* @return 验签结果
*/
public static boolean verify(String text, String sign, String publicKey, String charset)
throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(getContentBytes(text, charset));
return signature.verify(Base64.decodeBase64(sign));
}
/**
* <P>
* 私钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
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 decryptedData;
}
/**
* <p>
* 公钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
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 decryptedData;
}
/**
* <p>
* 公钥加密
* </p>
*
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
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 = out.toByteArray();
out.close();
return encryptedData;
}
/**
* <p>
* 私钥加密
* </p>
*
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
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 = out.toByteArray();
out.close();
return encryptedData;
}
/**
* @param content
* @param charset
* @return
* @throws SignatureException
* @throws UnsupportedEncodingException
*/
private static byte[] getContentBytes(String content, String charset) {
if (charset == null || "".equals(charset)) {
return content.getBytes();
}
try {
return content.getBytes(charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
}
}
/**
* <p>
* 获取私钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64.encodeBase64String(key.getEncoded());
}
/**
* <p>
* 获取公钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64.encodeBase64String(key.getEncoded());
}
}
\ No newline at end of file
package com.jz.dm.gateway.common.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSAUtils {
public static final String CHARSET = "UTF-8";
public static final String RSA_ALGORITHM = "RSA";
public static Map<String, String> createKeys(int keySize){
//为RSA算法创建一个KeyPairGenerator对象
KeyPairGenerator kpg;
try{
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
}catch(NoSuchAlgorithmException e){
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
}
//初始化KeyPairGenerator对象,密钥长度
kpg.initialize(keySize);
//生成密匙对
KeyPair keyPair = kpg.generateKeyPair();
//得到公钥
Key publicKey = keyPair.getPublic();
String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
//得到私钥
Key privateKey = keyPair.getPrivate();
System.out.println("私钥格式:"+privateKey.getFormat());
String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
Map<String, String> keyPairMap = new HashMap<String, String>();
keyPairMap.put("publicKey", publicKeyStr);
keyPairMap.put("privateKey", privateKeyStr);
return keyPairMap;
}
/**
* 得到公钥
* @param publicKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
/**
* 得到私钥
* @param privateKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过PKCS#8编码的Key指令获得私钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
/**
* 公钥加密
* @param data
* @param publicKey
* @return
*/
public static String publicEncrypt(String data, RSAPublicKey publicKey){
try{
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
}catch(Exception e){
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
}
}
/**
* 私钥解密
* @param data
* @param privateKey
* @return
*/
public static String privateDecrypt(String data, RSAPrivateKey privateKey){
try{
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
}catch(Exception e){
throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
}
}
/**
* 私钥加密
* @param data
* @param privateKey
* @return
*/
public static String privateEncrypt(String data, RSAPrivateKey privateKey){
try{
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));
}catch(Exception e){
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
}
}
/**
* 公钥解密
* @param data
* @param publicKey
* @return
*/
public static String publicDecrypt(String data, RSAPublicKey publicKey){
try{
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET);
}catch(Exception e){
throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
}
}
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){
int maxBlock = 0;
if(opmode == Cipher.DECRYPT_MODE){
maxBlock = keySize / 8;
}else{
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try{
while(datas.length > offSet){
if(datas.length-offSet > maxBlock){
buff = cipher.doFinal(datas, offSet, maxBlock);
}else{
buff = cipher.doFinal(datas, offSet, datas.length-offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
}catch(Exception e){
throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e);
}
byte[] resultDatas = out.toByteArray();
IOUtils.closeQuietly(out);
return resultDatas;
}
}
package com.jz.dm.gateway.common.util;
/**
* 结果码
*
*/
public interface ResultCode {
/**
* 编码
*
* @return
*/
public String getCode();
/**
* 信息
*
* @return
*/
public String getMsg();
}
package com.jz.dm.gateway.common.util;
/**
* 签名类型
*
*/
public enum SignType {
RSA, RSA2, MD5
}
package com.jz.dm.gateway.common.util;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.jz.dm.gateway.common.StringUtil;
import com.jz.dm.gateway.common.exception.SignatureException;
import com.jz.dm.gateway.signtype.Md5;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
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.*;
/**
* 签名工具
*
*/
@Slf4j
public class SignatureUtil {
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 SIGN_REQUEST = "SIGN_REQUEST";
public static final String SIGN_CALLBACK = "SIGN_CALLBACK";
/**
* 获取签名校验内容
*
* @param params
* @return
*/
private static String getVerifyContent(Map<String, Object> params, String... excludeParams) {
if (params == null) {
return null;
}
if (excludeParams == null || excludeParams.length == 0) {
params.remove("sign");
} else {
for (String excludeParam : excludeParams) {
params.remove(excludeParam);
}
}
StringBuffer content = new StringBuffer();
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
for (String key : keys) {
if (params.get(key) != null){
String value = params.get(key).toString();
if (!StringUtils.isEmpty(value)) {
content.append(key).append("=").append(value);
}
}
}
return content.toString();
}
/**
* 校验签名
*
* @param params
* @param publicKey
* @param charset
* @return
* @throws
*/
public static boolean verify(Map params, String publicKey, String charset,
SignType signType, String... excludeParams) {
String sign = (String) params.get("sign");
String content = getVerifyContent(params, excludeParams);
log.info("请求验签: {}", content);
if (signType == SignType.RSA) {
return rsaVerify(content, sign, publicKey, charset);
} else if (signType == SignType.RSA2) {
return rsa256Verify(content, sign, publicKey, charset);
} else if (signType == SignType.MD5) {
String calcSign = Md5.encrypt(content, publicKey, charset);
return StringUtils.equals(calcSign, sign);
} else {
throw new SignatureException(OpenApiResultCode.SIGN_TYPE_NOT_SUPPORT,
"Sign Type is Not Support : signType=" + signType);
}
}
public static void main(String[] args) {
//ed123fca54c919bce4d5e16b6ebd0304
Map<String,Object> map = new HashMap<>();
Map<String,Object> map1 = new HashMap<>();
map1.put("tradeNo", "2020041510842580008");
map1.put("outTradeNo", "XJ1586919520927");
map1.put("status", "PAYMENT");
map.put("data", map1);
String responseJson = JsonUtil.toJSONString(map,
PropertyNamingStrategy.SnakeCase);
String s = "app_id=200407008243charset=UTF-8method=trade.submitparams={\"accountType\":\"WBANK\",\"outTradeNo\":\"TS2020041411353338464\",\"remark\":\"test11\",\"items\":[{\"amount\":\"10\",\"idCard\":\"430524199707287172\",\"mobile\":\"15910401066\",\"name\":\"马斌\",\"remark\":\"test22\",\"cardNo\":\"6217995550000488697\"}]}sign_type=MD5timestamp=1586858028000version=1.0.0";
SignType signType = SignType.MD5;
String calcSign = Md5.encrypt(s, "pwxw5FaQ4UFvycYfbmRvqPQ1m96aJblURXyVsnMXPe8qJhurmebv1XPnvPkJjjC8", "UTF-8");
System.out.println(calcSign);
}
/**
* rsa校验签名
*
* @param content
* @param sign
* @param publicKey
* @param charset
* @return
* @throws
*/
public static boolean rsaVerify(String content, String sign, String publicKey, String charset) {
try {
PublicKey pubKey = getPublicKeyFromX509("RSA",
new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initVerify(pubKey);
if (StringUtil.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64.decodeBase64(sign.getBytes()));
} catch (Exception e) {
throw new SignatureException(OpenApiResultCode.SIGN_VERIFY_ERROR,
"RSAcontent = " + content + "; charset = " + charset, e);
}
}
/**
* rsa256校验签名
*
* @param content
* @param sign
* @param publicKey
* @param charset
* @return
* @throws
*/
public static boolean rsa256Verify(String content, String sign, String publicKey,
String charset) {
try {
PublicKey pubKey = getPublicKeyFromX509("RSA",
new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_SHA256RSA_ALGORITHMS);
signature.initVerify(pubKey);
if (StringUtil.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64.decodeBase64(sign.getBytes()));
} catch (Exception e) {
throw new SignatureException(OpenApiResultCode.SIGN_VERIFY_ERROR,
"RSAcontent = " + content + "; charset = " + charset, e);
}
}
/**
* 获取公钥
*
* @param algorithm
* @param ins
* @return
* @throws Exception
*/
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));
}
/**
* 获取签名内容
*
* @param params
* @return
*/
public static String getSignContent(Map<String, Object> params) {
StringBuffer content = new StringBuffer();
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
int index = 0;
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key) == null ? "" : params.get(key).toString();
if (StringUtil.isNotEmpty(key, value)) {
content.append(key + "=" + value);
index++;
}
}
return content.toString();
}
/**
* 内容签名
*
* @param params
* @param publicKey
* @param charset
* @param signType
* @param providePublicKey true : 惠多多提供外部公钥了, false : 没有对外提供公钥,使用外部公钥加密做签名
* @return
*/
public static String sign(Map<String, Object> params, String publicKey, String charset,
SignType signType, String businessType, boolean providePublicKey) {
String signContent = getSignContent(params);
return sign(signContent, publicKey, charset, signType, businessType, providePublicKey);
}
/**
* rsa内容签名
*
* @param content
* @param privateKey
* @param charset
* @return
*/
public static String sign(String content, String privateKey, String charset,
SignType signType, String type, boolean providePublicKey) {
log.info("参与加签字符串:{}", content);
if (signType == SignType.RSA) {
if (SIGN_CALLBACK.equals(type)) {
if (providePublicKey) {
return callBackRsaSignByPrivateKey(content, privateKey, charset);
} else {
return callBackRsaSignByPublicKey(content, privateKey, charset);
}
}
if (providePublicKey) {
return rsaSignByPrivateKey(content, privateKey, charset);
} else {
return rsaSignByPublicKey(content, privateKey, charset);
}
} else if (signType == SignType.RSA2) {
return rsa256Sign(content, privateKey, charset);
} else if (signType == SignType.MD5) {
return Md5.encrypt(content, privateKey, charset);
} else {
throw new SignatureException(OpenApiResultCode.SIGN_TYPE_NOT_SUPPORT,
"Sign Type is Not Support : signType=" + signType);
}
}
public static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
InputStream ins) throws Exception {
if (ins == null || StringUtil.isEmpty(algorithm)) {
return null;
}
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
byte[] privateKey = StreamUtil.readText(ins).getBytes();
privateKey = Base64.decodeBase64(privateKey);
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey));
}
/**
* sha256WithRsa 加签
*
* @param content
* @param privateKey
* @param charset
* @return
*/
public static String rsa256Sign(String content, String privateKey, String charset) {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
new ByteArrayInputStream(privateKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_SHA256RSA_ALGORITHMS);
signature.initSign(priKey);
if (StringUtil.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 SignatureException(OpenApiResultCode.DATA_SIGN_ERROR,
"RSAcontent = " + content + "; charset = " + charset, e);
}
}
/**
* sha1WithRsa 加签
*
* @param content
* @param publicKey
* @param charset
* @return
*/
public static String rsaSignByPublicKey(String content, String publicKey, String charset) {
try {
byte[] signed = RSA.encryptByPublicKey(content.getBytes(charset), publicKey);
return new String(Base64.encodeBase64(signed));
} catch (InvalidKeySpecException e) {
throw new SignatureException(OpenApiResultCode.PUBLIC_KEY_FORMAT_ERROR,
"RSA公钥格式不正确,请检查是否正确配置了PKCS8格式的公钥", e);
} catch (Exception e) {
throw new SignatureException(OpenApiResultCode.DATA_SIGN_ERROR,
"RSAcontent = " + content + "; charset = " + charset, e);
}
}
/**
* sha1WithRsa 加签
*
* @param content
* @param privateKey
* @param charset
* @return
*/
public static String rsaSignByPrivateKey(String content, String privateKey, String charset) {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
new ByteArrayInputStream(privateKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
if (StringUtil.isEmpty(charset)) {
signature.update(content.getBytes());
} else {
signature.update(content.getBytes(charset));
}
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed));
} catch (InvalidKeySpecException e) {
throw new SignatureException(OpenApiResultCode.PRIVATE_KEY_FORMAT_ERROR,
"RSA私钥格式不正确,请检查是否正确配置了PKCS8格式的私钥", e);
} catch (Exception e) {
throw new SignatureException(OpenApiResultCode.DATA_SIGN_ERROR,
"RSAcontent = " + content + "; charset = " + charset, e);
}
}
/**
* sha1WithRsa 回调内容加签
* @param content
* @param publicKey
* @param charset
* @return
*/
public static String callBackRsaSignByPublicKey(String content, String publicKey, String charset) {
try {
byte[] signed = RSA.encryptByPublicKey(Md5.encrypt(content,"").getBytes(charset), publicKey);
return new String(Base64.encodeBase64(signed));
} catch (InvalidKeySpecException e) {
throw new SignatureException(OpenApiResultCode.PUBLIC_KEY_FORMAT_ERROR,
"RSA公钥格式不正确,请检查是否正确配置了PKCS8格式的公钥", e);
} catch (Exception e) {
throw new SignatureException(OpenApiResultCode.DATA_SIGN_ERROR,
"RSAcontent = " + content + "; charset = " + charset, e);
}
}
/**
* sha1WithRsa 回调内容加签
* @param content
* @param privateKey
* @param charset
* @return
*/
public static String callBackRsaSignByPrivateKey(String content, String privateKey, String charset) {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
new ByteArrayInputStream(privateKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
if (StringUtil.isEmpty(charset)) {
signature.update(Md5.encrypt(content,"").getBytes());
} else {
signature.update(Md5.encrypt(content,"").getBytes(charset));
}
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed));
} catch (InvalidKeySpecException e) {
throw new SignatureException(OpenApiResultCode.PRIVATE_KEY_FORMAT_ERROR,
"RSA私钥格式不正确,请检查是否正确配置了PKCS8格式的私钥", e);
} catch (Exception e) {
throw new SignatureException(OpenApiResultCode.DATA_SIGN_ERROR,
"RSAcontent = " + content + "; charset = " + charset, e);
}
}
}
package com.jz.dm.gateway.common.util;
import java.io.*;
/**
* 流处理工具
*
*/
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();
}
}
}
}
package com.jz.dm.gateway.common.util;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
/**
*
* @author Admin
*/
public final class TtpayUtils {
/**
* 除去数组中的空值和签名参数
* 为了兼容健康商城签名问题,过滤sign2参数
* @param sArray 签名参数组
* @return 去掉空值与签名参数后的新签名参数组
*/
public static Map<String, String> filter(Map<String, String> sArray) {
Map<String, String> result = new HashMap<String, String>();
if (sArray == null || sArray.size() <= 0) {
return result;
}
for (String key : sArray.keySet()) {
String value = sArray.get(key);
if (StringUtils.isEmpty(value) || key.equalsIgnoreCase("sign")) {
continue;
}
result.put(key, value);
}
return result;
}
/**
* 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param params 需要排序并参与字符拼接的参数组
* @return 拼接后字符串
*/
public static String createLinkString(Map<String, String> params) {
// 第一步:把字典按Key的字母顺序排序,参数使用TreeMap已经完成排序
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder sb = new StringBuilder();
for (String key : keys) {
String value = params.get(key);
if (!StringUtils.isEmpty(value)) {
sb.append(key).append("=").append(value);
}
}
return sb.toString();
}
/**
* 方法说明:根据运单号返回还有校验位
*
* @param no
* @return
*/
public static String createId(String mobile, int length) {
int count = 0;
String no = mobile.substring(0, length);//计算前6位校验码
int len = no.length();
for (int i=0;i<len;i++) {
int p = (no.charAt(len - i -1)) * (i * 2 + 1);
int q = divide(p, 10);
int r = p - q * 10;
count += (q + r);
}
return ((divide(count, 10) + 1) * 10 - count) % 10 + mobile.substring(mobile.length() - length + 1);
}
public static int divide(int x, int y) {
if (y == 0) {
return 0;
}
BigDecimal bigX = new BigDecimal(x);
BigDecimal bigY = new BigDecimal(y);
return bigX.divide(bigY, 0, RoundingMode.HALF_UP).intValue();
}
public static void main(String[] args) {
System.out.println(TtpayUtils.createId("15000000013", 7));
}
}
package com.jz.dm.gateway.common.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.*;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
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.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
public final class WebUtils {
private static final int CONNECT_TIMEOUT = Config.getHttpConnectTimeout();// 设置连接建立的超时时间为10s
private static final int SOCKET_TIMEOUT = Config.getHttpSocketTimeout();
private static final int MAX_CONN = Config.getHttpMaxPoolSize(); // 最大连接数
private static final int MAX_PRE_ROUTE = Config.getHttpMaxPoolSize();
private static final int MAX_ROUTE = Config.getHttpMaxPoolSize();
private static CloseableHttpClient httpClient; // 发送请求的客户端单例
private static PoolingHttpClientConnectionManager manager; // 连接池管理类
private static ScheduledExecutorService monitorExecutor;
private final static Object syncLock = new Object(); // 相当于线程锁,用于线程安全
/**
* http 请求
*
* @param url
* @param params
* @return
* @throws Exception
*/
public static String post(String url, Map<String, String> params) throws Exception {
CloseableHttpClient client = getHttpClient(url);
String responseText = "";
CloseableHttpResponse response = null;
try {
HttpPost method = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECT_TIMEOUT)
.setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
method.setConfig(requestConfig);
if (params != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (Entry<String, String> param : params.entrySet()) {
NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
paramList.add(pair);
}
method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
}
response = client.execute(method, HttpClientContext.create());
HttpEntity entity = response.getEntity();
if (entity != null) {
responseText = EntityUtils.toString(entity);
}
} catch (Exception e) {
throw e;
} finally {
try {
if (null != response) {
response.close();
}
} catch (Exception e) {
throw e;
}
}
return responseText;
}
public static String post(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
CloseableHttpClient client = getHttpClient(url);
String responseText = "";
CloseableHttpResponse response = null;
try {
HttpPost method = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECT_TIMEOUT)
.setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
method.setConfig(requestConfig);
if (null != headers && !headers.isEmpty()) {
for (Entry<String, String> entry : headers.entrySet()) {
method.setHeader(entry.getKey(), entry.getValue());
}
}
if (params != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (Entry<String, String> param : params.entrySet()) {
NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
paramList.add(pair);
}
method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
}
response = client.execute(method, HttpClientContext.create());
HttpEntity entity = response.getEntity();
if (entity != null) {
responseText = EntityUtils.toString(entity);
}
} catch (Exception e) {
throw e;
} finally {
try {
if (null != response) {
response.close();
}
} catch (Exception e) {
throw e;
}
}
return responseText;
}
/**
* 通过流方式传数据
*
* @param uri
* @param data
* @return
*/
public static String post(String uri, String data) {
log.info("向银行发起参数:{}", data);
CloseableHttpClient httpClient = getHttpClient(uri);
HttpPost method = new HttpPost(uri);
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECT_TIMEOUT)
.setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
method.setConfig(requestConfig);
String readContent = null;
try {
method.addHeader("Content-type", "application/xml; charset=ISO-8859-1");
method.setHeader("Accept", "application/xml");
method.setEntity(new StringEntity(data, Charset.forName("utf-8")));
HttpResponse response = httpClient.execute(method, HttpClientContext.create());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
return "failed";
}
HttpEntity entity = response.getEntity();
InputStream in = entity.getContent();
int count = 0;
while (count == 0) {
count = Integer.parseInt("" + entity.getContentLength());// in.available();
}
if (count <= 0) {
return EntityUtils.toString(entity);
}
byte[] bytes = new byte[count];
int readCount = 0; // 已经成功读取的字节的个数
while (readCount <= count) {
if (readCount == count) {
break;
}
readCount += in.read(bytes, readCount, count - readCount);
}
readContent = new String(bytes, 0, readCount, "UTF-8");
log.info("Get Response Content():\n {}", readContent);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return readContent;
}
/**
* 关闭连接池
*/
public static void closeConnectionPool() {
try {
httpClient.close();
manager.close();
monitorExecutor.shutdown();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 把map转为xml
*
* @param parameters
* @return
*/
public static String parseXML(Map<String, String> parameters) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Iterator<Entry<String, String>> itor = parameters.entrySet().iterator();
while (itor.hasNext()) {
Entry<String, String> entry = itor.next();
String k = entry.getKey();
String v = entry.getValue();
if (null != v && !"".equals(v) && !"appkey".equals(k)) {
sb.append("<" + k + ">" + parameters.get(k) + "</" + k + ">\n");
}
}
sb.append("</xml>");
return sb.toString();
}
/**
* 把map转为xml
*
* @param parameters
* @return
*/
public static String parseJSON(Map<String, String> parameters) {
return new JSONWriter().write(parameters);
}
/**
* 从URL中提取所有的参数。
*
* @param query URL地址
* @return 参数映射
*/
public static Map<String, String> splitUrlQuery(String query) {
Map<String, String> result = new HashMap<String, String>();
String[] pairs = query.split("&");
if (pairs != null && pairs.length > 0) {
for (String pair : pairs) {
String[] param = pair.split("=", 2);
if (param != null && param.length == 2) {
result.put(param[0], param[1]);
}
}
}
return result;
}
public static CloseableHttpClient getHttpClient(String url) {
int port = 80;
String hostName = url.split("/")[2];
if (hostName.contains(":")){
String[] args = hostName.split(":");
hostName = args[0];
port = Integer.parseInt(args[1]);
}
if (httpClient == null) {
// 多线程下多个线程同时调用getHttpClient容易导致重复创建httpClient对象的问题,所以加上了同步锁
synchronized (syncLock) {
if (httpClient == null) {
httpClient = createHttpClient(hostName, port);
// 开启监控线程,对异常和空闲线程进行关闭
monitorExecutor = Executors.newScheduledThreadPool(1);
monitorExecutor.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// 关闭异常连接
manager.closeExpiredConnections();
// 关闭5s空闲的连接
manager.closeIdleConnections(Config.getHttpIdelTimeout(), TimeUnit.MILLISECONDS);
}
}, Config.getHttpMonitorInterval(), Config.getHttpMonitorInterval(), TimeUnit.MILLISECONDS);
}
}
}
return httpClient;
}
/**
* 根据host和port构建httpclient实例
*
* @param host 要访问的域名
* @param port 要访问的端口
* @return
*/
public static CloseableHttpClient createHttpClient(String host, int port) {
ConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainSocketFactory).register("https", sslSocketFactory).build();
manager = new PoolingHttpClientConnectionManager(registry);
// 设置连接参数
manager.setMaxTotal(MAX_CONN); // 最大连接数
manager.setDefaultMaxPerRoute(MAX_PRE_ROUTE); // 路由最大连接数
HttpHost httpHost = new HttpHost(host, port);
manager.setMaxPerRoute(new HttpRoute(httpHost), MAX_ROUTE);
// 请求失败时,进行请求重试
HttpRequestRetryHandler handler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException e, int i, HttpContext httpContext) {
if (i > 3) {
// 重试超过3次,放弃请求
log.error("retry has more than 3 time, give up request");
return false;
}
if (e instanceof NoHttpResponseException) {
// 服务器没有响应,可能是服务器断开了连接,应该重试
log.error("receive no response from server, retry");
return true;
}
if (e instanceof SSLHandshakeException) {
// SSL握手异常
log.error("SSL hand shake exception");
return false;
}
if (e instanceof InterruptedIOException) {
// 超时
log.error("InterruptedIOException");
return false;
}
if (e instanceof UnknownHostException) {
// 服务器不可达
log.error("server host unknown");
return false;
}
if (e instanceof ConnectTimeoutException) {
// 连接超时
log.error("Connection Time out");
return false;
}
if (e instanceof SSLException) {
log.error("SSLException");
return false;
}
HttpClientContext context = HttpClientContext.adapt(httpContext);
HttpRequest request = context.getRequest();
if (!(request instanceof HttpEntityEnclosingRequest)) {
// 如果请求不是关闭连接的请求
return true;
}
return false;
}
};
return HttpClients.custom().setConnectionManager(manager).setRetryHandler(handler).build();
}
}
class Config {
static int httpConnectTimeout = 3000;
static int httpSocketTimeout = 60000;
static int httpMaxPoolSize = 2000;
static int httpMonitorInterval = 3000;
static int httpIdelTimeout = 2000;
public static int getHttpIdelTimeout() {
return httpIdelTimeout;
}
public static int getHttpSocketTimeout() {
return httpSocketTimeout;
}
public static int getHttpMaxPoolSize() {
return httpMaxPoolSize;
}
public static int getHttpMonitorInterval() {
return httpMonitorInterval;
}
public static int getHttpConnectTimeout() {
return httpConnectTimeout;
}
}
package com.jz.dm.gateway.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 日志常量
*
*/
public class LoggingConstants {
/** 业务摘要日志 */
public static final Logger DIGEST_LOGGER = LoggerFactory.getLogger("GATEWAY-DIGEST");
/** 报警日志,内容关键字用##号包括,便于报警信息归类 */
public static final Logger ALERT_LOGGER = LoggerFactory.getLogger("GATEWAY-ALERT");
/** 网关路由分发 */
public static final Logger DISPATCHER_LOGGER = LoggerFactory
.getLogger("GATEWAY-DISPATCHER");
public static final Logger REGISTRY_LOGGER = LoggerFactory.getLogger("GATEWAY-REGISTRY");
/** 分隔符*/
public static final String SEP = ",";
/** 点分割符*/
public static final String DOT_SEP = ".";
/** 默认值*/
public static final String DEFAULT_STR = "-";
/** 冒号 */
public static final String COLON = ":";
/** 金额币种分隔 */
public static final String AMOUNT_CURRENCY_SPLIT = "^";
/** 左中括号 */
public static final String LBRACKET = "[";
/** 右中括号 */
public static final String RBRACKET = "]";
/** "@" 符号*/
public static final String MONKEYS_AT = "@";
}
/**
* Copyright (c) 2011-2014 All Rights Reserved.
*/
package com.jz.dm.gateway.config;
/**
*
* @author Admin
* @version $Id: Property.java 2014年8月27日 下午6:28:46 $
*/
public class Property {
private static java.util.Properties property = null;
private Property() {
}
public static void init(java.util.Properties props) {
property = props;
}
public static void setProperty(String key, Object value) {
property.put(key, value);
}
public static String getProperty(String key) {
return property.getProperty(key);
}
public static String getProperty(String key, String defaultValue) {
return property.getProperty(key, defaultValue);
}
}
package com.jz.dm.gateway.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.jz.dm.gateway.common.util.JsonUtil;
import com.jz.dm.gateway.gateway.GatewayService;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.RequestContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* 网关请求
* @author key
*/
@RestController
public class GatewayController {
@Autowired
private GatewayService gatewayService;
@RequestMapping(value = "/gateway", consumes = "application/json")
public String gateway(@RequestBody String json, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
GatewayRequest gatewayRequest = JSON.parseObject(json, GatewayRequest.class);
return doGateway(gatewayRequest, httpServletRequest, httpServletResponse);
}
@RequestMapping(value = "/gateway")
public String gateway(GatewayRequest gatewayRequest, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
return doGateway(gatewayRequest, httpServletRequest, httpServletResponse);
}
private String doGateway(GatewayRequest gatewayRequest, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
try {
RequestContext requestContext = RequestContext.getCurrentContext();
requestContext.setRequest(httpServletRequest);
requestContext.setResponse(httpServletResponse);
GatewayResponse gatewayResponse = gatewayService.invoke(gatewayRequest);
/**
* see https://github.com/alibaba/fastjson/issues/2780
*/
JSONObject result = new JSONObject();
convertResponse(result, gatewayResponse);
return JsonUtil.toJSONString(result, PropertyNamingStrategy.SnakeCase);
} finally {
RequestContext.getCurrentContext().reset();
}
}
private void convertResponse(JSONObject result, GatewayResponse gatewayResponse) {
result.put("code", gatewayResponse.getCode());
result.put("msg", gatewayResponse.getMsg());
Map<String, Object> data = gatewayResponse.getResponse();
data.remove("code");
data.remove("msg");
if (!CollectionUtils.isEmpty(data)) {
result.put("data", data);
if (StringUtils.isNotBlank(gatewayResponse.getEncryptData())) {
result.put("data", gatewayResponse.getEncryptData());
}
}
result.put("sign", gatewayResponse.getSign());
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.RequestContext;
import org.springframework.core.Ordered;
/**
* 抽象过滤器
* @author key
*/
public abstract class AbstractFilter implements Filter, Ordered {
@Override
public void doFilter(GatewayRequest request, GatewayResponse response, FilterChain chain) {
RequestContext context = RequestContext.getCurrentContext();
if (context.isExcludeFilter(getFilterName())) {
chain.doFilter(request, response);
} else {
internalDoFilter(request, response, chain);
}
}
/**
* 执行过滤
*
* @param request
* @param response
* @param chain
*/
protected abstract void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain);
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.StringUtil;
import com.jz.dm.gateway.common.exception.GatewayException;
import com.jz.dm.gateway.common.util.SignType;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.Format;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.GatewayResultCode;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
/**
* 参数检查
*
* @author key
*/
@Component
public class CheckArgsFilter extends AbstractFilter {
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
// 校验参数非空
if (StringUtil.isEmpty(request.getAppId()) || StringUtil.isEmpty(request.getMethod())
|| StringUtil.isEmpty(request.getCharset()) || StringUtil.isEmpty(request.getSignType())
|| StringUtil.isEmpty(request.getSign()) || StringUtil.isEmpty(request.getTimestamp())
|| StringUtil.isEmpty(request.getVersion())
|| StringUtil.isEmpty(request.getParams())) {
throw new GatewayException(GatewayResultCode.ILLEGAL_ARGUMENT);
}
// 设置默认值
if (StringUtil.isEmpty(request.getFormat())) {
request.setFormat(Format.JSON.name());
}
try {
Format.valueOf(request.getFormat());
Charset.forName(request.getCharset());
SignType.valueOf(request.getSignType());
} catch (Exception ex) {
throw new GatewayException(GatewayResultCode.ILLEGAL_ARGUMENT);
}
chain.doFilter(request, response);
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_2;
}
@Override
public String getFilterName() {
return "CheckArgsFilter";
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.exception.GatewayException;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.GatewayResultCode;
import com.jz.dm.gateway.model.RequestContext;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 检查提交数据大小
*
*/
@Component("CheckPostSizeFilter")
public class CheckPostSizeFilter extends AbstractFilter {
@Override
public String getFilterName() {
return "CheckPostSizeFilter";
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_1;
}
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
HttpServletRequest httpServletRequest = RequestContext.getCurrentContext().getRequest();
Boolean postDataTooLarge = (Boolean) httpServletRequest.getAttribute("postDataTooLarge");
if (postDataTooLarge != null && postDataTooLarge) {
Integer maxPostSize = (Integer) httpServletRequest.getAttribute("maxPostSize");
Integer postSize = (Integer) httpServletRequest.getAttribute("postSize");
throw new GatewayException(GatewayResultCode.POST_DATA_TOO_LARGE,
"maxPostSize:" + maxPostSize + ", postSize:" + postSize);
}
chain.doFilter(request, response);
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.exception.GatewayException;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.GatewayResultCode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 时间戳校验过滤器
*
* @author key
*/
@Component
public class CheckTimestampFilter extends AbstractFilter {
@Value("${api.skipFilter}")
private boolean skipFilter;
/**
* 时间戳超时分钟,10分钟
*/
private static final long max = 1000 * 60 * 10; //10分钟
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response, FilterChain chain) {
if (!skipFilter) {
String timestamp = request.getTimestamp();
long time = 0;
try {
time = Long.valueOf(timestamp);
} catch (Exception ex) {
throw new GatewayException(GatewayResultCode.ILLEGAL_ARGUMENT);
}
if (System.currentTimeMillis() - time > max) {
throw new GatewayException(GatewayResultCode.ILLEGAL_REQUEST);
}
}
chain.doFilter(request, response);
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_5;
}
@Override
public String getFilterName() {
return "CheckTimestampFilter";
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
/**
* 过滤器
*
* @author key
*/
public interface Filter {
/**
* Returns the filter-name of this filter as defined in the deployment
* descriptor.
*/
public String getFilterName();
/**
* 执行过滤
*
* @param request gateway request
* @param response gateway response
* @param chain filter chain
*/
void doFilter(GatewayRequest request, GatewayResponse response, FilterChain chain);
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
/**
* 请求过滤链
* @author key
*/
public interface FilterChain {
/**
* 请求过滤
*
* @param request gateway request
* @param response gateway response
*/
void doFilter(GatewayRequest request, GatewayResponse response);
}
package com.jz.dm.gateway.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 过滤链工厂
*
*/
@Component
public class FilterChainFactory {
@Autowired
private FilterFactory filterFactory;
/**
* 获取过滤链
*
*/
public FilterChain getFilterChain() {
List<Filter> filters = filterFactory.getFilters();
return new FilterChainImpl(filters);
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.exception.OpenApiException;
import com.jz.dm.gateway.common.util.LogUtil;
import com.jz.dm.gateway.common.util.ResultCode;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.GatewayResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* 过滤链
*
*/
public class FilterChainImpl implements FilterChain {
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
private int pos = 0;
private final List<Filter> filters = new ArrayList<Filter>();
public FilterChainImpl() { }
public FilterChainImpl(List<Filter> filters) {
addFilters(filters);
}
@Override
public void doFilter(GatewayRequest request, GatewayResponse response) {
Filter nextFilter = nextFilter();
if (nextFilter == null) {
return;
}
try {
nextFilter.doFilter(request, response, this);
} catch (OpenApiException ex) {
ResultCode resultCode = ex.getResultCode();
LogUtil.error(LOGGER, ex, "doFilter occur exception,code=" + resultCode.getCode()
+ ",msg=" + resultCode.getMsg() + ",request=" + request);
response.setCode(ex.getResultCode().getCode());
response.setMsg(ex.getResultCode().getMsg());
} catch (Throwable ex) {
LogUtil.error(LOGGER, ex, "doFilter occur unknown exception,request=" + request);
response.setCode(GatewayResultCode.UNKNOWN_EXCEPTION.getCode());
response.setMsg(GatewayResultCode.UNKNOWN_EXCEPTION.getMsg());
}
}
public Filter nextFilter() {
if (pos < filters.size()) {
return filters.get(pos++);
}
return null;
}
public void addFilters(List<Filter> filters) {
this.filters.addAll(filters);
}
public void addFilter(Filter filter) {
this.filters.add(filter);
}
public void addFilter(int index, Filter filter) {
this.filters.add(index, filter);
}
}
package com.jz.dm.gateway.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 过滤器工厂
*
*/
@Component
public class FilterFactory {
/**
* 过滤器列表
*/
@Autowired
private final List<Filter> filters = new ArrayList<Filter>();
/**
* 获取过滤器列表
*
* @return
*/
public List<Filter> getFilters() {
return filters;
}
}
package com.jz.dm.gateway.filter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jz.dm.gateway.common.exception.GatewayException;
import com.jz.dm.gateway.common.util.LogUtil;
import com.jz.dm.gateway.config.LoggingConstants;
import com.jz.dm.gateway.gateway.DefaultOpenApiDispatcher;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.*;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 网关路由过滤器
*
*/
@Component
public class InvokeRouteFilter extends AbstractFilter {
/** openapi dispatcher logger */
private static final Logger DISPATCHER_LOGGER = LoggingConstants.DISPATCHER_LOGGER;
@Autowired
DefaultOpenApiDispatcher defaultOpenApiDispatcher;
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
String openApiResponse = null;
long startTime = System.currentTimeMillis();
try {
OpenApi openApi = (OpenApi) RequestContext.getCurrentContext().get("openApi");
if (openApi.getRouteType() == null) {
throw new GatewayException(GatewayResultCode.ILLEGAL_ROUTE_TYPE);
}
if (openApi.getRouteType() != RouteType.SRPING) {
chain.doFilter(request, response);
return;
}
DispatchContext context = new DispatchContext();
context.setAppId(request.getAppId());
context.setApplication(openApi.getApplication());
context.setOpenApiMethod(request.getMethod());
context.setOpenApiParams(request.getParams());
context.setOpenApiVersion(request.getVersion());
for (GatewayRequest.Attribute attribute : request.getExtAttributes().values()) {
if (attribute != null && attribute.isPass) {
context.setExtAttribute(attribute.name, attribute.value);
}
}
openApiResponse = defaultOpenApiDispatcher.doDispatch(context);
JSONObject jsonObject = (JSONObject) JSON.parse(openApiResponse);
response.setAttribute(jsonObject);
} finally {
long elapseTime = System.currentTimeMillis() - startTime;
LogUtil.info(DISPATCHER_LOGGER,
"gateway do default dispatch,request=" + request + ",response=" + openApiResponse
+ "," + elapseTime + "ms");
}
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_6;
}
@Override
public String getFilterName() {
return "InvokeRouteFilter";
}
}
package com.jz.dm.gateway.filter;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.jz.dm.gateway.common.StringUtil;
import com.jz.dm.gateway.common.exception.SignatureException;
import com.jz.dm.gateway.common.util.*;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.GatewayResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.security.interfaces.RSAPrivateKey;
import java.util.HashMap;
import java.util.Map;
/**
* 签名过滤器
*/
@Component
public class SignatureFilter extends AbstractFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(SignatureFilter.class);
// @Autowired
// private IApiWhiteService apiWhiteService;
@Value("${secret_private}")
private String secretPrivate;
private String encryptData;
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
try {
chain.doFilter(request, response);
} finally {
String responseJson = null;
String sign = StringUtil.EMPTY_STRING;
String privatekey = null;
if (StringUtil.isEmpty(request.getAppId())) {
return;
}
//ApiWhite apiWhite = apiWhiteService.byMerchantId(request.getAppId());
//if (apiWhite == null) {
// return;
//}
//是否提供密码
//boolean providePublicKey = false;
//if ("0".equals(apiWhite.getProvideSecret())) {
// privatekey = apiWhite.getSecretKey();
//} else if ("1".equals(apiWhite.getProvideSecret())) {
// privatekey = secretPrivate;
// providePublicKey = true;
//}
try {
responseJson = JsonUtil.toJSONString(response.getResponse(),
PropertyNamingStrategy.SnakeCase);
if (StringUtil.isNotEmpty(request.getSignType())) {
String charset = request.getCharset();
if (StringUtil.isEmpty(charset)) {
charset = Constants.CHARSET_UTF8;
}
//if (providePublicKey) {
// sign = SignatureUtil.sign(convertResult(response.getResponse(), response, apiWhite), privatekey, charset, SignType.valueOf(request.getSignType()), SignatureUtil.SIGN_REQUEST, providePublicKey);
//} else {
// sign = SignatureUtil.sign(convertResult(response.getResponse(), response, apiWhite), privatekey, charset, SignType.valueOf(request.getSignType()), SignatureUtil.SIGN_REQUEST, providePublicKey);
//}
}
} catch (JSONException e) {
LogUtil.error(LOGGER, e,
"serializer response to json string error. response=" + response.getResponse());
response.clearAttributes();
response.setCode(OpenApiResultCode.RESPONSE_DATA_FORMAT_ERROR.getCode());
response.setMsg(OpenApiResultCode.RESPONSE_DATA_FORMAT_ERROR.getMsg());
// sign = signatureException(request, response, privatekey, providePublicKey);
} catch (SignatureException ex) {
LogUtil.error(LOGGER, ex,
"sign response error. response=" + response.getResponse());
response.clearAttributes();
response.setCode(ex.getResultCode().getCode());
response.setMsg(ex.getResultCode().getMsg());
} catch (Throwable ex) {
LogUtil.error(LOGGER, ex,
"signatureFilter doFilter error. response=" + response.getResponse());
response.clearAttributes();
response.setCode(GatewayResultCode.UNKNOWN_EXCEPTION.getCode());
response.setMsg(GatewayResultCode.UNKNOWN_EXCEPTION.getMsg());
// sign = signatureException(request, response, privatekey, providePublicKey);
}
response.setSign(sign);
//if (apiWhite.getIsEncrypt()) {
// response.setEncryptData(encryptData);
//}
}
}
private Map<String, Object> convertResult(Map<String, Object> attributes, GatewayResponse response) {
Map<String, Object> mapResult = new HashMap<>();
mapResult.put("code", response.getCode());
mapResult.put("msg", response.getMsg());
Object code = attributes.get("code");
Object msg = attributes.get("msg");
attributes.remove("code");
attributes.remove("msg");
if (!CollectionUtils.isEmpty(attributes)) {
mapResult.put("data", JsonUtil.toJSONString(attributes, PropertyNamingStrategy.SnakeCase));
//if (apiWhite.getIsEncrypt()) {
// String string = (String) mapResult.get("data");
// try {
// RSAPrivateKey privateKey = RSAUtils.getPrivateKey(secretPrivate);
// String encrypt = RSAUtils.privateEncrypt(string, privateKey);
// mapResult.put("data", encrypt);
// encryptData = encrypt;
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
}
attributes.put("code", code);
attributes.put("msg", msg);
return mapResult;
}
private String signatureException(GatewayRequest request, GatewayResponse response,
String privateKey, boolean providePublicKey) {
String responseJson = null;
String sign = StringUtil.EMPTY_STRING;
try {
responseJson = JsonUtil.toJSONString(response.getResponse(),
PropertyNamingStrategy.SnakeCase);
} catch (JSONException e1) {
LogUtil.error(LOGGER, e1,
"serializer response to json string error. response=" + response.getResponse());
return sign;
}
try {
sign = SignatureUtil.sign(responseJson, privateKey, request.getCharset(), SignType.valueOf(request.getSignType()), SignatureUtil.SIGN_REQUEST, providePublicKey);
} catch (SignatureException ex) {
LogUtil.error(LOGGER, ex, "sign response error. response=" + response.getResponse());
}
return sign;
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_0;
}
@Override
public String getFilterName() {
return "SignatureFilter";
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.util.HddHashMap;
import com.jz.dm.gateway.common.util.RSAUtils;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.security.interfaces.RSAPublicKey;
/**
* 验签过滤器
*/
@Slf4j
@Component
public class VerifySignFilter extends AbstractFilter {
//@Autowired
//private IApiWhiteService apiWhiteService;
@Value("${api.skipFilter}")
private boolean skipFilter;
private final static String CHARSET = "UTF-8";
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
HddHashMap params = new HddHashMap();
params.put("app_id", request.getAppId());
params.put("method", request.getMethod());
params.put("charset", request.getCharset());
params.put("sign", request.getSign());
params.put("sign_type", request.getSignType());
params.put("timestamp", request.getTimestamp());
params.put("version", request.getVersion());
params.put("params", request.getParams());
//ApiWhite apiWhite = apiWhiteService.byMerchantId(request.getAppId());
//if (apiWhite != null) {
// String publicKey = apiWhite.getSecretKey();
//
// if (!skipFilter) {
// boolean verify = SignatureUtil.verify(params, publicKey, request.getCharset(), SignType.valueOf(request.getSignType()));
// if (!verify) {
// throw new SignatureException(OpenApiResultCode.SIGN_VERIFY_ERROR);
// }
//
// //参数解密
// if (apiWhite.getIsEncrypt()) {
// String decryptParams = decryptParams(request.getParams(), publicKey);
// request.setParams(decryptParams);
// }
// }
//}
// 后期再扩展
OpenApi openApi = new OpenApi();
openApi.setApplication("HDD_API_GATEWAY");
openApi.setRouteType(RouteType.SRPING);
RequestContext.getCurrentContext().set("openApi", openApi);
chain.doFilter(request, response);
}
private String decryptParams(String params, String publicKey) {
log.info("解密前请求参数,{}", params);
try {
RSAPublicKey key = RSAUtils.getPublicKey(publicKey);
String decrypt = RSAUtils.publicDecrypt(params, key);
log.info("解密后请求参数,{}", decrypt);
return decrypt;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_4;
}
@Override
public String getFilterName() {
return "VerifySignFilter";
}
}
package com.jz.dm.gateway.gateway;
import com.alibaba.fastjson.JSON;
import com.jz.dm.gateway.common.StringUtil;
import com.jz.dm.gateway.common.exception.OpenApiException;
import com.jz.dm.gateway.common.util.OpenApiRequest;
import com.jz.dm.gateway.common.util.OpenApiResponse;
import com.jz.dm.gateway.common.util.OpenApiResultCode;
import com.jz.dm.gateway.model.DispatchContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 默认openapi分发器
*
*/
@Component
public class DefaultOpenApiDispatcher implements OpenApiDispatcher {
private static final Logger LOGGER = LoggerFactory
.getLogger(DefaultOpenApiDispatcher.class);
/**
* openapi服务
*/
private final Map<String, OpenApiService> openApiServices = new ConcurrentHashMap<String, OpenApiService>();
/**
* 服务注入可参考: /openapi-demo/src/main/resources/META-INF/application-context.xml
* @param openApiServiceList
* <pre>
* &lt;!-- 定义开放接口服务 -->
* &lt;bean id="addUserOpenApiService" class="com.xxx.openapi.demo.openapi.AddUserOpenApiService" /&gt;
* &lt;bean id="getUserOpenApiService" class="com.xxx.openapi.demo.openapi.GetUserOpenApiService" /&gt;
* </pre>
*/
@Resource
public void setOpenApiServices(List<OpenApiService> openApiServiceList) {
for (OpenApiService openApiService : openApiServiceList) {
String openApiServiceKey = getOpenApiServiceKey(openApiService.getOpenApiMethod(),
openApiService.getOpenApiVersion());
openApiServices.put(openApiServiceKey, openApiService);
}
}
private String getOpenApiServiceKey(String openApiMethod, String openApiVersion) {
return openApiMethod + "&" + openApiVersion;
}
@Override
public String doDispatch(DispatchContext context) {
OpenApiResponse response = new OpenApiResponse();
String openApiServiceKey = getOpenApiServiceKey(context.getOpenApiMethod(),
context.getOpenApiVersion());
OpenApiService openApiService = openApiServices.get(openApiServiceKey);
if (openApiService == null) {
response.setCode(OpenApiResultCode.ILLEGAL_INTERFACE.getCode());
response.setMsg(OpenApiResultCode.ILLEGAL_INTERFACE.getMsg());
return JSON.toJSONString(response.getAttributes());
}
try {
OpenApiRequest request = new OpenApiRequest(context.getOpenApiParams());
request.setAppId(context.getAppId());
request.setExtAttributes(context.getExtAttributes());
openApiService.doService(request, response);
} catch (Throwable ex) {
if (ex instanceof OpenApiException) {
OpenApiException oae = (OpenApiException) ex;
response.setCode(oae.getResultCode().getCode());
response.setMsg(oae.getResultCode().getMsg());
} else {
LOGGER.error("OpenApiService doService error,DispatchContext=" + context, ex);
response.setCode(OpenApiResultCode.UNKNOWN_EXCEPTION.getCode());
response.setMsg(OpenApiResultCode.UNKNOWN_EXCEPTION.getMsg());
}
return JSON.toJSONString(response.getAttributes());
}
if (StringUtil.isEmpty(response.getCode())) {
response.setCode(OpenApiResultCode.SUCCESS.getCode());
response.setMsg(OpenApiResultCode.SUCCESS.getMsg());
}
return JSON.toJSONString(response.getAttributes());
}
}
package com.jz.dm.gateway.gateway;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
/**
* GatewayService
*/
public interface GatewayService {
GatewayResponse invoke(GatewayRequest gatewayRequest);
}
package com.jz.dm.gateway.gateway;
import com.jz.dm.gateway.model.DispatchContext;
/**
* openapi分发器
*
*/
public interface OpenApiDispatcher {
/**
* openapi dispatch
*
* @param context dispatch context
*
* @return
*/
public String doDispatch(DispatchContext context);
}
package com.jz.dm.gateway.gateway;
import com.jz.dm.gateway.common.util.OpenApiRequest;
import com.jz.dm.gateway.common.util.OpenApiResponse;
/**
* openapi服务
*
*/
public interface OpenApiService {
/**
* 获取openapi接口名
*
* @return
*/
public String getOpenApiMethod();
/**
* 获取openapi接口版本
*
* @return
*/
public String getOpenApiVersion();
/**
* openapi服务调用
*
* @param request
* @param response
*/
public void doService(OpenApiRequest request, OpenApiResponse response);
}
package com.jz.dm.gateway.gateway.common;
/**
* 常量
*
*/
public class Constants {
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_TYPE = "sign_type";
public static final String SIGN = "sign";
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 PARAMS = "params";
public static final String RESPONSE = "response";
public static final String SUCCESS = "SUCCESS";
public static final String BUSINESS_ID = "business_id";
public static final String NOTIFY_TYPE = "notify_type";
public static final String NOTIFY_TIME = "notify_time";
/** 默认时间格式 **/
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";
/** 默认版本 */
public static final String DEFAULT_VERSION = "1.0.0";
public static final int FILTER_ORDER_0 = 0;
public static final int FILTER_ORDER_1 = 1;
public static final int FILTER_ORDER_2 = 2;
public static final int FILTER_ORDER_3 = 3;
public static final int FILTER_ORDER_4 = 4;
public static final int FILTER_ORDER_5 = 5;
public static final int FILTER_ORDER_6 = 6;
}
/**
* Copyright (c) 2011-2019 All Rights Reserved.
*/
package com.jz.dm.gateway.gateway.impl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* API白名单表 服务实现类
*
* @author zengxx
* @version $Id: ApiWhiteServiceImpl.java 2020-04-02 $
*/
//@Service("apiWhiteService")
//public class ApiWhiteServiceImpl implements IApiWhiteService {
//@Resource
//private ApiWhiteMapper apiWhiteMapper;
//@Resource
//private MeasureRecordMapper measureRecordMapper;
//
//@Override
//public ApiWhite byMerchantId(String merchantId) throws TtyException {
// return apiWhiteMapper.byMerchantId(merchantId);
//}
//
//@Override
//@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
//public long adjustAmt(String merchantId, long amt) {
// if (amt == 0) {
// return amt;
// }
// BigDecimal adjustAmt = new BigDecimal(amt).divide(new BigDecimal(100));
// ApiWhite apiWhite = apiWhiteMapper.byMerchantId(merchantId);
// long result = apiWhiteMapper.adjustAmt(merchantId, adjustAmt);
// if (result != 1) {
// return 0;
// } else {
// MeasureRecord measure = new MeasureRecord();
// //已用金额
// BigDecimal sumUseAmt = apiWhiteMapper.sumUseAmt(merchantId);
// if (sumUseAmt == null) {
// sumUseAmt = BigDecimal.ZERO;
// }
// if (amt > 0) {
// measure.setChangType("0");
// measure.setUseAmount(sumUseAmt.subtract(adjustAmt));
// } else {
// measure.setChangType("1");
// measure.setUseAmount(sumUseAmt.add(adjustAmt.abs()));
// }
// measure.setChangeAmount(adjustAmt.abs());
// measure.setAfterAmount(apiWhite.getUsableAmount().add(adjustAmt));
//
// measure.setMerchantId(apiWhite.getMerchantId());
// measure.setName(apiWhite.getName());
// measure.setBeforeAmount(apiWhite.getUsableAmount());
// measure.setChangDate(LocalDateTime.now());
// measure.setCreateUser("API");
// measure.setCreateDate(LocalDateTime.now());
// //插入流水信息
// if (measureRecordMapper.insert(measure) > 0) {
// return 1;
// }
// }
// return 0;
//}
//@Override
//@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
//public void invoke3bcCount(String merchantId) {
// apiWhiteMapper.invoke3bcCount(merchantId);
//}
//}
package com.jz.dm.gateway.gateway.impl;
import com.jz.dm.gateway.filter.FilterChain;
import com.jz.dm.gateway.filter.FilterChainFactory;
import com.jz.dm.gateway.gateway.GatewayService;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 网关服务
*
*/
@Service
public class GatewayServiceImpl implements GatewayService {
@Autowired
private FilterChainFactory filterChainFactory;
@Override
public GatewayResponse invoke(GatewayRequest gatewayRequest) {
GatewayResponse gatewayResponse = new GatewayResponse();
FilterChain filterChain = filterChainFactory.getFilterChain();
filterChain.doFilter(gatewayRequest, gatewayResponse);
return gatewayResponse;
}
}
package com.jz.dm.gateway.model;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* Dispatch Context
*/
public class DispatchContext implements Serializable {
/**
* 序列号
*/
private static final long serialVersionUID = -3448256355423553719L;
/**
* 商户应用id
*/
private String appId;
/**
* 应用
*/
private String application;
/**
* openapi接口
*/
private String openApiMethod;
/**
* openapi接口参数,json格式
*/
private String openApiParams;
/**
* openapi接口版本
*/
private String openApiVersion;
/**
* 扩展属性
*/
private final Map<String, Object> extAttributes = new HashMap<String, Object>();
/**
* Getter method for property <tt>appId</tt>.
*
* @return property value of appId
*/
public String getAppId() {
return appId;
}
/**
* Setter method for property <tt>appId</tt>.
*
* @param appId value to be assigned to property appId
*/
public void setAppId(String appId) {
this.appId = appId;
}
/**
* Getter method for property <tt>application</tt>.
*
* @return property value of application
*/
public String getApplication() {
return application;
}
/**
* Setter method for property <tt>application</tt>.
*
* @param application value to be assigned to property application
*/
public void setApplication(String application) {
this.application = application;
}
/**
* Getter method for property <tt>openApiMethod</tt>.
*
* @return property value of openApiMethod
*/
public String getOpenApiMethod() {
return openApiMethod;
}
/**
* Setter method for property <tt>openApiMethod</tt>.
*
* @param openApiMethod value to be assigned to property openApiMethod
*/
public void setOpenApiMethod(String openApiMethod) {
this.openApiMethod = openApiMethod;
}
/**
* Getter method for property <tt>openApiParams</tt>.
*
* @return property value of openApiParams
*/
public String getOpenApiParams() {
return openApiParams;
}
/**
* Setter method for property <tt>openApiParams</tt>.
*
* @param openApiParams value to be assigned to property openApiParams
*/
public void setOpenApiParams(String openApiParams) {
this.openApiParams = openApiParams;
}
/**
* Getter method for property <tt>openApiVersion</tt>.
*
* @return property value of openApiVersion
*/
public String getOpenApiVersion() {
return openApiVersion;
}
/**
* Setter method for property <tt>openApiVersion</tt>.
*
* @param openApiVersion value to be assigned to property openApiVersion
*/
public void setOpenApiVersion(String openApiVersion) {
this.openApiVersion = openApiVersion;
}
/**
* 获取扩展属性
*
* @param attributeName
* @return
*/
@SuppressWarnings("unchecked")
public <T> T getExtAttribute(String attributeName) {
return (T) extAttributes.get(attributeName);
}
/**
* 设置属性
*
* @param attributeName
* @param attributeValue
*/
public void setExtAttribute(String attributeName, Object attributeValue) {
extAttributes.put(attributeName, attributeValue);
}
/**
* Getter method for property <tt>extAttributes</tt>.
*
* @return property value of extAttributes
*/
public Map<String, Object> getExtAttributes() {
return extAttributes;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "DispatchContext [application=" + application + ", openApiMethod=" + openApiMethod
+ ", openApiParams=" + openApiParams + ", openApiVersion=" + openApiVersion + "]";
}
}
package com.jz.dm.gateway.model;
/**
* 数据格式
*
*/
public enum Format {
JSON, XML
}
package com.jz.dm.gateway.model;
import com.jz.dm.gateway.web.annotation.ParamName;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* api请求
*
* @author key
*/
public class GatewayRequest implements Serializable {
/**
* 分配的ID
*/
@ParamName("app_id")
private String appId;
/**
* 接口名称
*/
private String method;
/**
* 格式,目前仅支持JSON
*/
private String format;
/**
* 请求使用的编码格式,如UTF-8,GBK,GB2312等
*/
private String charset;
/**
* 生成签名字符串所使用的签名算法类型
*/
@ParamName("sign_type")
private String signType;
/**
* 请求参数的签名串
*/
private String sign;
/**
* 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss"
*/
private String timestamp;
/**
* 调用的接口版本,固定为:1.0
*/
private String version;
/**
* 回调通知地址
*/
@ParamName("notify_url")
private String notifyUrl;
/**
* 返回地址
*/
@ParamName("return_url")
private String returnUrl;
/**
* 请求参数,JSON格式
*/
private String params;
/**
* 扩展属性
*/
private final Map<String, Attribute> extAttributes = new HashMap<String, Attribute>();
/**
* Getter method for property <tt>appId</tt>.
*
* @return property value of appId
*/
public String getAppId() {
return appId;
}
/**
* Setter method for property <tt>appId</tt>.
*
* @param appId value to be assigned to property appId
*/
public void setAppId(String appId) {
this.appId = appId;
}
/**
* Getter method for property <tt>method</tt>.
*
* @return property value of method
*/
public String getMethod() {
return method;
}
/**
* Setter method for property <tt>method</tt>.
*
* @param method value to be assigned to property method
*/
public void setMethod(String method) {
this.method = method;
}
/**
* Getter method for property <tt>format</tt>.
*
* @return property value of format
*/
public String getFormat() {
return format;
}
/**
* Setter method for property <tt>format</tt>.
*
* @param format value to be assigned to property format
*/
public void setFormat(String format) {
this.format = format;
}
/**
* Getter method for property <tt>charset</tt>.
*
* @return property value of charset
*/
public String getCharset() {
return charset;
}
/**
* Setter method for property <tt>charset</tt>.
*
* @param charset value to be assigned to property charset
*/
public void setCharset(String charset) {
this.charset = charset;
}
/**
* Getter method for property <tt>signType</tt>.
*
* @return property value of signType
*/
public String getSignType() {
return signType;
}
/**
* Setter method for property <tt>signType</tt>.
*
* @param signType value to be assigned to property signType
*/
public void setSignType(String signType) {
this.signType = signType;
}
/**
* Getter method for property <tt>sign</tt>.
*
* @return property value of sign
*/
public String getSign() {
return sign;
}
/**
* Setter method for property <tt>sign</tt>.
*
* @param sign value to be assigned to property sign
*/
public void setSign(String sign) {
this.sign = sign;
}
/**
* Getter method for property <tt>timestamp</tt>.
*
* @return property value of timestamp
*/
public String getTimestamp() {
return timestamp;
}
/**
* Setter method for property <tt>timestamp</tt>.
*
* @param timestamp value to be assigned to property timestamp
*/
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
/**
* Getter method for property <tt>version</tt>.
*
* @return property value of version
*/
public String getVersion() {
return version;
}
/**
* Setter method for property <tt>version</tt>.
*
* @param version value to be assigned to property version
*/
public void setVersion(String version) {
this.version = version;
}
/**
* Getter method for property <tt>notifyUrl</tt>.
*
* @return property value of notifyUrl
*/
public String getNotifyUrl() {
return notifyUrl;
}
/**
* Setter method for property <tt>notifyUrl</tt>.
*
* @param notifyUrl value to be assigned to property notifyUrl
*/
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
/**
* Getter method for property <tt>returnUrl</tt>.
*
* @return property value of returnUrl
*/
public String getReturnUrl() {
return returnUrl;
}
/**
* Setter method for property <tt>returnUrl</tt>.
*
* @param returnUrl value to be assigned to property returnUrl
*/
public void setReturnUrl(String returnUrl) {
this.returnUrl = returnUrl;
}
/**
* Getter method for property <tt>params</tt>.
*
* @return property value of params
*/
public String getParams() {
return params;
}
/**
* Setter method for property <tt>params</tt>.
*
* @param params value to be assigned to property params
*/
public void setParams(String params) {
this.params = params;
}
/**
* 获取扩展属性
*
* @param attributeName
* @return
*/
public Attribute getExtAttribute(String attributeName) {
return extAttributes.get(attributeName);
}
/**
* 设置属性
*
* @param attribute
*/
public void setExtAttribute(Attribute attribute) {
if (attribute == null) {
return;
}
extAttributes.put(attribute.name, attribute);
}
/**
* Getter method for property <tt>extAttributes</tt>.
*
* @return property value of extAttributes
*/
public Map<String, Attribute> getExtAttributes() {
return extAttributes;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "GatewayRequest [appId=" + appId + ", method=" + method + ", format=" + format
+ ", charset=" + charset + ", signType=" + signType + ", sign=" + sign
+ ", timestamp=" + timestamp + ", version=" + version + ", notifyUrl=" + notifyUrl
+ ", returnUrl=" + returnUrl + ", params=" + params + ", extAttributes="
+ extAttributes + "]";
}
public static class Attribute {
/**
*  熟悉名称
*/
public String name;
/**
* 属性值
*/
public Object value;
/**
* 是否传递到业务系统
*/
public boolean isPass;
public Attribute(String name, Object value) {
this(name, value, false);
}
public Attribute(String name, Object value, boolean isPass) {
this.name = name;
this.value = value;
this.isPass = isPass;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "Attribute [name=" + name + ", value=" + value + ", isPass=" + isPass + "]";
}
}
}
package com.jz.dm.gateway.model;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.HashMap;
import java.util.Map;
/**
* api响应
*
* @author key
*/
@JSONType(orders = { "response", "sign" })
public class GatewayResponse {
/**
* 结果码
*/
private static final String ATTRIBUTE_NAME_CODE = "code";
/**
* 结果消息
*/
private static final String ATTRIBUTE_NAME_MSG = "msg";
/**
* 数据签名
*/
private String sign;
/**
* 属性信息
*/
private final Map<String, Object> attributes = new HashMap<String, Object>();
/**
* 加密后参数密文
*/
@JsonIgnore
private String encryptData;
public String getEncryptData() {
return encryptData;
}
public void setEncryptData(String encryptData) {
this.encryptData = encryptData;
}
/**
* 默认构造函数
*/
public GatewayResponse() {
}
/**
* 构造函数,初始化属性信息
*
* @param attributes
*/
public GatewayResponse(Map<String, Object> attributes) {
this.attributes.putAll(attributes);
}
@JSONField(serialize = false)
public String getCode() {
return (String) attributes.get(ATTRIBUTE_NAME_CODE);
}
public void setCode(String code) {
attributes.put(ATTRIBUTE_NAME_CODE, code);
}
@JSONField(serialize = false)
public String getMsg() {
return (String) attributes.get(ATTRIBUTE_NAME_MSG);
}
public void setMsg(String msg) {
attributes.put(ATTRIBUTE_NAME_MSG, msg);
}
@SuppressWarnings("unchecked")
public <T> T getAttribute(String attributeName) {
return (T) attributes.get(attributeName);
}
public void setAttribute(String attributeName, Object attributeValue) {
attributes.put(attributeName, attributeValue);
}
public void setAttribute(Map<String, Object> attributes) {
this.attributes.putAll(attributes);
}
public void clearAttributes() {
attributes.clear();
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public Map<String, Object> getResponse() {
return attributes;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "GatewayResponse [sign=" + sign + ", attributes=" + attributes + "]";
}
}
package com.jz.dm.gateway.model;
import com.jz.dm.gateway.common.util.ResultCode;
import java.util.HashMap;
import java.util.Map;
/**
* 网关结果码
*
*/
public enum GatewayResultCode implements ResultCode {
/** 处理成功 */
SUCCESS("SUCCESS", "处理成功"),
/** 处理成功 */
FAIL("FAIL", "处理失败"),
/** 未知异常 */
UNKNOWN_EXCEPTION("UNKNOWN_EXCEPTION", "未知异常"),
/** 无效接口 */
ILLEGAL_INTERFACE("ILLEGAL_INTERFACE", "无效接口"),
/** 无效参数 */
ILLEGAL_ARGUMENT("ILLEGAL_ARGUMENT", "无效参数"),
/** 无效请求 */
ILLEGAL_REQUEST("ILLEGAL_REQUEST", "无效请求"),
/** 接口未授权 */
INTERFACE_NO_AUTHORITY("INTERFACE_NO_AUTHORITY", "接口未授权"),
/** 请求超过限制 */
RATE_LIMIT_EXCEEDED("RATE_LIMIT_EXCEEDED", "请求超过限制"),
/** 无效路由类型 */
ILLEGAL_ROUTE_TYPE("ILLEGAL_ROUTE_TYPE", "无效路由类型"),
/** ip不允许访问 */
IP_NOT_ALLOW_ACCESS("IP_NOT_ALLOW_ACCESS", "ip不允许访问"),
/** ip不允许访问 */
IP_NOT_CONFIG("IP_NOT_CONFIG", "未配置白名单"),
/** 提交数据过大 */
POST_DATA_TOO_LARGE("POST_DATA_TOO_LARGE", "提交数据过大"),
/** 调用转发异常 */
DISPATCHER_EXCEPTION("DISPATCHER_EXCEPTION", "调用转发异常"),
/*账户不存在*/
ACCOUNT_EXIST("ACCOUNT_EXIST","账户信息不存在");
;
/**
* 初始化保存到map里方便根据code获取
*/
private static Map<String, GatewayResultCode> RESULT_CODES = new HashMap<String, GatewayResultCode>();
static {
for (GatewayResultCode gatewayResultCode : GatewayResultCode.values()) {
RESULT_CODES.put(gatewayResultCode.code, gatewayResultCode);
}
}
/** 结果码 */
private String code;
/** 结果码信息 */
private String msg;
/**
* 构造函数
*
* @param code 结果码
* @param msg 结果码信息
*/
private GatewayResultCode(String code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 通过枚举<code>code</code>获得枚举
*
* @param code 结果码
* @return 枚举
*/
public static GatewayResultCode getGatewayResultCode(String code) {
return RESULT_CODES.get(code);
}
/**
* Getter method for property <tt>code</tt>.
*
* @return property value of code
*/
@Override
public String getCode() {
return code;
}
/**
* Setter method for property <tt>code</tt>.
*
* @param code value to be assigned to property code
*/
public void setCode(String code) {
this.code = code;
}
/**
* Getter method for property <tt>msg</tt>.
*
* @return property value of msg
*/
@Override
public String getMsg() {
return msg;
}
/**
* Setter method for property <tt>msg</tt>.
*
* @param msg value to be assigned to property msg
*/
public void setMsg(String msg) {
this.msg = msg;
}
}
package com.jz.dm.gateway.model;
import com.alibaba.fastjson.JSON;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* open api接口
*
*/
public class OpenApi {
/**
* id
*/
private Long id;
/**
* 接口名称
*/
private String method;
/**
* 描述
*/
private String description;
/**
* 数据格式
*/
private String format;
/**
* 请求使用的编码格式,如utf-8,gbk,gb2312等
*/
private String charset;
/**
* 生成签名字符串所使用的签名算法类型
*/
private String signType;
/**
* 调用的接口版本
*/
private String version;
/**
* 负责人
*/
private String owner;
/**
* 应用
*/
private String application;
/**
* 是否删除
*/
private Boolean isDelete;
/**
* 路由类型
*/
private RouteType routeType;
/**
* 路由Url
*/
private String routeUrl;
/**
* 路由请求编码
*/
private String routeCharset;
/**
* 扩展属性
*/
private Map<String, Object> extProperties = new HashMap<String, Object>();
/**
* 创建时间
*/
private Date gmtCreate;
/**
* 创建者
*/
private String createOperator;
/**
* 修改时间
*/
private Date gmtModified;
/**
* 最后修改者
*/
private String lastModifyOperator;
/**
* Getter method for property <tt>id</tt>.
*
* @return property value of id
*/
public Long getId() {
return id;
}
/**
* Setter method for property <tt>id</tt>.
*
* @param id value to be assigned to property id
*/
public void setId(Long id) {
this.id = id;
}
/**
* Getter method for property <tt>method</tt>.
*
* @return property value of method
*/
public String getMethod() {
return method;
}
/**
* Setter method for property <tt>method</tt>.
*
* @param method value to be assigned to property method
*/
public void setMethod(String method) {
this.method = method;
}
/**
* Getter method for property <tt>description</tt>.
*
* @return property value of description
*/
public String getDescription() {
return description;
}
/**
* Setter method for property <tt>description</tt>.
*
* @param description value to be assigned to property description
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Getter method for property <tt>format</tt>.
*
* @return property value of format
*/
public String getFormat() {
return format;
}
/**
* Setter method for property <tt>format</tt>.
*
* @param format value to be assigned to property format
*/
public void setFormat(String format) {
this.format = format;
}
/**
* Getter method for property <tt>charset</tt>.
*
* @return property value of charset
*/
public String getCharset() {
return charset;
}
/**
* Setter method for property <tt>charset</tt>.
*
* @param charset value to be assigned to property charset
*/
public void setCharset(String charset) {
this.charset = charset;
}
/**
* Getter method for property <tt>signType</tt>.
*
* @return property value of signType
*/
public String getSignType() {
return signType;
}
/**
* Setter method for property <tt>signType</tt>.
*
* @param signType value to be assigned to property signType
*/
public void setSignType(String signType) {
this.signType = signType;
}
/**
* Getter method for property <tt>version</tt>.
*
* @return property value of version
*/
public String getVersion() {
return version;
}
/**
* Setter method for property <tt>version</tt>.
*
* @param version value to be assigned to property version
*/
public void setVersion(String version) {
this.version = version;
}
/**
* Getter method for property <tt>owner</tt>.
*
* @return property value of owner
*/
public String getOwner() {
return owner;
}
/**
* Setter method for property <tt>owner</tt>.
*
* @param owner value to be assigned to property owner
*/
public void setOwner(String owner) {
this.owner = owner;
}
/**
* Getter method for property <tt>application</tt>.
*
* @return property value of application
*/
public String getApplication() {
return application;
}
/**
* Getter method for property <tt>isDelete</tt>.
*
* @return property value of isDelete
*/
public Boolean getIsDelete() {
return isDelete;
}
/**
* Setter method for property <tt>isDelete</tt>.
*
* @param isDelete value to be assigned to property isDelete
*/
public void setIsDelete(Boolean isDelete) {
this.isDelete = isDelete;
}
/**
* Getter method for property <tt>routeType</tt>.
*
* @return property value of routeType
*/
public RouteType getRouteType() {
return routeType;
}
/**
* Setter method for property <tt>routeType</tt>.
*
* @param routeType value to be assigned to property routeType
*/
public void setRouteType(RouteType routeType) {
this.routeType = routeType;
}
/**
* Getter method for property <tt>routeUrl</tt>.
*
* @return property value of routeUrl
*/
public String getRouteUrl() {
return routeUrl;
}
/**
* Setter method for property <tt>routeUrl</tt>.
*
* @param routeUrl value to be assigned to property routeUrl
*/
public void setRouteUrl(String routeUrl) {
this.routeUrl = routeUrl;
}
/**
* Getter method for property <tt>routeCharset</tt>.
*
* @return property value of routeCharset
*/
public String getRouteCharset() {
return routeCharset;
}
/**
* Setter method for property <tt>routeCharset</tt>.
*
* @param routeCharset value to be assigned to property routeCharset
*/
public void setRouteCharset(String routeCharset) {
this.routeCharset = routeCharset;
}
/**
* Setter method for property <tt>application</tt>.
*
* @param application value to be assigned to property application
*/
public void setApplication(String application) {
this.application = application;
}
@SuppressWarnings("unchecked")
public <T> T getExtProperty(String key) {
if (this.extProperties == null) {
return null;
}
return (T) this.extProperties.get(key);
}
public void setExtProperty(String key, Object value) {
if (this.extProperties == null) {
return;
}
this.extProperties.put(key, value);
}
public String getExtProperty() {
if (this.extProperties == null) {
return null;
}
return JSON.toJSONString(this.extProperties);
}
public void setExtProperty(String extProperty) {
if (extProperty == null) {
return;
}
this.extProperties = new HashMap<String, Object>(JSON.parseObject(extProperty));
}
/**
* Getter method for property <tt>extProperties</tt>.
*
* @return property value of extProperties
*/
public Map<String, Object> getExtProperties() {
return extProperties;
}
/**
* Setter method for property <tt>extProperties</tt>.
*
* @param extProperties value to be assigned to property extProperties
*/
public void setExtProperties(Map<String, Object> extProperties) {
this.extProperties = extProperties;
}
/**
* Getter method for property <tt>gmtCreate</tt>.
*
* @return property value of gmtCreate
*/
public Date getGmtCreate() {
return gmtCreate;
}
/**
* Setter method for property <tt>gmtCreate</tt>.
*
* @param gmtCreate value to be assigned to property gmtCreate
*/
public void setGmtCreate(Date gmtCreate) {
this.gmtCreate = gmtCreate;
}
/**
* Getter method for property <tt>createOperator</tt>.
*
* @return property value of createOperator
*/
public String getCreateOperator() {
return createOperator;
}
/**
* Setter method for property <tt>createOperator</tt>.
*
* @param createOperator value to be assigned to property createOperator
*/
public void setCreateOperator(String createOperator) {
this.createOperator = createOperator;
}
/**
* Getter method for property <tt>gmtModified</tt>.
*
* @return property value of gmtModified
*/
public Date getGmtModified() {
return gmtModified;
}
/**
* Setter method for property <tt>gmtModified</tt>.
*
* @param gmtModified value to be assigned to property gmtModified
*/
public void setGmtModified(Date gmtModified) {
this.gmtModified = gmtModified;
}
/**
* Getter method for property <tt>lastModifyOperator</tt>.
*
* @return property value of lastModifyOperator
*/
public String getLastModifyOperator() {
return lastModifyOperator;
}
/**
* Setter method for property <tt>lastModifyOperator</tt>.
*
* @param lastModifyOperator value to be assigned to property lastModifyOperator
*/
public void setLastModifyOperator(String lastModifyOperator) {
this.lastModifyOperator = lastModifyOperator;
}
}
package com.jz.dm.gateway.model;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* 请求上下文
*
*/
public class RequestContext extends ConcurrentHashMap<String, Object> {
private static final long serialVersionUID = -1993922957778726516L;
protected static Class<? extends RequestContext> CONTEXT_CLASS = RequestContext.class;
protected static final ThreadLocal<? extends RequestContext> THREAD_LOCAL = //
new ThreadLocal<RequestContext>() {
@Override
protected RequestContext initialValue() {
try {
return CONTEXT_CLASS.newInstance();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
};
public RequestContext() {
super();
}
/**
* Override the default RequestContext
*
* @param clazz
*/
public static void setContextClass(Class<? extends RequestContext> clazz) {
CONTEXT_CLASS = clazz;
}
/**
* Get the current RequestContext
*
* @return the current RequestContext
*/
public static RequestContext getCurrentContext() {
return THREAD_LOCAL.get();
}
/**
* puts the key, value into the map. a null value will remove the key from the map
*
* @param key
* @param value
*/
public void set(String key, Object value) {
if (value != null) {
put(key, value);
} else {
remove(key);
}
}
/**
* @return the HttpServletRequest from the "request" key
*/
public HttpServletRequest getRequest() {
return (HttpServletRequest) get("request");
}
/**
* sets the HttpServletRequest into the "request" key
*
* @param request
*/
public void setRequest(HttpServletRequest request) {
put("request", request);
}
/**
* @return the HttpServletResponse from the "response" key
*/
public HttpServletResponse getResponse() {
return (HttpServletResponse) get("response");
}
/**
* sets the "response" key to the HttpServletResponse passed in
*
* @param response
*/
public void setResponse(HttpServletResponse response) {
set("response", response);
}
/**
* get exclude filter
*
* @return
*/
@SuppressWarnings("unchecked")
public Set<String> getExcludeFilters() {
return (Set<String>) get("excludeFilters");
}
/**
* set exclude filter
*
* @param excludeFilters
*/
public void setExcludeFilters(Set<String> excludeFilters) {
set("excludeFilters", excludeFilters);
}
/**
* if filter in exclude filter set, return true
*
* @param filterName
* @return
*/
public boolean isExcludeFilter(String filterName) {
Set<String> excludeFilters = getExcludeFilters();
return excludeFilters != null && excludeFilters.contains(filterName);
}
/**
* reset the threadLocal context. Done at the end of the request.
*/
public void reset() {
THREAD_LOCAL.remove();
}
}
package com.jz.dm.gateway.model;
/**
* 路由类型
*/
public enum RouteType {
SRPING
}
package com.jz.dm.gateway.service;
/**
* @author ZC
* @PACKAGE_NAME: com.jz.gateway.service
* @PROJECT_NAME: jz-dm-parent
* @NAME: Test
* @USER: key
* @DATE: 2020-11-24/16:21
* @DAY_NAME_SHORT: 周二
* @Description:
**/
public class Test {
}
package com.jz.dm.gateway.service.trade;
import com.jz.dm.gateway.common.util.OpenApiRequest;
import com.jz.dm.gateway.common.util.OpenApiResponse;
import com.jz.dm.gateway.gateway.OpenApiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class TradeAddService implements OpenApiService {
@Override
public String getOpenApiMethod() {
return "bal.query";
}
@Override
public String getOpenApiVersion() {
return "1.0.0";
}
@Override
public void doService(OpenApiRequest request, OpenApiResponse response) {
System.out.println("~~~~~~~~~~~~请求到接口~~~~~~~~~~~~");
}
}
package com.jz.dm.gateway.signtype;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* MD5加密算法
*
* @author Admin
* @version $Id: Md5Utils.java 2014年9月3日 下午4:01:08 $
*/
public class Md5 {
private static Logger log = LoggerFactory.getLogger(Md5.class);
private static final String SIGN_TYPE = "MD5";
private static final String CHARSET_NAME = "UTF-8";
private static final String salt = "3zsAa6W9gfSMMhPSlQTdWFUSHY3LS8Vb";
/**
* MD5加密
*
* @param data
* @return
* @throws NoSuchAlgorithmException
*/
public static String encrypt(byte[] data) {
try {
MessageDigest md5 = MessageDigest.getInstance(SIGN_TYPE);
md5.update(data);
return byte2hex(md5.digest());
} catch (NoSuchAlgorithmException e) {
log.debug("md5 加密异常", e);
}
return "";
}
/**
* MD5加密
*
* @param str
* @return
* @throws NoSuchAlgorithmException
*/
public static String encrypt(String str) {
try {
MessageDigest md5 = MessageDigest.getInstance(SIGN_TYPE);
md5.update((str + salt).getBytes(CHARSET_NAME));
return byte2hex(md5.digest());
} catch (Exception e) {
log.debug("md5 加密异常", e);
}
return null;
}
/**
* MD5加盐加密
*
* @param str
* @param salt
* @return
* @throws NoSuchAlgorithmException
*/
public static String encrypt(String str, String salt) {
try {
MessageDigest md5 = MessageDigest.getInstance(SIGN_TYPE);
md5.update((str + salt).getBytes(CHARSET_NAME));
return byte2hex(md5.digest());
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("md5 加密异常", e);
}
}
return "";
}
public static String encrypt(String str, String salt, String charset) {
try {
MessageDigest md5 = MessageDigest.getInstance(SIGN_TYPE);
md5.update((str + salt).getBytes(charset));
return byte2hex(md5.digest());
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("md5 加密异常", e);
}
}
return "";
}
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();
}
public static byte[] hex2byte(String str) {
if (str == null) {
return null;
}
str = str.trim();
int len = str.length();
if (len <= 0 || len % 2 == 1) {
return null;
}
byte[] b = new byte[len / 2];
try {
for (int i = 0; i < str.length(); i += 2) {
b[(i / 2)] = (byte) Integer.decode("0x" + str.substring(i, i + 2)).intValue();
}
return b;
} catch (Exception e) {
}
return null;
}
/**
* 给TOP请求做MD5签名。
*
* @param sortedParams 所有字符型的TOP请求参数
* @param secret 签名密钥
* @return 签名
* @throws IOException
*/
public static String signRequestNew(Map<String, String> sortedParams, String secret) throws IOException {
// 第一步:把字典按Key的字母顺序排序
List<String> keys = new ArrayList<String>(sortedParams.keySet());
Collections.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = sortedParams.get(key);
if (!StringUtils.isEmpty(key) && !StringUtils.isEmpty(value) && !"sign".equals(key)) {
query.append(key).append("=").append(value);
}
}
log.info("获取当APP请求参数,签名前值为:" + query.toString());
return Md5.encrypt(query.toString(), secret);
}
public static void main(String[] args) {
System.out.println(encrypt("200128008012abc@123", ""));
}
}
package com.jz.dm.gateway.signtype;
import com.jz.dm.gateway.gateway.common.Constants;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class SHA1WithRSA {
public static final String SIGN_TYPE_RSA = "RSA";
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* RSA签名
*
* @param content 待签名数据
* @param privateKey 商户私钥
* @param input_charset 编码格式
* @return 签名值
*/
public static String sign(String content, String privateKey, String input_charset) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
KeyFactory keyf = KeyFactory.getInstance(SIGN_TYPE_RSA);
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update(content.getBytes(input_charset));
byte[] signed = signature.sign();
return Base64.encode(signed);
} catch (Exception e) {
}
return null;
}
/**
* RSA验签名检查
*
* @param content 待签名数据
* @param sign 签名值
* @param ali_public_key 支付宝公钥
* @param input_charset 编码格式
* @return 布尔值
*/
public static boolean verify(String content, String sign, String ali_public_key, String input_charset) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(SIGN_TYPE_RSA);
byte[] encodedKey = Base64.decode(ali_public_key);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
signature.initVerify(pubKey);
signature.update(content.getBytes(input_charset));
boolean bverify = signature.verify(Base64.decode(sign));
return bverify;
} catch (Exception e) {
}
return false;
}
public static String encrypt(String content, String publickey) {
try {
byte[] data = content.getBytes("UTF-8");
byte[] keys = Base64.decode(publickey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keys);
KeyFactory keyFactory = KeyFactory.getInstance(SIGN_TYPE_RSA);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0, i = 0;
byte[] cache;
// 对数据分段加密
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 = out.toByteArray();
out.close();
return Base64.encode(encryptedData);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static String decrypt(String content, String privatekey) {
try {
byte[] data = Base64.decode(content);
byte[] keyBytes = Base64.decode(privatekey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(SIGN_TYPE_RSA);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0, i = 0;
byte[] cache;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return new String(decryptedData, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static void main(String[] args) {
//String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANWCsjJK8va1KQpKqn+A2H98nlt2DJc1krohxOOlr2M6lAZeNacMhMvgAxH6Af+VZBFoOOBIUyaSBlWcXtxdpBKSAe5sLESyhLMK0jRDZJst13Tfimq65X0G2yEFQQAD3wLlrp+EGnJIXTZwLRRPKCfR34bOvvDuVi6GFD3rjFtXAgMBAAECgYAtaiNlNzP+7gHQwpkJjep/E47LfYyoDSkslko+8dsgjDE4OYnIAo2sn/WHOVp7dtdWLIkMi9XD+oOGakBzNyfSt+Xmzc4NBJoBGp1YRjJy8vwwgMD9QLCeXcTLaIMbfoDQ6D410rjPecqdfrfqf8+OEsR13XJ3W7qavvFejT8eAQJBAO/s5sqRg7W0ASTA8nQE18xO+kmJWNpZOAawh1bdh9b5ZIqjtXOk46XenxQBP00PgLlPbTHwj7YqozG8ixnsMZcCQQDj0LzuIbecFuOeQRkyRYSMX/CKqg8g3MvmB+gcKV1Con007y7NthYK/ILEdIhll/5k/F1zz4pQvgv/t5tWetxBAkEAxcQsFUvPGobO7oHRGIspanKrYtRBFnK2eOUoGhUvNKeMFa+OEU4YjBAuZmoEyLt/qsBqzOBzRYBt1sCIlIyZ7wJAHOL88d0IoRwt5IUworU552rK32pM3MfietqJzfhYwPhFlA64CpGKHf6CvlJgcTFiqn9tgh/Q1AglEVnAsqiFgQJAcspCepgN1Ef9We1lLccFdf+7uBp0iFTv232pPoLV4OPwaacgbtRi/rJYuRsAtQ66d2PMPp6VhROzLpVCwQhwpA==";
String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANWCsjJK8va1KQpKqn+A2H98nlt2DJc1krohxOOlr2M6lAZeNacMhMvgAxH6Af+VZBFoOOBIUyaSBlWcXtxdpBKSAe5sLESyhLMK0jRDZJst13Tfimq65X0G2yEFQQAD3wLlrp+EGnJIXTZwLRRPKCfR34bOvvDuVi6GFD3rjFtXAgMBAAECgYAtaiNlNzP+7gHQwpkJjep/E47LfYyoDSkslko+8dsgjDE4OYnIAo2sn/WHOVp7dtdWLIkMi9XD+oOGakBzNyfSt+Xmzc4NBJoBGp1YRjJy8vwwgMD9QLCeXcTLaIMbfoDQ6D410rjPecqdfrfqf8+OEsR13XJ3W7qavvFejT8eAQJBAO/s5sqRg7W0ASTA8nQE18xO+kmJWNpZOAawh1bdh9b5ZIqjtXOk46XenxQBP00PgLlPbTHwj7YqozG8ixnsMZcCQQDj0LzuIbecFuOeQRkyRYSMX/CKqg8g3MvmB+gcKV1Con007y7NthYK/ILEdIhll/5k/F1zz4pQvgv/t5tWetxBAkEAxcQsFUvPGobO7oHRGIspanKrYtRBFnK2eOUoGhUvNKeMFa+OEU4YjBAuZmoEyLt/qsBqzOBzRYBt1sCIlIyZ7wJAHOL88d0IoRwt5IUworU552rK32pM3MfietqJzfhYwPhFlA64CpGKHf6CvlJgcTFiqn9tgh/Q1AglEVnAsqiFgQJAcspCepgN1Ef9We1lLccFdf+7uBp0iFTv232pPoLV4OPwaacgbtRi/rJYuRsAtQ66d2PMPp6VhROzLpVCwQhwpA==";
String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVgrIySvL2tSkKSqp/gNh/fJ5bdgyXNZK6IcTjpa9jOpQGXjWnDITL4AMR+gH/lWQRaDjgSFMmkgZVnF7cXaQSkgHubCxEsoSzCtI0Q2SbLdd034pquuV9BtshBUEAA98C5a6fhBpySF02cC0UTygn0d+Gzr7w7lYuhhQ964xbVwIDAQAB";
String ali_pub_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB";
String content = "body=2015-01-11在天上人间消费&buyer_email=215262016@qq.com&buyer_id=2088902962305570&discount=0.00&gmt_create=2015-01-11 09:54:48&gmt_payment=2015-01-11 09:54:49&is_total_fee_adjust=N&notify_id=8261289e01d29d527d5de6802b90d99156&notify_time=2015-01-11 09:54:49&notify_type=trade_status_sync&out_trade_no=2015011100000002&payment_type=1&price=0.01&quantity=1&seller_email=ttl66868@163.com&seller_id=2088711660560521&subject=天上人间消费&total_fee=0.01&trade_no=2015011128211457&trade_status=TRADE_SUCCESS&use_coupon=N";
String sign = sign(content, privateKey, Constants.CHARSET_UTF8);
System.out.println(sign);
boolean b = verify(content, sign, pubKey, Constants.CHARSET_UTF8);
System.out.println(b);
sign = "C9guMhDh1MSmE2O7O04oaPbCkKWf0WsokBR97W1BQidL/mQaQpvyHFSGYe+jnWo8iOryZCOirWrSrdfbwWePkCj9PGyPD9GeW0gUoK6VOdDxekUXPQvRmV2KznOhDXIQF+aw+aiMiTKsGEskdLorn9LaEP13TTYQHaiXzSh+G50=";
boolean bl = verify(content, sign, ali_pub_key, Constants.CHARSET_UTF8);
System.out.println(bl);
}
/**
* 解密
*
* @param content 密文
* @param private_key 商户私钥
* @param input_charset 编码格式
* @return 解密后的字符串
*/
public static String decrypt(String content, String private_key, String input_charset) throws Exception {
PrivateKey prikey = getPrivateKey(private_key);
Cipher cipher = Cipher.getInstance(SIGN_TYPE_RSA);
cipher.init(Cipher.DECRYPT_MODE, prikey);
InputStream ins = new ByteArrayInputStream(Base64.decode(content));
ByteArrayOutputStream writer = new ByteArrayOutputStream();
// rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
byte[] buf = new byte[128];
int bufl;
while ((bufl = ins.read(buf)) != -1) {
byte[] block = null;
if (buf.length == bufl) {
block = buf;
} else {
block = new byte[bufl];
for (int i = 0; i < bufl; i++) {
block[i] = buf[i];
}
}
writer.write(cipher.doFinal(block));
}
return new String(writer.toByteArray(), input_charset);
}
/**
* 得到私钥
*
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = Base64.decode(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(SIGN_TYPE_RSA);
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
}
package com.jz.dm.gateway.signtype;
import com.jz.dm.gateway.common.util.Base64;
import com.jz.dm.gateway.common.util.StreamUtil;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class SHA256WithRSA {
public static final String SIGN_TYPE_RSA = "RSA";
public static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
/**
* RSA签名
*
* @param content 待签名数据
* @param privateKey 商户私钥
* @param input_charset 编码格式
* @return 签名值
*/
public static String sign(String content, String privateKey, String input_charset) {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, new ByteArrayInputStream(privateKey.getBytes()));
Signature signature = Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
signature.initSign(priKey);
signature.update(content.getBytes(input_charset));
return new String(Base64.encodeBase64(signature.sign()));
} catch (Exception e) {
}
return null;
}
/**
* RSA验签名检查
*
* @param content 待签名数据
* @param sign 签名值
* @param ali_public_key 支付宝公钥
* @param input_charset 编码格式
* @return 布尔值
*/
public static boolean verify(String content, String sign, String publicKey, String input_charset) {
try {
PublicKey pubKey = getPublicKeyFromX509(SIGN_TYPE_RSA, new ByteArrayInputStream(publicKey.getBytes()));
Signature signature = Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
signature.initVerify(pubKey);
signature.update(content.getBytes(input_charset));
return signature.verify(Base64.decodeBase64(sign.getBytes()));
} catch (Exception e) {
}
return false;
}
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 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));
}
private static java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
private static java.util.Base64.Encoder encoder = java.util.Base64.getEncoder();
public static Map<String, byte[]> generateKeyBytes() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(SIGN_TYPE_RSA);
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, byte[]> keyMap = new HashMap<String, byte[]>();
keyMap.put("PUBLIC_KEY", publicKey.getEncoded());
keyMap.put("PRIVATE_KEY", privateKey.getEncoded());
return keyMap;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws UnsupportedEncodingException {
Map<String, byte[]> a = generateKeyBytes();
String key = encoder.encodeToString(a.get("PRIVATE_KEY"));
String pkey = encoder.encodeToString(a.get("PUBLIC_KEY"));
String content = "abc";
String sign = SHA1WithRSA.sign(content, key, "utf-8");
System.out.println(SHA1WithRSA.verify(content, sign, pkey, "utf-8"));
}
}
package com.jz.dm.gateway.web.annotation;
import java.lang.annotation.*;
/**
* 参数名
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamName {
/**
* The name of the request parameter to bind to.
*/
String value();
}
package com.jz.dm.gateway.web.binder;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
import javax.servlet.ServletRequest;
import java.util.Map;
/**
* 参数名注解绑定
*
*/
public class ParamNameAnnotationBinder extends ExtendedServletRequestDataBinder {
private final Map<String, String> paramNamesMapping;
public ParamNameAnnotationBinder(Object target, String objectName,
Map<String, String> paramNamesMapping) {
super(target, objectName);
this.paramNamesMapping = paramNamesMapping;
}
@Override
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
super.addBindValues(mpvs, request);
for (Map.Entry<String, String> entry : paramNamesMapping.entrySet()) {
String from = entry.getKey();
String to = entry.getValue();
if (mpvs.contains(from)) {
mpvs.add(to, mpvs.getPropertyValue(from).getValue());
}
}
}
}
\ No newline at end of file
package com.jz.dm.gateway.web.binder;
import com.jz.dm.gateway.web.annotation.ParamName;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 参数名注解绑定
*
*/
public class ParamNameAnnotationResolver extends ServletModelAttributeMethodProcessor {
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
/**
* 参数名映射
*/
private final Map<Class<?>, Map<String, String>> classToParamNamesMapping = new ConcurrentHashMap<Class<?>, Map<String, String>>();
public ParamNameAnnotationResolver(boolean annotationNotRequired) {
super(annotationNotRequired);
}
@Override
protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest nativeWebRequest) {
Object target = binder.getTarget();
Class<?> targetClass = target.getClass();
if (!classToParamNamesMapping.containsKey(targetClass)) {
Map<String, String> paramNamesMapping = getParamNamesMapping(targetClass);
classToParamNamesMapping.put(targetClass, paramNamesMapping);
}
ParamNameAnnotationBinder paramNameDataBinder = new ParamNameAnnotationBinder(target,
binder.getObjectName(), classToParamNamesMapping.get(targetClass));
requestMappingHandlerAdapter.getWebBindingInitializer().initBinder(paramNameDataBinder,
nativeWebRequest);
super.bindRequestParameters(paramNameDataBinder, nativeWebRequest);
}
/**
* 获取注解参数名和字段名映射
*
* @param targetClass
* @return
*/
private static Map<String, String> getParamNamesMapping(Class<?> targetClass) {
Field[] fields = targetClass.getDeclaredFields();
Map<String, String> renameMap = new HashMap<String, String>();
for (Field field : fields) {
ParamName paramNameAnnotation = field.getAnnotation(ParamName.class);
if (paramNameAnnotation != null && !paramNameAnnotation.value().isEmpty()) {
renameMap.put(paramNameAnnotation.value(), field.getName());
}
}
if (renameMap.isEmpty())
return Collections.emptyMap();
return renameMap;
}
}
\ No newline at end of file
#开发环境配置
#spring:
# #缓存会话
# redis:
# host: 120.76.132.142
# password: redis@123
# port: 6379
# timeout: 10000
# lettuce:
# pool:
# max-active: 8
# max-wait: -1ms
# min-idle: 0
# max-idle: 8
#
#数据库
# datasource:
# url: jdbc:mysql://120.76.132.142:3306/fbpaydb?serverTimezone=GMT%2B8&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false
# username: root
# password: Hdd@pay.126
# type: com.zaxxer.hikari.HikariDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# hikari:
# minimum-idle: 20
# maximum-pool-size: 100
# auto-commit: true
# idle-timeout: 30000
# pool-name: MyHikariCP
# max-lifetime: 1800000
# connection-timeout: 30000
# connection-test-query: SELECT 1
# 跳过签名
api:
skipFilter: false #是否跳过拦截器
skipIpLimit: true #是否为ip列表
maxPostSize: 1048576 #最大支持上传文件数
supplierId: 200314008093 #供应商ID
# 代发三要素校验定时任务
validCron: 0/1 * * * * *
##测试环境配置
#spring:
#
# #缓存会话
# redis:
# host: r-wz9cnvxpbfm2ir35dh.redis.rds.aliyuncs.com
# password: hdd2020@888
# port: 6379
# timeout: 10000
# lettuce:
# pool:
# max-active: 100 #连接池最大连接数(使用负值表示没有限制)
# max-idle: 100 #连接池中的最大空闲连接
# min-idle: 50 #连接池中的最小空闲连接
# max-wait: 6000 #连接池最大阻塞等待时间(使用负值表示没有限制)
#
# #数据库
# datasource:
# url: jdbc:mysql://172.18.126.216:3306/btcpaydb?serverTimezone=GMT%2B8&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false
# username: root
# password: hdd2020@888
# type: com.zaxxer.hikari.HikariDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# hikari:
# minimum-idle: 20
# maximum-pool-size: 100
# auto-commit: true
# idle-timeout: 30000
# pool-name: MyHikariCP
# max-lifetime: 1800000
# connection-timeout: 30000
# connection-test-query: SELECT 1
# 系统信息 #服务端口和项目名称
info: server:
app: port: 8088
name: "@project.name@" servlet:
description: "@project.description@" context-path: /
version: "@project.version@"
spring-boot-version: "@project.parent.version@"
##Djasypt.encryptor.password
#jasypt:
# encryptor:
# password: btcpay.com
#日志打印
logging:
level:
com.netflix.discovery: 'OFF'
org.springframework.cloud: 'DEBUG'
#SPRING配置文件
spring: spring:
application:
name: 九章数据平台
aop:
proxy-target-class: true
profiles: profiles:
active: test active: dev #默认使用的配置文件
http:
encoding:
charset: UTF-8
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
default-property-inclusion: NON_NULL
#MyBatis
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
# typeAliasesPackage: com.btcpay.account.domain;com.btcpay.shopping.domain;com.btcpay.order.domain;com.btcpay.merchant.domain;com.btcpay.system.domain
# type-handlers-package: com.btcpay.commons.typehandler
global-config:
id-type: 1
field-strategy: 2
db-column-underline: true
refresh-mapper: true
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
sysProperties:
session-timeout: 3600
developerList:
- name: 九章
value:
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<substitutionProperty name="log.proj" value="gateway" />
<!-- 服务器 -->
<substitutionProperty name="log.base" value="/logs/${log.proj}" />
<!-- 本地 -->
<!-- <substitutionProperty name="log.base" value="/Users/luoyichang/Desktop/hdd/logs/${log.proj}" />-->
<substitutionProperty name="max.size" value="100MB" />
<jmxConfigurator />
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [${log.proj}:%thread] %-5level %logger{80} - %msg%n
</pattern>
</layout>
</appender>
<appender name="file.debug" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- All Log Info -->
<File>${log.base}/${log.proj}.log</File>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.proj}_%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</layout>
</appender>
<appender name="file.info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- <File>${log.base}/${log.proj}_info.log</File> -->
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.proj}_info_%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file.error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.proj}_error_%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file.warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.proj}_warn_%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 临界值过滤器,过滤掉低于指定临界值的日志 -->
<level>WARN</level>
</filter>
</appender>
<!--异步输出 -->
<appender name="async.file.info" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="file.info" />
</appender>
<appender name="async.file.debug" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="file.debug" />
</appender>
<appender name="async.file.warn" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="file.warn" />
</appender>
<appender name="async.file.error" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="file.error" />
</appender>
<root level="info" additivity="false">
<appender-ref ref="stdout" />
<!-- <appender-ref ref="async.file.debug" /> -->
<appender-ref ref="async.file.info" />
<appender-ref ref="async.file.error" />
<!-- <appender-ref ref="async.file.warn" /> -->
</root>
<logger name="io.lettuce.core.protocol.ConnectionWatchdog" additivity="false">
<appender-ref ref="stdout" />
<level value="ERROR" />
</logger>
<logger name="io.lettuce.core.protocol.ReconnectionHandler" additivity="false">
<appender-ref ref="stdout" />
<level value="ERROR" />
</logger>
</configuration>
\ No newline at end of file
package domian; /**
* Copyright (c) 2011-2018 All Rights Reserved.
*/
import com.alibaba.fastjson.JSON;
import com.jz.dm.gateway.common.util.TtpayUtils;
import com.jz.dm.gateway.common.util.WebUtils;
import com.jz.dm.gateway.signtype.Md5;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* @author Admin
* @version $Id: PushSdkTest.java 2018年4月12日 下午4:31:31 $
*/
public class PushSdkLocalhostTest1 {
private static String uri = "http://localhost:8088/gateway";
public static void main(String[] args) throws Exception {
// 余额查询接口
balQuery();
//委托订单查询
//orderQuery();
//取消订单
//cancelOrder();
//账户信息查询
//accQuery();
//代发订单详情
//orderDetail();
}
protected static void balQuery() {
try {
Map<String, String> data = new HashMap<>();
data.put("appId", "200316008117");
data.put("method", "bal.query");
data.put("charset", "UTF-8");
data.put("signType", "MD5");
data.put("timestamp", String.valueOf(System.currentTimeMillis()));
data.put("version", "1.0.0");
Map<String, String> params = new HashMap<>();
params.put("account_no", "5845342722900679704");
params.put("account_type", "WBANK");
data.put("params", JSON.toJSONString(params));
String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
data.put("sign", sign);
System.out.println(data);
String rsp = WebUtils.post(uri, data);
System.out.println(rsp);
} catch (Exception e) {
e.printStackTrace();
}
}
//protected static void orderQuery() {
// try {
// Map<String, String> data = new HashMap<>();
// data.put("app_id", "200314008093");
// data.put("method", "trade.query");
// data.put("charset", "UTF-8");
// data.put("sign_type", "MD5");
//
// data.put("timestamp", String.valueOf(System.currentTimeMillis()));
// data.put("version", "1.0.0");
//
// Map<String, String> params = new HashMap<>();
// //商户订单号
// params.put("out_trade_no", "YW202003040013");
// //银行卡号(非必填)
// //params.put("card_no", "6214806601002512988");
// data.put("params", JSON.toJSONString(params));
// String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
// String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
// data.put("sign", sign);
//
// String rsp = WebUtils.post(uri, data);
// System.out.println(rsp);
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
//
//protected static void cancelOrder() {
// try {
// Map<String, String> data = new HashMap<>();
// data.put("app_id", "200314008092");
// data.put("method", "trade.cancel");
// data.put("charset", "UTF-8");
// data.put("sign_type", "MD5");
//
// data.put("timestamp", String.valueOf(System.currentTimeMillis()));
// data.put("version", "1.0.0");
//
// Map<String, String> params = new HashMap<>();
// params.put("remark", "订单取消");
// //商户订单号
// params.put("out_trade_no", "2020031410810730003");
// data.put("params", JSON.toJSONString(params));
//
// String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
// String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
// data.put("sign", sign);
//
// String rsp = WebUtils.post(uri, data);
// System.out.println(rsp);
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
//protected static void accQuery() {
// try {
// Map<String, String> data = new HashMap<>();
// data.put("app_id", "200314008092");
// data.put("method", "acc.query");
// data.put("charset", "UTF-8");
// data.put("sign_type", "MD5");
//
// data.put("timestamp", String.valueOf(System.currentTimeMillis()));
// data.put("version", "1.0.0");
//
// Map<String, String> params = new HashMap<>();
// //params.put("remark", "订单取消");
// //商户订单号
// //params.put("out_trade_no", "2020031410810730003");
// data.put("params", JSON.toJSONString(params));
//
// String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
// String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
// data.put("sign", sign);
//
// String rsp = WebUtils.post(uri, data);
// System.out.println(rsp);
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
//protected static void orderDetail() {
// try {
// Map<String, String> data = new HashMap<>();
// data.put("app_id", "200314008093");
// data.put("method", "trade.detail");
// data.put("charset", "UTF-8");
// data.put("sign_type", "MD5");
//
// data.put("timestamp", String.valueOf(System.currentTimeMillis()));
// data.put("version", "1.0.0");
//
// Map<String, String> params = new HashMap<>();
// //商户订单号
// params.put("out_trade_no", "YW202003040012");
// data.put("params", JSON.toJSONString(params));
//
// String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
// String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
// data.put("sign", sign);
//
// String rsp = WebUtils.post(uri, data);
// System.out.println(rsp);
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment