Commit 66f14f4f authored by zhangc's avatar zhangc

Merge branch 'master' into dm_dev

parents fd185271 b02e361c
<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>
<artifactId>jz-dm-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>jz-dm-apigateway</artifactId>
<name>jz-dm-apigateway</name>
<description>jz-dm-apigateway</description>
<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>
<artifactId>jz-dm-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<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.mall;
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.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.context.annotation.ComponentScan;
/**
* @author key
*/
@SpringBootApplication
@EnableRedisHttpSession
public class Application {
@ComponentScan(basePackages = {"com.jz.dm"})
@MapperScan("com.jz.dm.mapper")
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
SpringApplication.run(ApiGatewayApplication.class, args);
}
......
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);
}
}
package com.jz.dm.gateway.constant;
/**
* 常量
*
*/
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_KEY = "app_key";
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 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;
}
package com.jz.dm.gateway.constant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 日志常量
*
*/
public class LoggingConstants {
/** 业务摘要日志 */
public static final Logger DIGEST_LOGGER = LoggerFactory.getLogger("GATEWAY-DIGEST");
/** 报警日志,内容关键字用##号包括,便于报警信息归类 */
public static final Logger ALERT_LOGGER = LoggerFactory.getLogger("GATEWAY-ALERT");
/** 网关路由分发 */
public static final Logger DISPATCHER_LOGGER = LoggerFactory
.getLogger("GATEWAY-DISPATCHER");
public static final Logger REGISTRY_LOGGER = LoggerFactory.getLogger("GATEWAY-REGISTRY");
/** 分隔符*/
public static final String SEP = ",";
/** 点分割符*/
public static final String DOT_SEP = ".";
/** 默认值*/
public static final String DEFAULT_STR = "-";
/** 冒号 */
public static final String COLON = ":";
/** 金额币种分隔 */
public static final String AMOUNT_CURRENCY_SPLIT = "^";
/** 左中括号 */
public static final String LBRACKET = "[";
/** 右中括号 */
public static final String RBRACKET = "]";
/** "@" 符号*/
public static final String MONKEYS_AT = "@";
}
package com.jz.dm.gateway.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.jz.dm.gateway.common.util.JsonUtil;
import com.jz.dm.gateway.gateway.GatewayService;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.RequestContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* 网关请求
* @author key
*/
@RestController
public class GatewayController {
@Autowired
private GatewayService gatewayService;
@RequestMapping(value = "/gateway", consumes = "application/json")
public String gateway(@RequestBody String json, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
GatewayRequest gatewayRequest = JSON.parseObject(json, GatewayRequest.class);
return doGateway(gatewayRequest, httpServletRequest, httpServletResponse);
}
@RequestMapping(value = "/gateway")
public String gateway(GatewayRequest gatewayRequest, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
return doGateway(gatewayRequest, httpServletRequest, httpServletResponse);
}
private String doGateway(GatewayRequest gatewayRequest, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
try {
RequestContext requestContext = RequestContext.getCurrentContext();
requestContext.setRequest(httpServletRequest);
requestContext.setResponse(httpServletResponse);
GatewayResponse gatewayResponse = gatewayService.invoke(gatewayRequest);
JSONObject result = new JSONObject();
convertResponse(result, gatewayResponse);
return JsonUtil.toJSONString(result, PropertyNamingStrategy.SnakeCase);
} finally {
RequestContext.getCurrentContext().reset();
}
}
private void convertResponse(JSONObject result, GatewayResponse gatewayResponse) {
result.put("code", gatewayResponse.getCode());
result.put("msg", gatewayResponse.getMsg());
Map<String, Object> data = gatewayResponse.getResponse();
data.remove("code");
data.remove("msg");
if (!CollectionUtils.isEmpty(data)) {
result.put("data", data);
if (StringUtils.isNotBlank(gatewayResponse.getEncryptData())) {
result.put("data", gatewayResponse.getEncryptData());
}
}
result.put("sign", gatewayResponse.getSign());
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.RequestContext;
import org.springframework.core.Ordered;
/**
* 抽象过滤器
* @author key
*/
public abstract class AbstractFilter implements Filter, Ordered {
@Override
public void doFilter(GatewayRequest request, GatewayResponse response, FilterChain chain) {
RequestContext context = RequestContext.getCurrentContext();
if (context.isExcludeFilter(getFilterName())) {
chain.doFilter(request, response);
} else {
internalDoFilter(request, response, chain);
}
}
/**
* 执行过滤
*
* @param request
* @param response
* @param chain
*/
protected abstract void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain);
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.util.StringUtil;
import com.jz.dm.gateway.common.exception.GatewayException;
import com.jz.dm.gateway.common.util.SignType;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.enums.Format;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.enums.GatewayResultCode;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
/**
* 参数检查过滤器
*
* @author key
*/
@Component
public class CheckArgsFilter extends AbstractFilter {
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
// 校验参数非空
if (StringUtil.isEmpty(request.getAppKey()) || StringUtil.isEmpty(request.getMethod())
|| StringUtil.isEmpty(request.getCharset()) || StringUtil.isEmpty(request.getSignType())
|| StringUtil.isEmpty(request.getSign()) || StringUtil.isEmpty(request.getTimestamp())
|| StringUtil.isEmpty(request.getVersion())
|| StringUtil.isEmpty(request.getParams())) {
throw new GatewayException(GatewayResultCode.ILLEGAL_ARGUMENT);
}
// 设置默认值
if (StringUtil.isEmpty(request.getFormat())) {
request.setFormat(Format.JSON.name());
}
try {
Format.valueOf(request.getFormat());
Charset.forName(request.getCharset());
SignType.valueOf(request.getSignType());
} catch (Exception ex) {
throw new GatewayException(GatewayResultCode.ILLEGAL_ARGUMENT);
}
chain.doFilter(request, response);
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_2;
}
@Override
public String getFilterName() {
return "CheckArgsFilter";
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.exception.GatewayException;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.enums.GatewayResultCode;
import com.jz.dm.gateway.model.RequestContext;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 检查提交数据大小
*
*/
@Component("CheckPostSizeFilter")
public class CheckPostSizeFilter extends AbstractFilter {
@Override
public String getFilterName() {
return "CheckPostSizeFilter";
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_1;
}
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
HttpServletRequest httpServletRequest = RequestContext.getCurrentContext().getRequest();
Boolean postDataTooLarge = (Boolean) httpServletRequest.getAttribute("postDataTooLarge");
if (postDataTooLarge != null && postDataTooLarge) {
Integer maxPostSize = (Integer) httpServletRequest.getAttribute("maxPostSize");
Integer postSize = (Integer) httpServletRequest.getAttribute("postSize");
throw new GatewayException(GatewayResultCode.POST_DATA_TOO_LARGE,
"maxPostSize:" + maxPostSize + ", postSize:" + postSize);
}
chain.doFilter(request, response);
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.exception.GatewayException;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.enums.GatewayResultCode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 时间戳校验过滤器
*
* @author key
*/
@Component
public class CheckTimestampFilter extends AbstractFilter {
@Value("${api.skipFilter}")
private boolean skipFilter;
/**
* 时间戳超时分钟,10分钟
*/
private static final long max = 1000 * 60 * 10; //10分钟
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response, FilterChain chain) {
if (!skipFilter) {
String timestamp = request.getTimestamp();
long time = 0;
try {
time = Long.valueOf(timestamp);
} catch (Exception ex) {
throw new GatewayException(GatewayResultCode.ILLEGAL_ARGUMENT);
}
if (System.currentTimeMillis() - time > max) {//无效时间戳
throw new GatewayException(GatewayResultCode.ILLEGAL_TIMETEMP);
}
}
chain.doFilter(request, response);
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_5;
}
@Override
public String getFilterName() {
return "CheckTimestampFilter";
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
/**
* 过滤器
*
* @author key
*/
public interface Filter {
/**
* Returns the filter-name of this filter as defined in the deployment
* descriptor.
* @return
*/
public String getFilterName();
/**
* 执行过滤
*
* @param request gateway request
* @param response gateway response
* @param chain filter chain
*/
void doFilter(GatewayRequest request, GatewayResponse response, FilterChain chain);
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
/**
* 请求过滤链
* @author key
*/
public interface FilterChain {
/**
* 请求过滤
*
* @param request gateway request
* @param response gateway response
*/
void doFilter(GatewayRequest request, GatewayResponse response);
}
package com.jz.dm.gateway.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 过滤链工厂
*
*/
@Component
public class FilterChainFactory {
@Autowired
private FilterFactory filterFactory;
/**
* 获取过滤链
*
*/
public FilterChain getFilterChain() {
List<Filter> filters = filterFactory.getFilters();
return new FilterChainImpl(filters);
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.exception.OpenApiException;
import com.jz.dm.gateway.common.util.LogUtil;
import com.jz.dm.gateway.common.util.ResultCode;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.enums.GatewayResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* 过滤链
*
*/
public class FilterChainImpl implements FilterChain {
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
private int pos = 0;
private final List<Filter> filters = new ArrayList<Filter>();
public FilterChainImpl() { }
public FilterChainImpl(List<Filter> filters) {
addFilters(filters);
}
@Override
public void doFilter(GatewayRequest request, GatewayResponse response) {
Filter nextFilter = nextFilter();
if (nextFilter == null) {
return;
}
try {
nextFilter.doFilter(request, response, this);
} catch (OpenApiException ex) {
ResultCode resultCode = ex.getResultCode();
LogUtil.error(LOGGER, ex, "doFilter occur exception,code=" + resultCode.getCode()
+ ",msg=" + resultCode.getMsg() + ",request=" + request);
response.setCode(ex.getResultCode().getCode());
response.setMsg(ex.getResultCode().getMsg());
} catch (Throwable ex) {
LogUtil.error(LOGGER, ex, "doFilter occur unknown exception,request=" + request);
response.setCode(GatewayResultCode.UNKNOWN_EXCEPTION.getCode());
response.setMsg(GatewayResultCode.UNKNOWN_EXCEPTION.getMsg());
}
}
public Filter nextFilter() {
if (pos < filters.size()) {
return filters.get(pos++);
}
return null;
}
public void addFilters(List<Filter> filters) {
this.filters.addAll(filters);
}
public void addFilter(Filter filter) {
this.filters.add(filter);
}
public void addFilter(int index, Filter filter) {
this.filters.add(index, filter);
}
}
package com.jz.dm.gateway.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 过滤器工厂
*
*/
@Component
public class FilterFactory {
/**
* 过滤器列表
*/
@Autowired
private final List<Filter> filters = new ArrayList<Filter>();
/**
* 获取过滤器列表
*
* @return
*/
public List<Filter> getFilters() {
return filters;
}
}
package com.jz.dm.gateway.filter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jz.dm.gateway.common.exception.GatewayException;
import com.jz.dm.gateway.common.util.LogUtil;
import com.jz.dm.gateway.constant.LoggingConstants;
import com.jz.dm.gateway.gateway.DefaultOpenApiDispatcher;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.*;
import com.jz.dm.gateway.model.enums.GatewayResultCode;
import com.jz.dm.gateway.model.enums.RouteType;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 网关路由过滤器
*
*/
@Component
public class InvokeRouteFilter extends AbstractFilter {
/** openapi dispatcher logger */
private static final Logger DISPATCHER_LOGGER = LoggingConstants.DISPATCHER_LOGGER;
@Autowired
DefaultOpenApiDispatcher defaultOpenApiDispatcher;
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
String openApiResponse = null;
//当前系统时间戳
long startTime = System.currentTimeMillis();
try {
OpenApi openApi = (OpenApi) RequestContext.getCurrentContext().get("openApi");
if (openApi.getRouteType() == null) {
throw new GatewayException(GatewayResultCode.ILLEGAL_ROUTE_TYPE);
}
if (openApi.getRouteType() != RouteType.SRPING) {
chain.doFilter(request, response);
return;
}
DispatchContext context = new DispatchContext();
context.setAppId(request.getAppKey());
context.setApplication(openApi.getApplication());
context.setOpenApiMethod(request.getMethod());
context.setOpenApiParams(request.getParams());
context.setOpenApiVersion(request.getVersion());
for (GatewayRequest.Attribute attribute : request.getExtAttributes().values()) {
if (attribute != null && attribute.isPass) {
context.setExtAttribute(attribute.name, attribute.value);
}
}
openApiResponse = defaultOpenApiDispatcher.doDispatch(context);
JSONObject jsonObject = (JSONObject) JSON.parse(openApiResponse);
response.setAttribute(jsonObject);
} finally {
long elapseTime = System.currentTimeMillis() - startTime;
LogUtil.info(DISPATCHER_LOGGER,
"gateway do default dispatch,request=" + request + ",response=" + openApiResponse
+ "," + elapseTime + "ms");
}
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_6;
}
@Override
public String getFilterName() {
return "InvokeRouteFilter";
}
}
package com.jz.dm.gateway.filter;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.jz.dm.gateway.common.util.StringUtil;
import com.jz.dm.gateway.common.exception.SignatureException;
import com.jz.dm.gateway.common.util.*;
import com.jz.dm.gateway.gateway.common.Constants;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import com.jz.dm.gateway.model.enums.GatewayResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.Map;
/**
* 签名过滤器
*/
@Component
public class SignatureFilter extends AbstractFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(SignatureFilter.class);
// @Autowired
// private IApiWhiteService apiWhiteService;
@Value("${secret_private}")
private String secretPrivate;
private String encryptData;
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
try {
chain.doFilter(request, response);
} finally {
String responseJson = null;
String sign = StringUtil.EMPTY_STRING;
String privatekey = null;
if (StringUtil.isEmpty(request.getAppKey())) {
return;
}
//ApiWhite apiWhite = apiWhiteService.byMerchantId(request.getAppId());
//if (apiWhite == null) {
// return;
//}
//是否提供密码
//boolean providePublicKey = false;
//if ("0".equals(apiWhite.getProvideSecret())) {
// privatekey = apiWhite.getSecretKey();
//} else if ("1".equals(apiWhite.getProvideSecret())) {
// privatekey = secretPrivate;
// providePublicKey = true;
//}
try {
responseJson = JsonUtil.toJSONString(response.getResponse(),
PropertyNamingStrategy.SnakeCase);
if (StringUtil.isNotEmpty(request.getSignType())) {
String charset = request.getCharset();
if (StringUtil.isEmpty(charset)) {
charset = Constants.CHARSET_UTF8;
}
//if (providePublicKey) {
// sign = SignatureUtil.sign(convertResult(response.getResponse(), response, apiWhite), privatekey, charset, SignType.valueOf(request.getSignType()), SignatureUtil.SIGN_REQUEST, providePublicKey);
//} else {
// sign = SignatureUtil.sign(convertResult(response.getResponse(), response, apiWhite), privatekey, charset, SignType.valueOf(request.getSignType()), SignatureUtil.SIGN_REQUEST, providePublicKey);
//}
}
} catch (JSONException e) {
LogUtil.error(LOGGER, e,
"serializer response to json string error. response=" + response.getResponse());
response.clearAttributes();
response.setCode(OpenApiResultCode.RESPONSE_DATA_FORMAT_ERROR.getCode());
response.setMsg(OpenApiResultCode.RESPONSE_DATA_FORMAT_ERROR.getMsg());
// sign = signatureException(request, response, privatekey, providePublicKey);
} catch (SignatureException ex) {
LogUtil.error(LOGGER, ex,
"sign response error. response=" + response.getResponse());
response.clearAttributes();
response.setCode(ex.getResultCode().getCode());
response.setMsg(ex.getResultCode().getMsg());
} catch (Throwable ex) {
LogUtil.error(LOGGER, ex,
"signatureFilter doFilter error. response=" + response.getResponse());
response.clearAttributes();
response.setCode(GatewayResultCode.UNKNOWN_EXCEPTION.getCode());
response.setMsg(GatewayResultCode.UNKNOWN_EXCEPTION.getMsg());
// sign = signatureException(request, response, privatekey, providePublicKey);
}
response.setSign(sign);
//if (apiWhite.getIsEncrypt()) {
// response.setEncryptData(encryptData);
//}
}
}
private Map<String, Object> convertResult(Map<String, Object> attributes, GatewayResponse response) {
Map<String, Object> mapResult = new HashMap<>();
mapResult.put("code", response.getCode());
mapResult.put("msg", response.getMsg());
Object code = attributes.get("code");
Object msg = attributes.get("msg");
attributes.remove("code");
attributes.remove("msg");
if (!CollectionUtils.isEmpty(attributes)) {
mapResult.put("data", JsonUtil.toJSONString(attributes, PropertyNamingStrategy.SnakeCase));
//if (apiWhite.getIsEncrypt()) {
// String string = (String) mapResult.get("data");
// try {
// RSAPrivateKey privateKey = RSAUtils.getPrivateKey(secretPrivate);
// String encrypt = RSAUtils.privateEncrypt(string, privateKey);
// mapResult.put("data", encrypt);
// encryptData = encrypt;
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
}
attributes.put("code", code);
attributes.put("msg", msg);
return mapResult;
}
private String signatureException(GatewayRequest request, GatewayResponse response,
String privateKey, boolean providePublicKey) {
String responseJson = null;
String sign = StringUtil.EMPTY_STRING;
try {
responseJson = JsonUtil.toJSONString(response.getResponse(),
PropertyNamingStrategy.SnakeCase);
} catch (JSONException e1) {
LogUtil.error(LOGGER, e1,
"serializer response to json string error. response=" + response.getResponse());
return sign;
}
try {
sign = SignatureUtil.sign(responseJson, privateKey, request.getCharset(), SignType.valueOf(request.getSignType()), SignatureUtil.SIGN_REQUEST, providePublicKey);
} catch (SignatureException ex) {
LogUtil.error(LOGGER, ex, "sign response error. response=" + response.getResponse());
}
return sign;
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_0;
}
@Override
public String getFilterName() {
return "SignatureFilter";
}
}
package com.jz.dm.gateway.filter;
import com.jz.dm.gateway.common.util.HddHashMap;
import com.jz.dm.gateway.common.util.RSAUtils;
import com.jz.dm.gateway.constant.Constants;
import com.jz.dm.gateway.model.*;
import com.jz.dm.gateway.model.enums.RouteType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.security.interfaces.RSAPublicKey;
/**
* 验签过滤器
*/
@Slf4j
@Component
public class VerifySignFilter extends AbstractFilter {
//@Autowired
//private IApiWhiteService apiWhiteService;
@Value("${api.skipFilter}")
private boolean skipFilter;
private final static String CHARSET = "UTF-8";
@Override
protected void internalDoFilter(GatewayRequest request, GatewayResponse response,
FilterChain chain) {
HddHashMap params = new HddHashMap();
params.put("app_id", request.getAppKey());
params.put("method", request.getMethod());
params.put("charset", request.getCharset());
params.put("sign", request.getSign());
params.put("sign_type", request.getSignType());
params.put("timestamp", request.getTimestamp());
params.put("version", request.getVersion());
params.put("params", request.getParams());
//ApiWhite apiWhite = apiWhiteService.byMerchantId(request.getAppId());
//if (apiWhite != null) {
// String publicKey = apiWhite.getSecretKey();
//
// if (!skipFilter) {
// boolean verify = SignatureUtil.verify(params, publicKey, request.getCharset(), SignType.valueOf(request.getSignType()));
// if (!verify) {
// throw new SignatureException(OpenApiResultCode.SIGN_VERIFY_ERROR);
// }
//
// //参数解密
// if (apiWhite.getIsEncrypt()) {
// String decryptParams = decryptParams(request.getParams(), publicKey);
// request.setParams(decryptParams);
// }
// }
//}
// 后期再扩展
OpenApi openApi = new OpenApi();
openApi.setApplication("HDD_API_GATEWAY");
openApi.setRouteType(RouteType.SRPING);
RequestContext.getCurrentContext().set("openApi", openApi);
chain.doFilter(request, response);
}
private String decryptParams(String params, String publicKey) {
log.info("解密前请求参数,{}", params);
try {
RSAPublicKey key = RSAUtils.getPublicKey(publicKey);
String decrypt = RSAUtils.publicDecrypt(params, key);
log.info("解密后请求参数,{}", decrypt);
return decrypt;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
public int getOrder() {
return Constants.FILTER_ORDER_4;
}
@Override
public String getFilterName() {
return "VerifySignFilter";
}
}
package com.jz.dm.gateway.gateway;
import com.alibaba.fastjson.JSON;
import com.jz.dm.gateway.common.util.StringUtil;
import com.jz.dm.gateway.common.exception.OpenApiException;
import com.jz.dm.gateway.common.util.OpenApiRequest;
import com.jz.dm.gateway.common.util.OpenApiResponse;
import com.jz.dm.gateway.common.util.OpenApiResultCode;
import com.jz.dm.gateway.model.DispatchContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 默认openapi分发器
*
*/
@Component
public class DefaultOpenApiDispatcher implements OpenApiDispatcher {
private static final Logger LOGGER = LoggerFactory
.getLogger(DefaultOpenApiDispatcher.class);
/**
* openapi服务
*/
private final Map<String, OpenApiService> openApiServices = new ConcurrentHashMap<String, OpenApiService>();
/**
* 服务注入可参考: /openapi-demo/src/main/resources/META-INF/application-context.xml
* @param openApiServiceList
* <pre>
* &lt;!-- 定义开放接口服务 -->
* &lt;bean id="addUserOpenApiService" class="com.xxx.openapi.demo.openapi.AddUserOpenApiService" /&gt;
* &lt;bean id="getUserOpenApiService" class="com.xxx.openapi.demo.openapi.GetUserOpenApiService" /&gt;
* </pre>
*/
@Resource
public void setOpenApiServices(List<OpenApiService> openApiServiceList) {
for (OpenApiService openApiService : openApiServiceList) {
String openApiServiceKey = getOpenApiServiceKey(openApiService.getOpenApiMethod(),
openApiService.getOpenApiVersion());
openApiServices.put(openApiServiceKey, openApiService);
}
}
private String getOpenApiServiceKey(String openApiMethod, String openApiVersion) {
return openApiMethod + "&" + openApiVersion;
}
@Override
public String doDispatch(DispatchContext context) {
OpenApiResponse response = new OpenApiResponse();
String openApiServiceKey = getOpenApiServiceKey(context.getOpenApiMethod(),
context.getOpenApiVersion());
OpenApiService openApiService = openApiServices.get(openApiServiceKey);
if (openApiService == null) {
response.setCode(OpenApiResultCode.ILLEGAL_INTERFACE.getCode());
response.setMsg(OpenApiResultCode.ILLEGAL_INTERFACE.getMsg());
return JSON.toJSONString(response.getAttributes());
}
try {
OpenApiRequest request = new OpenApiRequest(context.getOpenApiParams());
request.setAppId(context.getAppId());
request.setExtAttributes(context.getExtAttributes());
openApiService.doService(request, response);
} catch (Throwable ex) {
if (ex instanceof OpenApiException) {
OpenApiException oae = (OpenApiException) ex;
response.setCode(oae.getResultCode().getCode());
response.setMsg(oae.getResultCode().getMsg());
} else {
LOGGER.error("OpenApiService doService error,DispatchContext=" + context, ex);
response.setCode(OpenApiResultCode.UNKNOWN_EXCEPTION.getCode());
response.setMsg(OpenApiResultCode.UNKNOWN_EXCEPTION.getMsg());
}
return JSON.toJSONString(response.getAttributes());
}
if (StringUtil.isEmpty(response.getCode())) {
response.setCode(OpenApiResultCode.SUCCESS.getCode());
response.setMsg(OpenApiResultCode.SUCCESS.getMsg());
}
return JSON.toJSONString(response.getAttributes());
}
}
package com.jz.dm.gateway.gateway;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
/**
* GatewayService
*/
public interface GatewayService {
GatewayResponse invoke(GatewayRequest gatewayRequest);
}
package com.jz.dm.gateway.gateway;
import com.jz.dm.gateway.model.DispatchContext;
/**
* openapi分发器
*
*/
public interface OpenApiDispatcher {
/**
* openapi dispatch
*
* @param context dispatch context
*
* @return
*/
public String doDispatch(DispatchContext context);
}
package com.jz.dm.gateway.gateway;
import com.jz.dm.gateway.common.util.OpenApiRequest;
import com.jz.dm.gateway.common.util.OpenApiResponse;
/**
* openapi服务
*
*/
public interface OpenApiService {
/**
* 获取openapi接口名
*
* @return
*/
public String getOpenApiMethod();
/**
* 获取openapi接口版本
*
* @return
*/
public String getOpenApiVersion();
/**
* openapi服务调用
*
* @param request
* @param response
*/
public void doService(OpenApiRequest request, OpenApiResponse response);
}
/**
* Copyright (c) 2011-2019 All Rights Reserved.
*/
package com.jz.dm.gateway.gateway.impl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* API白名单表 服务实现类
*
* @author zengxx
* @version $Id: ApiWhiteServiceImpl.java 2020-04-02 $
*/
//@Service("apiWhiteService")
//public class ApiWhiteServiceImpl implements IApiWhiteService {
//@Resource
//private ApiWhiteMapper apiWhiteMapper;
//@Resource
//private MeasureRecordMapper measureRecordMapper;
//
//@Override
//public ApiWhite byMerchantId(String merchantId) throws TtyException {
// return apiWhiteMapper.byMerchantId(merchantId);
//}
//
//@Override
//@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
//public long adjustAmt(String merchantId, long amt) {
// if (amt == 0) {
// return amt;
// }
// BigDecimal adjustAmt = new BigDecimal(amt).divide(new BigDecimal(100));
// ApiWhite apiWhite = apiWhiteMapper.byMerchantId(merchantId);
// long result = apiWhiteMapper.adjustAmt(merchantId, adjustAmt);
// if (result != 1) {
// return 0;
// } else {
// MeasureRecord measure = new MeasureRecord();
// //已用金额
// BigDecimal sumUseAmt = apiWhiteMapper.sumUseAmt(merchantId);
// if (sumUseAmt == null) {
// sumUseAmt = BigDecimal.ZERO;
// }
// if (amt > 0) {
// measure.setChangType("0");
// measure.setUseAmount(sumUseAmt.subtract(adjustAmt));
// } else {
// measure.setChangType("1");
// measure.setUseAmount(sumUseAmt.add(adjustAmt.abs()));
// }
// measure.setChangeAmount(adjustAmt.abs());
// measure.setAfterAmount(apiWhite.getUsableAmount().add(adjustAmt));
//
// measure.setMerchantId(apiWhite.getMerchantId());
// measure.setName(apiWhite.getName());
// measure.setBeforeAmount(apiWhite.getUsableAmount());
// measure.setChangDate(LocalDateTime.now());
// measure.setCreateUser("API");
// measure.setCreateDate(LocalDateTime.now());
// //插入流水信息
// if (measureRecordMapper.insert(measure) > 0) {
// return 1;
// }
// }
// return 0;
//}
//@Override
//@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
//public void invoke3bcCount(String merchantId) {
// apiWhiteMapper.invoke3bcCount(merchantId);
//}
//}
package com.jz.dm.gateway.gateway.impl;
import com.jz.dm.gateway.filter.FilterChain;
import com.jz.dm.gateway.filter.FilterChainFactory;
import com.jz.dm.gateway.gateway.GatewayService;
import com.jz.dm.gateway.model.GatewayRequest;
import com.jz.dm.gateway.model.GatewayResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 网关服务
*
*/
@Service
public class GatewayServiceImpl implements GatewayService {
@Autowired
private FilterChainFactory filterChainFactory;
@Override
public GatewayResponse invoke(GatewayRequest gatewayRequest) {
GatewayResponse gatewayResponse = new GatewayResponse();
FilterChain filterChain = filterChainFactory.getFilterChain();
filterChain.doFilter(gatewayRequest, gatewayResponse);
return gatewayResponse;
}
}
package com.jz.dm.gateway.model;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* Dispatch Context
*/
public class DispatchContext implements Serializable {
/**
* 序列号
*/
private static final long serialVersionUID = -3448256355423553719L;
/**
* 商户应用id
*/
private String appId;
/**
* 应用
*/
private String application;
/**
* openapi接口
*/
private String openApiMethod;
/**
* openapi接口参数,json格式
*/
private String openApiParams;
/**
* openapi接口版本
*/
private String openApiVersion;
/**
* 扩展属性
*/
private final Map<String, Object> extAttributes = new HashMap<String, Object>();
/**
* Getter method for property <tt>appId</tt>.
*
* @return property value of appId
*/
public String getAppId() {
return appId;
}
/**
* Setter method for property <tt>appId</tt>.
*
* @param appId value to be assigned to property appId
*/
public void setAppId(String appId) {
this.appId = appId;
}
/**
* Getter method for property <tt>application</tt>.
*
* @return property value of application
*/
public String getApplication() {
return application;
}
/**
* Setter method for property <tt>application</tt>.
*
* @param application value to be assigned to property application
*/
public void setApplication(String application) {
this.application = application;
}
/**
* Getter method for property <tt>openApiMethod</tt>.
*
* @return property value of openApiMethod
*/
public String getOpenApiMethod() {
return openApiMethod;
}
/**
* Setter method for property <tt>openApiMethod</tt>.
*
* @param openApiMethod value to be assigned to property openApiMethod
*/
public void setOpenApiMethod(String openApiMethod) {
this.openApiMethod = openApiMethod;
}
/**
* Getter method for property <tt>openApiParams</tt>.
*
* @return property value of openApiParams
*/
public String getOpenApiParams() {
return openApiParams;
}
/**
* Setter method for property <tt>openApiParams</tt>.
*
* @param openApiParams value to be assigned to property openApiParams
*/
public void setOpenApiParams(String openApiParams) {
this.openApiParams = openApiParams;
}
/**
* Getter method for property <tt>openApiVersion</tt>.
*
* @return property value of openApiVersion
*/
public String getOpenApiVersion() {
return openApiVersion;
}
/**
* Setter method for property <tt>openApiVersion</tt>.
*
* @param openApiVersion value to be assigned to property openApiVersion
*/
public void setOpenApiVersion(String openApiVersion) {
this.openApiVersion = openApiVersion;
}
/**
* 获取扩展属性
*
* @param attributeName
* @return
*/
@SuppressWarnings("unchecked")
public <T> T getExtAttribute(String attributeName) {
return (T) extAttributes.get(attributeName);
}
/**
* 设置属性
*
* @param attributeName
* @param attributeValue
*/
public void setExtAttribute(String attributeName, Object attributeValue) {
extAttributes.put(attributeName, attributeValue);
}
/**
* Getter method for property <tt>extAttributes</tt>.
*
* @return property value of extAttributes
*/
public Map<String, Object> getExtAttributes() {
return extAttributes;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "DispatchContext [application=" + application + ", openApiMethod=" + openApiMethod
+ ", openApiParams=" + openApiParams + ", openApiVersion=" + openApiVersion + "]";
}
}
package com.jz.dm.gateway.model;
import com.jz.dm.gateway.web.annotation.ParamName;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* api请求
*
* @author key
*/
public class GatewayRequest implements Serializable {
/**
* 分配的ID
*/
@ParamName("app_key")
private String appKey;
/**
* 接口名称
*/
private String method;
/**
* 格式,目前仅支持JSON
*/
private String format;
/**
* 请求使用的编码格式,如UTF-8,GBK,GB2312等
*/
private String charset;
/**
* 生成签名字符串所使用的签名算法类型
*/
@ParamName("sign_type")
private String signType;
/**
* 请求参数的签名串
*/
private String sign;
/**
* 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss"
*/
private String timestamp;
/**
* 调用的接口版本,固定为:1.0
*/
private String version;
///**
// * 回调通知地址
// */
//@ParamName("notify_url")
//private String notifyUrl;
///**
// * 返回地址
// */
//@ParamName("return_url")
//private String returnUrl;
/**
* 请求参数,JSON格式
*/
private String params;
/**
* 扩展属性
*/
private final Map<String, Attribute> extAttributes = new HashMap<String, Attribute>();
/**
* Getter method for property <tt>appId</tt>.
*
* @return property value of appId
*/
public String getAppKey() {
return appKey;
}
/**
* Setter method for property <tt>appId</tt>.
*
* @param appKey value to be assigned to property appId
*/
public void setAppKey(String appKey) {
this.appKey = appKey;
}
/**
* Getter method for property <tt>method</tt>.
*
* @return property value of method
*/
public String getMethod() {
return method;
}
/**
* Setter method for property <tt>method</tt>.
*
* @param method value to be assigned to property method
*/
public void setMethod(String method) {
this.method = method;
}
/**
* Getter method for property <tt>format</tt>.
*
* @return property value of format
*/
public String getFormat() {
return format;
}
/**
* Setter method for property <tt>format</tt>.
*
* @param format value to be assigned to property format
*/
public void setFormat(String format) {
this.format = format;
}
/**
* Getter method for property <tt>charset</tt>.
*
* @return property value of charset
*/
public String getCharset() {
return charset;
}
/**
* Setter method for property <tt>charset</tt>.
*
* @param charset value to be assigned to property charset
*/
public void setCharset(String charset) {
this.charset = charset;
}
/**
* Getter method for property <tt>signType</tt>.
*
* @return property value of signType
*/
public String getSignType() {
return signType;
}
/**
* Setter method for property <tt>signType</tt>.
*
* @param signType value to be assigned to property signType
*/
public void setSignType(String signType) {
this.signType = signType;
}
/**
* Getter method for property <tt>sign</tt>.
*
* @return property value of sign
*/
public String getSign() {
return sign;
}
/**
* Setter method for property <tt>sign</tt>.
*
* @param sign value to be assigned to property sign
*/
public void setSign(String sign) {
this.sign = sign;
}
/**
* Getter method for property <tt>timestamp</tt>.
*
* @return property value of timestamp
*/
public String getTimestamp() {
return timestamp;
}
/**
* Setter method for property <tt>timestamp</tt>.
*
* @param timestamp value to be assigned to property timestamp
*/
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
/**
* Getter method for property <tt>version</tt>.
*
* @return property value of version
*/
public String getVersion() {
return version;
}
/**
* Setter method for property <tt>version</tt>.
*
* @param version value to be assigned to property version
*/
public void setVersion(String version) {
this.version = version;
}
/**
* Getter method for property <tt>notifyUrl</tt>.
*
* @return property value of notifyUrl
*/
// public String getNotifyUrl() {
// return notifyUrl;
//}
/**
* Setter method for property <tt>notifyUrl</tt>.
*
* @param notifyUrl value to be assigned to property notifyUrl
*/
//public void setNotifyUrl(String notifyUrl) {
// this.notifyUrl = notifyUrl;
//}
/**
* Getter method for property <tt>returnUrl</tt>.
*
* @return property value of returnUrl
*/
//public String getReturnUrl() {
// return returnUrl;
//}
/**
* Setter method for property <tt>returnUrl</tt>.
*
* @param returnUrl value to be assigned to property returnUrl
*/
// public void setReturnUrl(String returnUrl) {
// this.returnUrl = returnUrl;
// }
/**
* Getter method for property <tt>params</tt>.
*
* @return property value of params
*/
public String getParams() {
return params;
}
/**
* Setter method for property <tt>params</tt>.
*
* @param params value to be assigned to property params
*/
public void setParams(String params) {
this.params = params;
}
/**
* 获取扩展属性
*
* @param attributeName
* @return
*/
public Attribute getExtAttribute(String attributeName) {
return extAttributes.get(attributeName);
}
/**
* 设置属性
*
* @param attribute
*/
public void setExtAttribute(Attribute attribute) {
if (attribute == null) {
return;
}
extAttributes.put(attribute.name, attribute);
}
/**
* Getter method for property <tt>extAttributes</tt>.
*
* @return property value of extAttributes
*/
public Map<String, Attribute> getExtAttributes() {
return extAttributes;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "GatewayRequest [appId=" + appKey + ", method=" + method + ", format=" + format
+ ", charset=" + charset + ", signType=" + signType + ", sign=" + sign
+ ", timestamp=" + timestamp + ", version=" + version
+ ", params=" + params + ", extAttributes="
+ extAttributes + "]";
}
public static class Attribute {
/**
*  熟悉名称
*/
public String name;
/**
* 属性值
*/
public Object value;
/**
* 是否传递到业务系统
*/
public boolean isPass;
public Attribute(String name, Object value) {
this(name, value, false);
}
public Attribute(String name, Object value, boolean isPass) {
this.name = name;
this.value = value;
this.isPass = isPass;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "Attribute [name=" + name + ", value=" + value + ", isPass=" + isPass + "]";
}
}
}
package com.jz.dm.gateway.model;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.HashMap;
import java.util.Map;
/**
* api响应
*
* @author key
*/
@JSONType(orders = { "response", "sign" })
public class GatewayResponse {
/**
* 结果码
*/
private static final String ATTRIBUTE_NAME_CODE = "code";
/**
* 结果消息
*/
private static final String ATTRIBUTE_NAME_MSG = "msg";
/**
* 数据签名
*/
private String sign;
/**
* 属性信息
*/
private final Map<String, Object> attributes = new HashMap<String, Object>();
/**
* 加密后参数密文
*/
@JsonIgnore
private String encryptData;
public String getEncryptData() {
return encryptData;
}
public void setEncryptData(String encryptData) {
this.encryptData = encryptData;
}
/**
* 默认构造函数
*/
public GatewayResponse() {
}
/**
* 构造函数,初始化属性信息
*
* @param attributes
*/
public GatewayResponse(Map<String, Object> attributes) {
this.attributes.putAll(attributes);
}
@JSONField(serialize = false)
public String getCode() {
return (String) attributes.get(ATTRIBUTE_NAME_CODE);
}
public void setCode(String code) {
attributes.put(ATTRIBUTE_NAME_CODE, code);
}
@JSONField(serialize = false)
public String getMsg() {
return (String) attributes.get(ATTRIBUTE_NAME_MSG);
}
public void setMsg(String msg) {
attributes.put(ATTRIBUTE_NAME_MSG, msg);
}
@SuppressWarnings("unchecked")
public <T> T getAttribute(String attributeName) {
return (T) attributes.get(attributeName);
}
public void setAttribute(String attributeName, Object attributeValue) {
attributes.put(attributeName, attributeValue);
}
public void setAttribute(Map<String, Object> attributes) {
this.attributes.putAll(attributes);
}
public void clearAttributes() {
attributes.clear();
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public Map<String, Object> getResponse() {
return attributes;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "GatewayResponse [sign=" + sign + ", attributes=" + attributes + "]";
}
}
package com.jz.dm.gateway.model;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* 请求上下文
*
*/
public class RequestContext extends ConcurrentHashMap<String, Object> {
private static final long serialVersionUID = -1993922957778726516L;
protected static Class<? extends RequestContext> CONTEXT_CLASS = RequestContext.class;
protected static final ThreadLocal<? extends RequestContext> THREAD_LOCAL = //
new ThreadLocal<RequestContext>() {
@Override
protected RequestContext initialValue() {
try {
return CONTEXT_CLASS.newInstance();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
};
public RequestContext() {
super();
}
/**
* Override the default RequestContext
*
* @param clazz
*/
public static void setContextClass(Class<? extends RequestContext> clazz) {
CONTEXT_CLASS = clazz;
}
/**
* Get the current RequestContext
*
* @return the current RequestContext
*/
public static RequestContext getCurrentContext() {
return THREAD_LOCAL.get();
}
/**
* puts the key, value into the map. a null value will remove the key from the map
*
* @param key
* @param value
*/
public void set(String key, Object value) {
if (value != null) {
put(key, value);
} else {
remove(key);
}
}
/**
* @return the HttpServletRequest from the "request" key
*/
public HttpServletRequest getRequest() {
return (HttpServletRequest) get("request");
}
/**
* sets the HttpServletRequest into the "request" key
*
* @param request
*/
public void setRequest(HttpServletRequest request) {
put("request", request);
}
/**
* @return the HttpServletResponse from the "response" key
*/
public HttpServletResponse getResponse() {
return (HttpServletResponse) get("response");
}
/**
* sets the "response" key to the HttpServletResponse passed in
*
* @param response
*/
public void setResponse(HttpServletResponse response) {
set("response", response);
}
/**
* get exclude filter
*
* @return
*/
@SuppressWarnings("unchecked")
public Set<String> getExcludeFilters() {
return (Set<String>) get("excludeFilters");
}
/**
* set exclude filter
*
* @param excludeFilters
*/
public void setExcludeFilters(Set<String> excludeFilters) {
set("excludeFilters", excludeFilters);
}
/**
* if filter in exclude filter set, return true
*
* @param filterName
* @return
*/
public boolean isExcludeFilter(String filterName) {
Set<String> excludeFilters = getExcludeFilters();
return excludeFilters != null && excludeFilters.contains(filterName);
}
/**
* reset the threadLocal context. Done at the end of the request.
*/
public void reset() {
THREAD_LOCAL.remove();
}
}
package com.jz.dm.gateway.model.enums;
/**
* 数据格式
*
*/
public enum Format {
JSON, XML
}
package com.jz.dm.gateway.model.enums;
import com.jz.dm.gateway.common.util.ResultCode;
import java.util.HashMap;
import java.util.Map;
/**
* 网关结果码
*
*/
public enum GatewayResultCode implements ResultCode {
/** 处理成功 */
SUCCESS("SUCCESS", "处理成功"),
/** 处理成功 */
FAIL("FAIL", "处理失败"),
/** 未知异常 */
UNKNOWN_EXCEPTION("UNKNOWN_EXCEPTION", "未知异常"),
/** 无效接口 */
ILLEGAL_INTERFACE("ILLEGAL_INTERFACE", "无效接口"),
/** 无效参数 */
ILLEGAL_ARGUMENT("ILLEGAL_ARGUMENT", "无效参数"),
/** 无效请求 */
ILLEGAL_REQUEST("ILLEGAL_REQUEST", "无效请求"),
/** 无效请求 */
ILLEGAL_TIMETEMP("ILLEGAL_TIMETEMP", "无效时间戳"),
/** 接口未授权 */
INTERFACE_NO_AUTHORITY("INTERFACE_NO_AUTHORITY", "接口未授权"),
/** 请求超过限制 */
RATE_LIMIT_EXCEEDED("RATE_LIMIT_EXCEEDED", "请求超过限制"),
/** 无效路由类型 */
ILLEGAL_ROUTE_TYPE("ILLEGAL_ROUTE_TYPE", "无效路由类型"),
/** ip不允许访问 */
IP_NOT_ALLOW_ACCESS("IP_NOT_ALLOW_ACCESS", "ip不允许访问"),
/** ip不允许访问 */
IP_NOT_CONFIG("IP_NOT_CONFIG", "未配置白名单"),
/** 提交数据过大 */
POST_DATA_TOO_LARGE("POST_DATA_TOO_LARGE", "提交数据过大"),
/** 调用转发异常 */
DISPATCHER_EXCEPTION("DISPATCHER_EXCEPTION", "调用转发异常"),
/*账户不存在*/
ACCOUNT_EXIST("ACCOUNT_EXIST","账户信息不存在");
;
/**
* 初始化保存到map里方便根据code获取
*/
private static Map<String, GatewayResultCode> RESULT_CODES = new HashMap<String, GatewayResultCode>();
static {
for (GatewayResultCode gatewayResultCode : GatewayResultCode.values()) {
RESULT_CODES.put(gatewayResultCode.code, gatewayResultCode);
}
}
/** 结果码 */
private String code;
/** 结果码信息 */
private String msg;
/**
* 构造函数
*
* @param code 结果码
* @param msg 结果码信息
*/
private GatewayResultCode(String code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 通过枚举<code>code</code>获得枚举
*
* @param code 结果码
* @return 枚举
*/
public static GatewayResultCode getGatewayResultCode(String code) {
return RESULT_CODES.get(code);
}
/**
* Getter method for property <tt>code</tt>.
*
* @return property value of code
*/
@Override
public String getCode() {
return code;
}
/**
* Setter method for property <tt>code</tt>.
*
* @param code value to be assigned to property code
*/
public void setCode(String code) {
this.code = code;
}
/**
* Getter method for property <tt>msg</tt>.
*
* @return property value of msg
*/
@Override
public String getMsg() {
return msg;
}
/**
* Setter method for property <tt>msg</tt>.
*
* @param msg value to be assigned to property msg
*/
public void setMsg(String msg) {
this.msg = msg;
}
}
package com.jz.dm.gateway.model.enums;
/**
* 路由类型
*/
public enum RouteType {
SRPING
}
package com.jz.dm.gateway.model.signtype;
import com.jz.dm.gateway.common.util.Base64;
import com.jz.dm.gateway.common.util.StreamUtil;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class SHA256WithRSA {
public static final String SIGN_TYPE_RSA = "RSA";
public static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
/**
* RSA签名
*
* @param content 待签名数据
* @param privateKey 商户私钥
* @param input_charset 编码格式
* @return 签名值
*/
public static String sign(String content, String privateKey, String input_charset) {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, new ByteArrayInputStream(privateKey.getBytes()));
Signature signature = Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
signature.initSign(priKey);
signature.update(content.getBytes(input_charset));
return new String(Base64.encodeBase64(signature.sign()));
} catch (Exception e) {
}
return null;
}
/**
* RSA验签名检查
*
* @param content 待签名数据
* @param sign 签名值
* @param ali_public_key 支付宝公钥
* @param input_charset 编码格式
* @return 布尔值
*/
public static boolean verify(String content, String sign, String publicKey, String input_charset) {
try {
PublicKey pubKey = getPublicKeyFromX509(SIGN_TYPE_RSA, new ByteArrayInputStream(publicKey.getBytes()));
Signature signature = Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
signature.initVerify(pubKey);
signature.update(content.getBytes(input_charset));
return signature.verify(Base64.decodeBase64(sign.getBytes()));
} catch (Exception e) {
}
return false;
}
public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception {
if (ins == null || StringUtils.isEmpty(algorithm)) {
return null;
}
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
byte[] encodedKey = StreamUtil.readText(ins).getBytes();
encodedKey = Base64.decodeBase64(encodedKey);
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
}
public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
StringWriter writer = new StringWriter();
StreamUtil.io(new InputStreamReader(ins), writer);
byte[] encodedKey = writer.toString().getBytes();
encodedKey = Base64.decodeBase64(encodedKey);
return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
}
private static java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
private static java.util.Base64.Encoder encoder = java.util.Base64.getEncoder();
public static Map<String, byte[]> generateKeyBytes() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(SIGN_TYPE_RSA);
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, byte[]> keyMap = new HashMap<String, byte[]>();
keyMap.put("PUBLIC_KEY", publicKey.getEncoded());
keyMap.put("PRIVATE_KEY", privateKey.getEncoded());
return keyMap;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws UnsupportedEncodingException {
Map<String, byte[]> a = generateKeyBytes();
String key = encoder.encodeToString(a.get("PRIVATE_KEY"));
String pkey = encoder.encodeToString(a.get("PUBLIC_KEY"));
String content = "abc";
String sign = SHA1WithRSA.sign(content, key, "utf-8");
System.out.println(SHA1WithRSA.verify(content, sign, pkey, "utf-8"));
}
}
package com.jz.dm.gateway.service;
/**
* @author ZC
* @PACKAGE_NAME: com.jz.gateway.service
* @PROJECT_NAME: jz-dm-parent
* @NAME: Test
* @USER: key
* @DATE: 2020-11-24/16:21
* @DAY_NAME_SHORT: 周二
* @Description:
**/
public class Test {
}
package com.jz.dm.gateway.service.trade;
import com.jz.dm.gateway.common.util.OpenApiRequest;
import com.jz.dm.gateway.common.util.OpenApiResponse;
import com.jz.dm.gateway.gateway.OpenApiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class TradeAddService implements OpenApiService {
@Override
public String getOpenApiMethod() {
return "bal.query";
}
@Override
public String getOpenApiVersion() {
return "1.0.0";
}
@Override
public void doService(OpenApiRequest request, OpenApiResponse response) {
System.out.println("~~~~~~~~~~~~请求到接口~~~~~~~~~~~~");
}
}
package com.jz.dm.gateway.web.annotation;
import java.lang.annotation.*;
/**
* 参数名
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamName {
/**
* The name of the request parameter to bind to.
*/
String value();
}
package com.jz.dm.gateway.web.binder;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
import javax.servlet.ServletRequest;
import java.util.Map;
/**
* 参数名注解绑定
*
*/
public class ParamNameAnnotationBinder extends ExtendedServletRequestDataBinder {
private final Map<String, String> paramNamesMapping;
public ParamNameAnnotationBinder(Object target, String objectName,
Map<String, String> paramNamesMapping) {
super(target, objectName);
this.paramNamesMapping = paramNamesMapping;
}
@Override
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
super.addBindValues(mpvs, request);
for (Map.Entry<String, String> entry : paramNamesMapping.entrySet()) {
String from = entry.getKey();
String to = entry.getValue();
if (mpvs.contains(from)) {
mpvs.add(to, mpvs.getPropertyValue(from).getValue());
}
}
}
}
\ No newline at end of file
package com.jz.dm.gateway.web.binder;
import com.jz.dm.gateway.web.annotation.ParamName;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 参数名注解绑定
*
*/
public class ParamNameAnnotationResolver extends ServletModelAttributeMethodProcessor {
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
/**
* 参数名映射
*/
private final Map<Class<?>, Map<String, String>> classToParamNamesMapping = new ConcurrentHashMap<Class<?>, Map<String, String>>();
public ParamNameAnnotationResolver(boolean annotationNotRequired) {
super(annotationNotRequired);
}
@Override
protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest nativeWebRequest) {
Object target = binder.getTarget();
Class<?> targetClass = target.getClass();
if (!classToParamNamesMapping.containsKey(targetClass)) {
Map<String, String> paramNamesMapping = getParamNamesMapping(targetClass);
classToParamNamesMapping.put(targetClass, paramNamesMapping);
}
ParamNameAnnotationBinder paramNameDataBinder = new ParamNameAnnotationBinder(target,
binder.getObjectName(), classToParamNamesMapping.get(targetClass));
requestMappingHandlerAdapter.getWebBindingInitializer().initBinder(paramNameDataBinder,
nativeWebRequest);
super.bindRequestParameters(paramNameDataBinder, nativeWebRequest);
}
/**
* 获取注解参数名和字段名映射
*
* @param targetClass
* @return
*/
private static Map<String, String> getParamNamesMapping(Class<?> targetClass) {
Field[] fields = targetClass.getDeclaredFields();
Map<String, String> renameMap = new HashMap<String, String>();
for (Field field : fields) {
ParamName paramNameAnnotation = field.getAnnotation(ParamName.class);
if (paramNameAnnotation != null && !paramNameAnnotation.value().isEmpty()) {
renameMap.put(paramNameAnnotation.value(), field.getName());
}
}
if (renameMap.isEmpty())
return Collections.emptyMap();
return renameMap;
}
}
\ No newline at end of file
#开发环境配置
#spring:
# #缓存会话
# redis:
# host: 120.76.132.142
# password: redis@123
# port: 6379
# timeout: 10000
# lettuce:
# pool:
# max-active: 8
# max-wait: -1ms
# min-idle: 0
# max-idle: 8
#
数据库
datasource:
url: jdbc:mysql://rm-wz9n399q2avsy3k6m4o.mysql.rds.aliyuncs.com/wj-mkt-project?serverTimezone=GMT%2B8&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false
username: root
password: I%ou$buy!ok
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 20
maximum-pool-size: 100
auto-commit: true
idle-timeout: 30000
pool-name: MyHikariCP
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
# 跳过签名
api:
skipFilter: false #是否跳过拦截器
skipIpLimit: true #是否为ip列表
maxPostSize: 1048576 #最大支持上传文件数
supplierId: 200314008093 #供应商ID
# 代发三要素校验定时任务
validCron: 0/1 * * * * *
##测试环境配置
#spring:
#
# #缓存会话
# redis:
# host: r-wz9cnvxpbfm2ir35dh.redis.rds.aliyuncs.com
# password: hdd2020@888
# port: 6379
# timeout: 10000
# lettuce:
# pool:
# max-active: 100 #连接池最大连接数(使用负值表示没有限制)
# max-idle: 100 #连接池中的最大空闲连接
# min-idle: 50 #连接池中的最小空闲连接
# max-wait: 6000 #连接池最大阻塞等待时间(使用负值表示没有限制)
#
# #数据库
# datasource:
# url: jdbc:mysql://172.18.126.216:3306/btcpaydb?serverTimezone=GMT%2B8&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false
# username: root
# password: hdd2020@888
# type: com.zaxxer.hikari.HikariDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# hikari:
# minimum-idle: 20
# maximum-pool-size: 100
# auto-commit: true
# idle-timeout: 30000
# pool-name: MyHikariCP
# max-lifetime: 1800000
# connection-timeout: 30000
# connection-test-query: SELECT 1
# 系统信息
info:
app:
name: "@project.name@"
description: "@project.description@"
version: "@project.version@"
spring-boot-version: "@project.parent.version@"
#服务端口和项目名称
server:
port: 8088
servlet:
context-path: /
##Djasypt.encryptor.password
#jasypt:
# encryptor:
# password: btcpay.com
#日志打印
logging:
level:
com.netflix.discovery: 'OFF'
org.springframework.cloud: 'DEBUG'
#SPRING配置文件
spring:
application:
name: 九章数据平台
aop:
proxy-target-class: true
profiles:
active: test
active: dev #默认使用的配置文件
sysProperties:
session-timeout: 3600
developerList:
- name: 九章
value:
http:
encoding:
charset: UTF-8
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
default-property-inclusion: NON_NULL
#MyBatis
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
# typeAliasesPackage: com.btcpay.account.domain;com.btcpay.shopping.domain;com.btcpay.order.domain;com.btcpay.merchant.domain;com.btcpay.system.domain
# type-handlers-package: com.btcpay.commons.typehandler
global-config:
id-type: 1
field-strategy: 2
db-column-underline: true
refresh-mapper: true
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<substitutionProperty name="log.proj" value="gateway" />
<!-- 服务器 -->
<substitutionProperty name="log.base" value="/logs/${log.proj}" />
<!-- 本地 -->
<!-- <substitutionProperty name="log.base" value="/Users/luoyichang/Desktop/hdd/logs/${log.proj}" />-->
<substitutionProperty name="max.size" value="100MB" />
<jmxConfigurator />
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [${log.proj}:%thread] %-5level %logger{80} - %msg%n
</pattern>
</layout>
</appender>
<appender name="file.debug" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- All Log Info -->
<File>${log.base}/${log.proj}.log</File>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.proj}_%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</layout>
</appender>
<appender name="file.info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- <File>${log.base}/${log.proj}_info.log</File> -->
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.proj}_info_%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file.error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.proj}_error_%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file.warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.proj}_warn_%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 临界值过滤器,过滤掉低于指定临界值的日志 -->
<level>WARN</level>
</filter>
</appender>
<!--异步输出 -->
<appender name="async.file.info" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="file.info" />
</appender>
<appender name="async.file.debug" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="file.debug" />
</appender>
<appender name="async.file.warn" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="file.warn" />
</appender>
<appender name="async.file.error" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="file.error" />
</appender>
<root level="info" additivity="false">
<appender-ref ref="stdout" />
<!-- <appender-ref ref="async.file.debug" /> -->
<appender-ref ref="async.file.info" />
<appender-ref ref="async.file.error" />
<!-- <appender-ref ref="async.file.warn" /> -->
</root>
<logger name="io.lettuce.core.protocol.ConnectionWatchdog" additivity="false">
<appender-ref ref="stdout" />
<level value="ERROR" />
</logger>
<logger name="io.lettuce.core.protocol.ReconnectionHandler" additivity="false">
<appender-ref ref="stdout" />
<level value="ERROR" />
</logger>
</configuration>
\ No newline at end of file
package domian; /**
* Copyright (c) 2011-2018 All Rights Reserved.
*/
import com.alibaba.fastjson.JSON;
import com.jz.dm.gateway.common.util.TtpayUtils;
import com.jz.dm.gateway.common.util.WebUtils;
import com.jz.dm.gateway.model.signtype.Md5;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* @author Admin
* @version $Id: PushSdkTest.java 2018年4月12日 下午4:31:31 $
*/
public class PushSdkLocalhostTest1 {
private static String uri = "http://localhost:8088/gateway";
public static void main(String[] args) throws Exception {
// 余额查询接口
balQuery();
//委托订单查询
//orderQuery();
//取消订单
//cancelOrder();
//账户信息查询
//accQuery();
//代发订单详情
//orderDetail();
}
protected static void balQuery() {
try {
Map<String, String> data = new HashMap<>();
data.put("appId", "200316008117");
data.put("method", "bal.query");
data.put("charset", "UTF-8");
data.put("signType", "MD5");
data.put("timestamp", String.valueOf(System.currentTimeMillis()));
data.put("version", "1.0.0");
Map<String, String> params = new HashMap<>();
params.put("account_no", "5845342722900679704");
params.put("account_type", "WBANK");
data.put("params", JSON.toJSONString(params));
String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
data.put("sign", sign);
System.out.println(data);
String rsp = WebUtils.post(uri, data);
System.out.println(rsp);
} catch (Exception e) {
e.printStackTrace();
}
}
//protected static void orderQuery() {
// try {
// Map<String, String> data = new HashMap<>();
// data.put("app_id", "200314008093");
// data.put("method", "trade.query");
// data.put("charset", "UTF-8");
// data.put("sign_type", "MD5");
//
// data.put("timestamp", String.valueOf(System.currentTimeMillis()));
// data.put("version", "1.0.0");
//
// Map<String, String> params = new HashMap<>();
// //商户订单号
// params.put("out_trade_no", "YW202003040013");
// //银行卡号(非必填)
// //params.put("card_no", "6214806601002512988");
// data.put("params", JSON.toJSONString(params));
// String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
// String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
// data.put("sign", sign);
//
// String rsp = WebUtils.post(uri, data);
// System.out.println(rsp);
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
//
//protected static void cancelOrder() {
// try {
// Map<String, String> data = new HashMap<>();
// data.put("app_id", "200314008092");
// data.put("method", "trade.cancel");
// data.put("charset", "UTF-8");
// data.put("sign_type", "MD5");
//
// data.put("timestamp", String.valueOf(System.currentTimeMillis()));
// data.put("version", "1.0.0");
//
// Map<String, String> params = new HashMap<>();
// params.put("remark", "订单取消");
// //商户订单号
// params.put("out_trade_no", "2020031410810730003");
// data.put("params", JSON.toJSONString(params));
//
// String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
// String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
// data.put("sign", sign);
//
// String rsp = WebUtils.post(uri, data);
// System.out.println(rsp);
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
//protected static void accQuery() {
// try {
// Map<String, String> data = new HashMap<>();
// data.put("app_id", "200314008092");
// data.put("method", "acc.query");
// data.put("charset", "UTF-8");
// data.put("sign_type", "MD5");
//
// data.put("timestamp", String.valueOf(System.currentTimeMillis()));
// data.put("version", "1.0.0");
//
// Map<String, String> params = new HashMap<>();
// //params.put("remark", "订单取消");
// //商户订单号
// //params.put("out_trade_no", "2020031410810730003");
// data.put("params", JSON.toJSONString(params));
//
// String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
// String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
// data.put("sign", sign);
//
// String rsp = WebUtils.post(uri, data);
// System.out.println(rsp);
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
//protected static void orderDetail() {
// try {
// Map<String, String> data = new HashMap<>();
// data.put("app_id", "200314008093");
// data.put("method", "trade.detail");
// data.put("charset", "UTF-8");
// data.put("sign_type", "MD5");
//
// data.put("timestamp", String.valueOf(System.currentTimeMillis()));
// data.put("version", "1.0.0");
//
// Map<String, String> params = new HashMap<>();
// //商户订单号
// params.put("out_trade_no", "YW202003040012");
// data.put("params", JSON.toJSONString(params));
//
// String dataStr = TtpayUtils.createLinkString(TtpayUtils.filter(data));
// String sign = Md5.encrypt(dataStr, "fP6R7cSvQj8JwThFvP1RrOomkHXydHx3", "UTF-8");
// data.put("sign", sign);
//
// String rsp = WebUtils.post(uri, data);
// System.out.println(rsp);
// } catch (Exception e) {
// e.printStackTrace();
// }
//}
}
package com.jz.dm.gateway.model.signtype;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* MD5加密算法
*
* @author Admin
* @version $Id: Md5Utils.java 2014年9月3日 下午4:01:08 $
*/
public class Md5 {
private static Logger log = LoggerFactory.getLogger(Md5.class);
private static final String SIGN_TYPE = "MD5";
private static final String CHARSET_NAME = "UTF-8";
private static final String salt = "3zsAa6W9gfSMMhPSlQTdWFUSHY3LS8Vb";
/**
* MD5加密
*
* @param data
* @return
* @throws NoSuchAlgorithmException
*/
public static String encrypt(byte[] data) {
try {
MessageDigest md5 = MessageDigest.getInstance(SIGN_TYPE);
md5.update(data);
return byte2hex(md5.digest());
} catch (NoSuchAlgorithmException e) {
log.debug("md5 加密异常", e);
}
return "";
}
/**
* MD5加密
*
* @param str
* @return
* @throws NoSuchAlgorithmException
*/
public static String encrypt(String str) {
try {
MessageDigest md5 = MessageDigest.getInstance(SIGN_TYPE);
md5.update((str + salt).getBytes(CHARSET_NAME));
return byte2hex(md5.digest());
} catch (Exception e) {
log.debug("md5 加密异常", e);
}
return null;
}
/**
* MD5加盐加密
*
* @param str
* @param salt
* @return
* @throws NoSuchAlgorithmException
*/
public static String encrypt(String str, String salt) {
try {
MessageDigest md5 = MessageDigest.getInstance(SIGN_TYPE);
md5.update((str + salt).getBytes(CHARSET_NAME));
return byte2hex(md5.digest());
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("md5 加密异常", e);
}
}
return "";
}
public static String encrypt(String str, String salt, String charset) {
try {
MessageDigest md5 = MessageDigest.getInstance(SIGN_TYPE);
md5.update((str + salt).getBytes(charset));
return byte2hex(md5.digest());
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("md5 加密异常", e);
}
}
return "";
}
public static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
public static byte[] hex2byte(String str) {
if (str == null) {
return null;
}
str = str.trim();
int len = str.length();
if (len <= 0 || len % 2 == 1) {
return null;
}
byte[] b = new byte[len / 2];
try {
for (int i = 0; i < str.length(); i += 2) {
b[(i / 2)] = (byte) Integer.decode("0x" + str.substring(i, i + 2)).intValue();
}
return b;
} catch (Exception e) {
}
return null;
}
/**
* 给TOP请求做MD5签名。
*
* @param sortedParams 所有字符型的TOP请求参数
* @param secret 签名密钥
* @return 签名
* @throws IOException
*/
public static String signRequestNew(Map<String, String> sortedParams, String secret) throws IOException {
// 第一步:把字典按Key的字母顺序排序
List<String> keys = new ArrayList<String>(sortedParams.keySet());
Collections.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = sortedParams.get(key);
if (!StringUtils.isEmpty(key) && !StringUtils.isEmpty(value) && !"sign".equals(key)) {
query.append(key).append("=").append(value);
}
}
log.info("获取当APP请求参数,签名前值为:" + query.toString());
return Md5.encrypt(query.toString(), secret);
}
public static void main(String[] args) {
System.out.println(encrypt("200128008012abc@123", ""));
}
}
package com.jz.dm.mall.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.sql.SQLException;
/**
* @ProjectName zhaxinle
* @Author: zeroJun
* @Date: 2018/8/16 16:49
* @Description: 主数据源配置类
*/
@Configuration
// 前缀为primary.datasource.druid的配置信息
@ConfigurationProperties(prefix = "spring.datasource")
@MapperScan(basePackages = DatabaseConfig.PACKAGE, sqlSessionFactoryRef = "sqlSessionFactory")
public class DatabaseConfig {
/**
* dao层的包路径
*/
static final String PACKAGE = "com.jz.dm.mall.moduls.mapper";
/**
* mapper文件的相对路径
*/
private static final String MAPPER_LOCATION = "classpath:mapperconf/*.xml";
private String filters;
private String url;
private String username;
private String password;
private String driverClassName;
private int initialSize;
private int minIdle;
private int maxActive;
private long maxWait;
private long timeBetweenEvictionRunsMillis;
private long minEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
// 主数据源使用@Primary注解进行标识
//@Primary
@Bean(name = "dataSource")
public DataSource dataSource() throws SQLException {
DruidDataSource druid = new DruidDataSource();
// 监控统计拦截的filters
druid.setFilters(filters);
// 配置基本属性
druid.setDriverClassName(driverClassName);
druid.setUsername(username);
druid.setPassword(password);
druid.setUrl(url);
//初始化时建立物理连接的个数
druid.setInitialSize(initialSize);
//最大连接池数量
druid.setMaxActive(maxActive);
//最小连接池数量
druid.setMinIdle(minIdle);
//获取连接时最大等待时间,单位毫秒。
druid.setMaxWait(maxWait);
//间隔多久进行一次检测,检测需要关闭的空闲连接
druid.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
//一个连接在池中最小生存的时间
druid.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
//用来检测连接是否有效的sql
druid.setValidationQuery(validationQuery);
//建议配置为true,不影响性能,并且保证安全性。
druid.setTestWhileIdle(testWhileIdle);
//申请连接时执行validationQuery检测连接是否有效
druid.setTestOnBorrow(testOnBorrow);
druid.setTestOnReturn(testOnReturn);
//是否缓存preparedStatement,也就是PSCache,oracle设为true,mysql设为false。分库分表较多推荐设置为false
druid.setPoolPreparedStatements(poolPreparedStatements);
// 打开PSCache时,指定每个连接上PSCache的大小
druid.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
return druid;
}
// 创建该数据源的事务管理
@Primary
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager() throws SQLException {
return new DataSourceTransactionManager(dataSource());
}
// 创建Mybatis的连接会话工厂实例
@Primary
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource); // 设置数据源bean
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(DatabaseConfig.MAPPER_LOCATION)); // 设置mapper文件路径
return sessionFactory.getObject();
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public long getMaxWait() {
return maxWait;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxPoolPreparedStatementPerConnectionSize() {
return maxPoolPreparedStatementPerConnectionSize;
}
public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
}
\ No newline at end of file
package com.jz.dm.mall.moduls.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.jz.dm.mall.moduls.service.TestService;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestService testService;
@RequestMapping("/hello")
public String test() throws Exception {
return testService.test();
}
}
package com.jz.dm.mall.moduls.mapper;
import java.util.Map;
public interface TestMapper {
/**
* @Title: getTest
* @Description: TODO(测试mapper接口)
* @param @return 参数
* @return Map<String,String> 返回类型
* @throws
*/
public Map<String, String> getTest();
}
package com.jz.dm.mall.moduls.service;
public interface TestService {
/**
* @Title: test
* @Description: TODO(测试方法)
* @param @return
* @param @throws Exception 参数
* @return String 返回类型
* @throws
*/
public String test()throws Exception;
}
package com.jz.dm.mall.moduls.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jz.dm.mall.moduls.mapper.TestMapper;
import com.jz.dm.mall.moduls.service.TestService;
@Service("testService")
public class TestServiceImpl implements TestService {
@Autowired
private TestMapper testMapper;
private Logger log = LoggerFactory.getLogger(TestServiceImpl.class);
@Override
public String test() throws Exception {
// TODO Auto-generated method stub
log.info("test");
return testMapper.getTest().toString();
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.jz.dm.mall.moduls.mapper.TestMapper" >
<mapper namespace="com.jz.dm.gateway.moduls.mapper.TestMapper" >
<select id="getTest" resultType="map">
select * from dm_test;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment