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>
<parent>
<groupId>com.jz.dm</groupId>
......@@ -8,4 +9,68 @@
<artifactId>jz-dm-apigateway</artifactId>
<name>jz-dm-apigateway</name>
<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>
\ 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;