bytes){
int len = 0;
for(byte[] b : bytes){
len = len + b.length;
}
byte[] newData = new byte[len];
int tempLen = 0;
for(byte[] b : bytes){
System.arraycopy(b,0,newData,tempLen,b.length);
tempLen = tempLen+b.length;
}
return newData;
}
private static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex);
}
return sign.toString();
}
private static byte[] encodeSHA256(byte[] data) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
return md.digest(data);
}
```
- 加密/解密
加密算法:Base64(DES(value,secretKey))
解密算法:DES(Base64(value),secretKey)
#### 参考实现:
```java
public static final String decryptDes(String cryptData, String key) {
String decryptedData = null;
try {
// 把字符串解码为字节数组,并解密
decryptedData = new String(decrypt(decryptBASE64(cryptData), key.getBytes()));
} catch (Exception e) {
throw new RuntimeException("解密错误,错误信息:", e);
}
return decryptedData;
}
public static final String encryptDes(String data, String key) {
String encryptedData = null;
try {
// 加密,并把字节数组编码成字符串
encryptedData = encryptBASE64(encrypt(data.getBytes(), key.getBytes("UTF-8")));
} catch (Exception e) {
throw new RuntimeException("加密错误,错误信息:", e);
}
return encryptedData;
}
private static byte[] decrypt(byte[] data, byte[] key) throws InvalidKeyException, NoSuchAlgorithmException,
InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
// 还原密钥
Key k = toKey(key);
// 实例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
public static byte[] encrypt(byte[] data, byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
// 还原密钥
Key k = toKey(key);
// 实例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
private static final byte[] decryptBASE64(String key) {
try {
return decode(key);
} catch (Exception e) {
throw new RuntimeException("解密错误,错误信息:", e);
}
}
private byte[] decode(String str) throws IOException {
byte[] arrayOfByte = str.getBytes();
ByteArrayInputStream inputStream = new ByteArrayInputStream(arrayOfByte);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
decodeBuffer(inputStream, outputStream);
return outputStream.toByteArray();
}
```
- 定义接口服务
XService约定一个接口服务为一个Controller类,且此类必须继承框架提供的三个基类之一。
带参数的接口服务基类:AbstractParamController
```java
/**
* 业务参数控制器基类
* 说明:
* 定义有业务参数的接口处理基本流程
* @author DuanYong
* @param 参数
* @since 2017年6月28日下午2:48:27
*/
@Slf4j
public abstract class AbstractParamController
extends BaseController {
/**
* 接口处理
*
说明:
* 1:请求参数解析
* 2:检查请求参数
* 3:业务处理
* 4:设置响应数据
* @author DuanYong
* @since 2017年6月28日下午3:19:43
* @param response 响应对象
*/
@RequestMapping
public final void handle(HttpServletResponse response) {
final Long startTime = System.currentTimeMillis();
//参数解析->检查请求参数->业务处理->设置响应数据
parse().map(r->validateFunction.apply(r)).map(r->Optional.ofNullable(execute(r))).map(o->setSuccessResponse(response,o.orElse(Optional.empty())));
log.info("接口->{},处理完成,耗时->{}秒,流水号:{}", SwapAreaUtils.getSwapAreaData().getReqMethod(),(System.currentTimeMillis() - startTime)/1000.0,SwapAreaUtils.getSwapAreaData().getTransactionSn());
}
/**
* 执行
* 说明:
* hystrix
* @author DuanYong
* @since 2017年11月13日下午3:41:04
* @param p 业务参数
* @return: java.lang.Object 业务返回对象
*/
private final Object execute(P p){
return executeFunction.apply(p);
}
/**
* 解析请求参数
* 说明:
* 将请求参数中的业务参数对象转换为服务使用的对象
* @author DuanYong
* @since 2017年6月28日下午3:17:32
* @return: java.util.Optional 业务参数对象
*/
protected final Optional
parse(){
BaseRequest baseRequest = SwapAreaUtils.getSwapAreaData().getBaseRequest();
baseRequest.getParameter().orElseThrow(()->new IllegalParameterException(Resources.getMessage(ErrorCodeConstants.COMMON_REQ_PARAM_PARSE_IS_EMPTY)));
try{
return baseRequest.getParameter().map(o->o.toString()).map(s->initBaseParameter(s,baseRequest));
}catch(Exception ex){
ex.printStackTrace();
log.error("将请求参数中的业务参数对象转换为服务使用的对象失败,流水号:{},请求参数:{},异常信息:", WebUtil.getSwapAreaData().getTransactionSn(),baseRequest.getParameter(),ex);
throw new IllegalParameterException(Resources.getMessage(ErrorCodeConstants.COMMON_REQ_PARAM_PARSE_ERROR));
}
}
/**
* 初始化初始请求参数
*
说明:
* 解析并初始化请求参数对象
* @author DuanYong
* @param paramString 参数原始json字符串
* @param baseRequest 请求参数对象
* @return P 业务参数对象
* @since 2017年11月14日上午11:07:19
*/
private P initBaseParameter(String paramString, BaseRequest baseRequest){
P p = FastJsonUtil.toBean(paramString,getParamClass());
p.setTransactionSn(baseRequest.getTransactionSn());
p.setQueryStringMap(baseRequest.getQueryStringMap());
return p;
}
/**
* 校验请求中的业务参数
* 说明:
* 由子类实现,如果参数检查不通过,请抛出参数异常:IllegalParameterException
* @author DuanYong
* @param p 业务参数对象
* @throws IllegalParameterException
* @since 2017年6月28日下午2:28:10
*/
protected abstract void validate(P p) throws IllegalParameterException;
/**
* 具体业务处理
* 说明:
* 由子类实现
* @author DuanYong
* @param p 业务参数对象
* @return 业务返回数据
* @since 2017年5月5日下午3:24:09
*/
protected abstract Object process(P p);
/**
* 获取参数类型
* 说明:
*
* @author DuanYong
* @return 参数类型对象
* @since 2017年7月24日上午10:33:30
*/
protected abstract Class getParamClass();
/**
* 服务降级,默认返回REQUEST_TIMEOUT字符串,框架统一处理抛出TimeoutException异常
*
说明:
* 注意:在fallback方法中不允许有远程方法调用,方法尽量要轻,调用其他外部接口也要进行hystrix降级。否则执行fallback方法会抛出异常
* @author DuanYong
* @param p 参数
* @return REQUEST_TIMEOUT
* @since 2018年8月21日上午11:20:37
*/
protected Object fallback(P p){
return Constants.REQUEST_TIMEOUT;
}
/**
* 校验并返回业务参数
*/
private Function validateFunction = (P p)->{
validate(p);
return p;
};
/**
* 执行业务处理
*/
private Function
executeFunction = (P p)-> process(p);
/**
* 执行降级业务处理
*/
private Function
fallbackFunction = (P p)-> fallback(p);
}
```
无参数的接口服务基类:AbstractNonParamController
```java
/**
* 无业务参数控制器基类
*
说明:
* 定义无业务参数接口处理基本流程
* 统一异常处理
* @author DuanYong
* @since 2017年7月11日上午8:49:58
*/
@Slf4j
public abstract class AbstractNonParamController extends BaseController {
/**
* 具体业务处理
* 说明:
* 由子类实现
* @author DuanYong
* @return 业务返回数据
* @since 2017年7月11日上午8:51:23
*/
protected abstract Object process();
/**
* 接口处理
* 说明:
* 业务处理
* 设置响应数据
* @since 2017年7月11日上午9:13:28
*/
@RequestMapping
private final void handle(HttpServletResponse httpServletResponse) {
Long startTime = System.currentTimeMillis();
//业务处理->设置响应数据
Optional.ofNullable(execute()).map(o->setSuccessResponse(httpServletResponse,o));
log.info("接口->{},处理完成,耗时->{}秒,流水号:{}", SwapAreaUtils.getSwapAreaData().getReqMethod(),(System.currentTimeMillis() - startTime)/1000.0,SwapAreaUtils.getSwapAreaData().getTransactionSn());
}
/**
* 执行
* 说明:
* @author DuanYong
* @return: java.lang.Object 业务返回数据
* @since 2017年11月13日下午3:41:04
*/
private final Object execute(){
return executeFunction.get();
}
/**
* 执行业务处理
*/
private Supplier