Commit 5dddac74 authored by 黎博's avatar 黎博

first commit

parents
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
### local log ###
*.log
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.qg</groupId>
<artifactId>holmes</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>holmes</name>
<description>QG QA project</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--common-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!--集成redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>spring-boot-starter-sentry</artifactId>
<version>1.0.9</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.35</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package cn.qg.holmes;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(value = "cn.qg.holmes.mapper")
public class HolmesApplication {
public static void main(String[] args) {
SpringApplication.run(HolmesApplication.class, args);
}
}
package cn.qg.holmes.aspect;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.io.IOUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
/**
* 日志切面
*/
@Aspect
@Component
public class HttpLogAspect {
private static final Logger logger = LoggerFactory.getLogger(HttpLogAspect.class);
@Pointcut("execution(public * cn.qg.holmes.controller..*.*(..))")
public void httpRequestLog() {}
/**
* 前置通知:在连接点之前执行的通知
*
* @param joinPoint
* @throws Throwable
*/
@Before("httpRequestLog()")
public void doBefore(JoinPoint joinPoint) throws JsonProcessingException {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
logger.info("请求发起ip地址: {}, 请求url: {}, 请求参数:{}", request.getRemoteAddr(), request.getRequestURI(), getQuery(request));
}
/**
* 后置通知:在连接点之后执行的通知
*
* @param ret
* @throws Throwable
*/
@AfterReturning(returning = "ret", pointcut = "httpRequestLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
logger.info("response:" + JSON.toJSONString(ret));
}
private String getQuery(HttpServletRequest request) {
if (isPostPutRequest(request)) {
return getParameters(request) + getRequestBody(request);
} else {
return getParameters(request);
}
}
private boolean isPostPutRequest(HttpServletRequest request) {
return "POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod());
}
private String getParameters(HttpServletRequest request) {
StringBuilder sb = new StringBuilder();
Map<String, String[]> params = request.getParameterMap();
for (String key : params.keySet()) {
sb.append('[')
.append(key)
.append('=')
.append(request.getParameter(key))
.append("] ");
}
return sb.toString();
}
private String getRequestBody(HttpServletRequest request) {
try {
return IOUtils.toString(request.getInputStream(), String.valueOf(Charset.defaultCharset()));
} catch (IOException e) {
return "";
}
}
}
package cn.qg.holmes.common;
import lombok.Data;
import java.io.Serializable;
@Data
public class JsonResult<T> implements Serializable {
private static final Long SUCCESS_CODE = 0L;
private static final String SUCCESS_MSG = "SUCCESS";
private static final Long ERROR_STATE_CODE = 1L;
private static final Long SUCCESS_BUSSINESS_CODE = 0L;
private static final Long ERROR_BUSSINESS_CODE = 1L;
private static final long serialVersionUID = -1L;
public static final Long API_INVOKE_UNEXPECTED_RESULT_CODE = 2L;
public static final String ZERO_FILL_TEMPLATE = "%04d";
private String msg = "";
// 0成功,1失败
private String code = "0000";
// 业务错误码
private String businessCode = "0000";
// 业务状态码
private String businessFlag = "0000";
private Object data = null;
public JsonResult() {
}
/**
* @param msg
* @param code
* @param data
*/
public JsonResult(String msg, Long code, Object data) {
this.msg = msg;
this.code = String.format(ZERO_FILL_TEMPLATE, code);
this.data = data;
}
public JsonResult(String msg, Long code, Object data, Long businessCode) {
this.msg = msg;
this.code = String.format(ZERO_FILL_TEMPLATE, code);
this.data = data;
this.businessCode = String.format(ZERO_FILL_TEMPLATE, businessCode);
}
public JsonResult(String msg, Long code, Object data, Long businessFlag, Long businessCode) {
this.msg = msg;
this.code = String.format(ZERO_FILL_TEMPLATE, code);
this.data = data;
this.businessCode = String.format(ZERO_FILL_TEMPLATE, businessCode);
this.businessFlag = String.format(ZERO_FILL_TEMPLATE, businessFlag);
}
/**
* 构造成功的JsonResult
*
* @param msg String
* @param data Object
* @return JsonResult
*/
public static JsonResult buildSuccessResult(String msg, Object data) {
return new JsonResult(msg, SUCCESS_CODE, data, SUCCESS_BUSSINESS_CODE);
}
public static JsonResult buildSuccessResult(Object data) {
return new JsonResult(SUCCESS_MSG, SUCCESS_CODE, data, SUCCESS_BUSSINESS_CODE);
}
public static JsonResult buildSuccessResult(String msg, Object data, Long bussinessId) {
return new JsonResult(msg, SUCCESS_CODE, data, bussinessId);
}
public static JsonResult buildSuccessResult(String msg, Object data, Long businessFlag, Long bussinessCode) {
return new JsonResult(msg, SUCCESS_CODE, data, businessFlag, bussinessCode);
}
/**
* 构造状态不正确的JsonResult
*
* @param msg String
* @param data Object
* @return JsonResult
*/
public static JsonResult buildErrorStateResult(String msg, Object data) {
return new JsonResult(msg, SUCCESS_CODE, data, ERROR_BUSSINESS_CODE);
}
public static JsonResult buildErrorStateResult(String msg, Object data, Long busniessId) {
return new JsonResult(msg, SUCCESS_CODE, data, busniessId);
}
public static JsonResult buildFatalErrorStateResult(String msg, Object data, Long busniessId) {
return new JsonResult(msg, ERROR_STATE_CODE, data, busniessId);
}
public static JsonResult buildFatalErrorStateResult(String msg, Object data) {
return new JsonResult(msg, ERROR_STATE_CODE, data, 1L);
}
public static JsonResult buildApiInvokeUnexpectedResult(String msg, Object data) {
return new JsonResult(msg, SUCCESS_CODE, data, API_INVOKE_UNEXPECTED_RESULT_CODE);
}
public JsonResult(Object data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getBusinessCode() {
return businessCode;
}
public void setBusinessCode(String businessCode) {
this.businessCode = businessCode;
}
public String getBusinessFlag() {
return businessFlag;
}
public void setBusinessFlag(String businessFlag) {
this.businessFlag = businessFlag;
}
@Override
public String toString() {
return "JsonResult{" + "businessCode='" + businessCode + '\'' + ", code='" + code + '\'' + ", data=" + data
+ ",businessFlag=" + businessFlag + '}';
}
public boolean isSuccess() {
return "0000".equals(code) && "0000".equals(businessCode);
}
}
package cn.qg.holmes.config;
import cn.qg.holmes.interceptor.YeebaoInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 拦截器,用于Mock
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public YeebaoInterceptor yeebaoInterceptor() {
return new YeebaoInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(yeebaoInterceptor()).addPathPatterns("/mock/tzt-api/**", "/mock/balance-board/**");
}
}
package cn.qg.holmes.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
/**
* 分页配置
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
package cn.qg.holmes.config;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* 配置自定义redisTemplate
*/
@Bean
RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 设置值(value)的序列化采用Jackson2JsonRedisSerializer。
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// 设置键(key)的序列化采用StringRedisSerializer。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
package cn.qg.holmes.controller.mock;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.mock.Mock;
import cn.qg.holmes.service.mock.MockService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@CrossOrigin
@RestController
public class MockController {
@Autowired
MockService mockService;
@RequestMapping(value = "/mock/**", method = { RequestMethod.GET, RequestMethod.POST})
public void mockMethod() {}
@PostMapping("/add/mock")
public JsonResult addMock(@RequestBody Mock mock) {
return JsonResult.buildSuccessResult(mockService.save(mock));
}
@GetMapping("/list/mock")
public JsonResult getMockList(Integer pageNum, Integer pageSize) {
IPage<Mock> page = new Page<>(pageNum, pageSize);
IPage<Mock> pageEntity = mockService.page(page);
Map<String, Object> map = new HashMap<>();
map.put("list", pageEntity.getRecords());
map.put("total", pageEntity.getTotal());
return JsonResult.buildSuccessResult(map);
}
@PostMapping("/edit/mock")
public JsonResult modifyMock(@RequestBody Mock mock) {
return JsonResult.buildSuccessResult(mockService.saveOrUpdate(mock));
}
}
package cn.qg.holmes.encrypt;
public interface EncryptConvertor {
String encrypt(String response);
String decrypt(String request);
}
package cn.qg.holmes.encrypt;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class EncryptFactory {
public static EncryptConvertor produce(String type) {
if ("yeebao".equals(type)) {
return new YeebaoEncryptConvertor();
} else {
log.info("请输入正确的加密类型类型!");
return null;
}
}
}
package cn.qg.holmes.encrypt;
import cn.qg.holmes.encrypt.yeebao.Aes;
import cn.qg.holmes.encrypt.yeebao.Rsa;
import com.alibaba.fastjson.JSON;
import java.util.HashMap;
import java.util.Map;
public class YeebaoEncryptConvertor implements EncryptConvertor{
private final String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANSBQSc0Hlr+mS7uoIjYS71X2DJ6ZrCcbB1uICqty9QY6W16nZ8tLN/d9k2Z+e2rGG8s7PskpU2T+WuJeDSXs/vpPllG8/tSRVaWcr9EzPaSti3ltSUH0QOLSypZEjTT/slscExj4PMOmQXUXP3gewjNWz1cYRI7dGnKPm+ZFah/AgMBAAECgYB8AcFngz6DkzcI8C+2K6JnJ6/+JPdv8JgWxID45tqfNrphLMB2dwJM0VY+CrCSRNnJZsoT9FqSXtuaKWqAJlbchhPZjupA9RkWFzlGpCQ63/CC71RYYY03eCnc7AIpn52whkjfWG/yf57jKzEwUT+U034uvXdaA+lVvJ0xqpj3gQJBAOmLODjecn450TJbNQaop+7Q5Hz2TUIxbYakzPpcLGv1QYgHa657r7PJ23ZltDBGldMaNTZfqJrtDcq0rTA4lBECQQDo8CcdUhMZ3JbR2UZN0CG8ljMbNWgNWBa37ebE3ZG5yYldc7zY9US/+/7lhxNDqG0saTvM9pJwEc3ccVMvksOPAkEAqq7V+zIQKVJmItBn06MFgNNoei+kTUFEk8f0CvG8gXYwW5NYzp+UzOg1HbW82B9uNmeMBl4pInknwEMF5B0lkQJAdRxQPgCGk+kAdo6LNxHd9Ed7eEF4h8Ty3xQfgnh3DHYTtsU6e8WMBA24kENB3zEtejeKFjkdVHTPD/Z1wSRDZwJAAvNuq0YuRDsESOAerkBZKonA5CD0M4vHTRqihHrjBohv6yxBU8P7gALrX7qmoaZ3aLmN8wHdOAGTR6LZjQdkoQ==";
private String aesKey = null;
private String encryptKey = null;
/**
* 易宝加密
* @param response
* @return
*/
@Override
public String encrypt(String response) {
try {
Map responseMap = JSON.parseObject(response, Map.class);
Map<String, Object> signData = new HashMap<>();
responseMap.put("sign", Rsa.sign(response, privateKey));
signData.put("encryptkey", encryptKey);
signData.put("data", Aes.encryptToBase64(JSON.toJSONString(responseMap), aesKey));
return JSON.toJSONString(signData);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 易宝解密
* @param request Http请求的request
* @return
*/
@Override
public String decrypt(String request) {
try {
Map requestMap = JSON.parseObject(request, Map.class);
encryptKey = requestMap.get("encryptkey").toString();
aesKey = Rsa.decrypt(encryptKey, privateKey);
return Aes.decryptFromBase64((String) requestMap.get("data"), aesKey);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
package cn.qg.holmes.encrypt.yeebao;
public abstract class AbstractConvertUtils {
private AbstractConvertUtils() {
}
public static String toHex(byte input[]) {
if (input == null) {
return null;
}
StringBuffer output = new StringBuffer(input.length * 2);
for (int i = 0; i < input.length; i++) {
int current = input[i] & 0xff;
if (current < 16) {
output.append("0");
}
output.append(Integer.toString(current, 16));
}
return output.toString();
}
}
package cn.qg.holmes.encrypt.yeebao;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class Aes {
private static final int KEY_LENGTH = 16;
/**
* 加密
*
* @param data 需要加密的内容
* @param key 加密密码
*/
public static byte[] encrypt(byte[] data, byte[] key) {
CheckUtils.notEmpty(data, "data");
CheckUtils.notEmpty(key, "key");
if (key.length != KEY_LENGTH) {
throw new RuntimeException("Invalid Aes key length (must be 16 bytes)");
}
try {
SecretKeySpec secretKey = new SecretKeySpec(key, "Aes");
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec seckey = new SecretKeySpec(enCodeFormat, "Aes");
Cipher cipher = Cipher.getInstance(ConfigureEncryptAndDecrypt.AES_ALGORITHM);// 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, seckey);// 初始化
byte[] result = cipher.doFinal(data);
return result; // 加密
} catch (Exception e) {
throw new RuntimeException("encrypt fail!", e);
}
}
/**
* 解密
*
* @param data 待解密内容
* @param key 解密密钥
*/
public static byte[] decrypt(byte[] data, byte[] key) {
CheckUtils.notEmpty(data, "data");
CheckUtils.notEmpty(key, "key");
if (key.length != KEY_LENGTH) {
throw new RuntimeException("Invalid Aes key length (must be 16 bytes)");
}
try {
SecretKeySpec secretKey = new SecretKeySpec(key, "Aes");
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec seckey = new SecretKeySpec(enCodeFormat, "Aes");
Cipher cipher = Cipher.getInstance(ConfigureEncryptAndDecrypt.AES_ALGORITHM);// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, seckey);// 初始化
byte[] result = cipher.doFinal(data);
return result; // 加密
} catch (Exception e) {
throw new RuntimeException("decrypt fail!", e);
}
}
public static String encryptToBase64(String data, String key) {
try {
byte[] valueByte = encrypt(data.getBytes(ConfigureEncryptAndDecrypt.CHAR_ENCODING),
key.getBytes(ConfigureEncryptAndDecrypt.CHAR_ENCODING));
return new String(Base64.encode(valueByte));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("encrypt fail!", e);
}
}
public static String decryptFromBase64(String data, String key) {
try {
byte[] originalData = Base64.decode(data.getBytes());
byte[] valueByte =
decrypt(originalData, key.getBytes(ConfigureEncryptAndDecrypt.CHAR_ENCODING));
return new String(valueByte, ConfigureEncryptAndDecrypt.CHAR_ENCODING);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("decrypt fail!", e);
}
}
public static String encryptWithKeyBase64(String data, String key) {
try {
byte[] valueByte = encrypt(data.getBytes(ConfigureEncryptAndDecrypt.CHAR_ENCODING),
Base64.decode(key.getBytes()));
return new String(Base64.encode(valueByte));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("encrypt fail!", e);
}
}
public static String decryptWithKeyBase64(String data, String key) {
try {
byte[] originalData = Base64.decode(data.getBytes());
byte[] valueByte = decrypt(originalData, Base64.decode(key.getBytes()));
return new String(valueByte, ConfigureEncryptAndDecrypt.CHAR_ENCODING);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("decrypt fail!", e);
}
}
public static byte[] genarateRandomKey() {
KeyGenerator keygen = null;
try {
keygen = KeyGenerator.getInstance(ConfigureEncryptAndDecrypt.AES_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(" genarateRandomKey fail!", e);
}
SecureRandom random = new SecureRandom();
keygen.init(random);
Key key = keygen.generateKey();
return key.getEncoded();
}
public static String genarateRandomKeyWithBase64() {
return new String(Base64.encode(genarateRandomKey()));
}
}
This diff is collapsed.
package cn.qg.holmes.encrypt.yeebao;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
public class CheckUtils {
/**
* 验证对象是否为NULL,空字符串,空数组,空的Collection或Map(只有空格的字符串也认为是空串)
*
* @param obj 被验证的对象
* @param message 异常信息
*/
@SuppressWarnings("rawtypes")
public static void notEmpty(Object obj, String message) {
if (obj == null) {
throw new IllegalArgumentException(message + " must be specified");
}
if (obj instanceof String && obj.toString().trim().length() == 0) {
throw new IllegalArgumentException(message + " must be specified");
}
if (obj.getClass().isArray() && Array.getLength(obj) == 0) {
throw new IllegalArgumentException(message + " must be specified");
}
if (obj instanceof Collection && ((Collection) obj).isEmpty()) {
throw new IllegalArgumentException(message + " must be specified");
}
if (obj instanceof Map && ((Map) obj).isEmpty()) {
throw new IllegalArgumentException(message + " must be specified");
}
}
}
package cn.qg.holmes.encrypt.yeebao;
public class ConfigureEncryptAndDecrypt {
public static final String CHAR_ENCODING = "UTF-8";
public static final String AES_ALGORITHM = "Aes/ECB/PKCS5Padding";
public static final String RSA_ALGORITHM = "Rsa/ECB/PKCS1Padding";
}
package cn.qg.holmes.encrypt.yeebao;
import lombok.extern.slf4j.Slf4j;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
@Slf4j
public class Digest {
public static final String ENCODE = "UTF-8";
public static String signMD5(String aValue, String encoding) {
try {
byte[] input = aValue.getBytes(encoding);
MessageDigest md = MessageDigest.getInstance("MD5");
return AbstractConvertUtils.toHex(md.digest(input));
} catch (NoSuchAlgorithmException e) {
log.error("{}", e);
return null;
} catch (UnsupportedEncodingException e) {
log.error("{}", e);
return null;
}
}
public static String hmacSign(String aValue) {
try {
byte[] input = aValue.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
return AbstractConvertUtils.toHex(md.digest(input));
} catch (NoSuchAlgorithmException e) {
log.error("{}", e);
return null;
}
}
public static String hmacSign(String aValue, String aKey) {
return hmacSign(aValue, aKey, ENCODE);
}
public static String hmacSign(String aValue, String aKey, String encoding) {
byte k_ipad[] = new byte[64];
byte k_opad[] = new byte[64];
byte keyb[];
byte value[];
try {
keyb = aKey.getBytes(encoding);
value = aValue.getBytes(encoding);
} catch (UnsupportedEncodingException e) {
keyb = aKey.getBytes();
value = aValue.getBytes();
}
Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
for (int i = 0; i < keyb.length; i++) {
k_ipad[i] = (byte) (keyb[i] ^ 0x36);
k_opad[i] = (byte) (keyb[i] ^ 0x5c);
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
log.error("{}", e);
return null;
}
md.update(k_ipad);
md.update(value);
byte dg[] = md.digest();
md.reset();
md.update(k_opad);
md.update(dg, 0, 16);
dg = md.digest();
return AbstractConvertUtils.toHex(dg);
}
public static String hmacSHASign(String aValue, String aKey, String encoding) {
byte k_ipad[] = new byte[64];
byte k_opad[] = new byte[64];
byte keyb[];
byte value[];
try {
keyb = aKey.getBytes(encoding);
value = aValue.getBytes(encoding);
} catch (UnsupportedEncodingException e) {
keyb = aKey.getBytes();
value = aValue.getBytes();
}
Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
for (int i = 0; i < keyb.length; i++) {
k_ipad[i] = (byte) (keyb[i] ^ 0x36);
k_opad[i] = (byte) (keyb[i] ^ 0x5c);
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException e) {
log.error("{}", e);
return null;
}
md.update(k_ipad);
md.update(value);
byte dg[] = md.digest();
md.reset();
md.update(k_opad);
md.update(dg, 0, 20);
dg = md.digest();
return AbstractConvertUtils.toHex(dg);
}
public static String digest(String aValue) {
return digest(aValue, ENCODE);
}
public static String digest(String aValue, String encoding) {
aValue = aValue.trim();
byte value[];
try {
value = aValue.getBytes(encoding);
} catch (UnsupportedEncodingException e) {
value = aValue.getBytes();
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException e) {
log.error("{}", e);
return null;
}
return AbstractConvertUtils.toHex(md.digest(value));
}
public static String digest(String aValue, String alg, String encoding) {
aValue = aValue.trim();
byte value[];
try {
value = aValue.getBytes(encoding);
} catch (UnsupportedEncodingException e) {
value = aValue.getBytes();
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance(alg);
} catch (NoSuchAlgorithmException e) {
log.error("{}", e);
return null;
}
return AbstractConvertUtils.toHex(md.digest(value));
}
public static String udpSign(String aValue) {
try {
byte[] input = aValue.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("SHA1");
return new String(Base64.encode(md.digest(input)), ENCODE);
} catch (Exception e) {
return null;
}
}
}
package cn.qg.holmes.encrypt.yeebao;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.Map.Entry;
import java.util.TreeMap;
@Slf4j
public class EncryUtil {
/**
* 生成RSA签名
*/
public static String handleRSA(TreeMap<String, Object> map,
String privateKey) {
StringBuffer sbuffer = new StringBuffer();
for (Entry<String, Object> entry : map.entrySet()) {
sbuffer.append(entry.getValue());
}
String signTemp = sbuffer.toString();
String sign = "";
if (StringUtils.isNotEmpty(privateKey)) {
sign = Rsa.sign(signTemp, privateKey);
}
return sign;
}
/**
* 对易宝支付返回的结果进行验签
*
* @param data 易宝支付返回的业务数据密文
* @param encrypt_key 易宝支付返回的对ybAesKey加密后的密文
* @param yibaoPublickKey 易宝支付提供的公钥
* @param merchantPrivateKey 商户自己的私钥
* @return 验签是否通过
* @throws Exception
*/
public static boolean checkDecryptAndSign(String data, String encrypt_key,
String yibaoPublickKey, String merchantPrivateKey) {
/** 1.使用YBprivatekey解开aesEncrypt。 */
String AESKey;
try {
AESKey = Rsa.decrypt(encrypt_key, merchantPrivateKey);
} catch (Exception e) {
/** AES密钥解密失败 */
log.error("{}", e);
return false;
}
/** 2.用aeskey解开data。取得data明文 */
String realData = Aes.decryptFromBase64(data, AESKey);
TreeMap<String, String> map = JSON.parseObject(realData,
new TypeReference<TreeMap<String, String>>() {
});
/** 3.取得data明文sign。 */
String sign = StringUtils.trimToEmpty(map.get("sign"));
StringBuilder signData = new StringBuilder();
for (Entry<String, String> entry : map.entrySet()) {
if (StringUtils.equals(entry.getKey(), "sign")) {
continue;
}
signData.append(entry.getValue() == null ? "" : entry.getValue());
}
/** 5. result为true时表明验签通过 */
String str = signData.toString();
return Rsa.checkSign(str, sign,
yibaoPublickKey);
}
}
package cn.qg.holmes.encrypt.yeebao;
import java.security.SecureRandom;
public class RandomUtil {
public static final SecureRandom random = new SecureRandom();
public static String getRandom(int length) {
StringBuilder ret = new StringBuilder();
for (int i = 0; i < length; i++) {
boolean isChar = (random.nextInt(2) % 2 == 0);// 输出字母还是数字
if (isChar) { // 字符串
int choice = random.nextInt(2) % 2 == 0 ? 65 : 97; // 取得大写字母还是小写字母
ret.append((char) (choice + random.nextInt(26)));
} else { // 数字
ret.append(Integer.toString(random.nextInt(10)));
}
}
return ret.toString();
}
}
package cn.qg.holmes.encrypt.yeebao;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class Rsa {
/**
* 指定key的大小
*/
private static int KEYSIZE = 1024;
/**
* 生成密钥对
*/
public static Map<String, String> generateKeyPair() throws Exception {
/** RSA算法要求有一个可信任的随机数源 */
SecureRandom sr = new SecureRandom();
/** 为RSA算法创建一个KeyPairGenerator对象 */
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Rsa");
/** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
kpg.initialize(KEYSIZE, sr);
/** 生成密匙对 */
KeyPair kp = kpg.generateKeyPair();
/** 得到公钥 */
Key publicKey = kp.getPublic();
byte[] publicKeyBytes = publicKey.getEncoded();
String pub = new String(Base64.encodeBase64(publicKeyBytes),
ConfigureEncryptAndDecrypt.CHAR_ENCODING);
/** 得到私钥 */
Key privateKey = kp.getPrivate();
byte[] privateKeyBytes = privateKey.getEncoded();
String pri = new String(Base64.encodeBase64(privateKeyBytes),
ConfigureEncryptAndDecrypt.CHAR_ENCODING);
Map<String, String> map = new HashMap<String, String>();
map.put("publicKey", pub);
map.put("privateKey", pri);
RSAPublicKey rsp = (RSAPublicKey) kp.getPublic();
BigInteger bint = rsp.getModulus();
byte[] b = bint.toByteArray();
byte[] deBase64Value = Base64.encodeBase64(b);
String retValue = new String(deBase64Value);
map.put("modulus", retValue);
return map;
}
/**
* 加密方法 source: 源数据
*/
public static String encrypt(String source, String publicKey)
throws Exception {
Key key = getPublicKey(publicKey);
/** 得到Cipher对象来实现对源数据的RSA加密 */
Cipher cipher = Cipher.getInstance(ConfigureEncryptAndDecrypt.RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] b = source.getBytes();
/** 执行加密操作 */
byte[] b1 = cipher.doFinal(b);
return new String(Base64.encodeBase64(b1),
ConfigureEncryptAndDecrypt.CHAR_ENCODING);
}
/**
* 解密算法 cryptograph:密文
*/
public static String decrypt(String cryptograph, String privateKey)
throws Exception {
Key key = getPrivateKey(privateKey);
/** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
Cipher cipher = Cipher.getInstance(ConfigureEncryptAndDecrypt.RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] b1 = Base64.decodeBase64(cryptograph.getBytes());
/** 执行解密操作 */
byte[] b = cipher.doFinal(b1);
return new String(b);
}
/**
* 得到公钥
*
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PublicKey getPublicKey(String key) throws Exception {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(
Base64.decodeBase64(key.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("Rsa");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/**
* 得到私钥
*
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
Base64.decodeBase64(key.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("Rsa");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
public static String sign(String content, String privateKey) {
String charset = ConfigureEncryptAndDecrypt.CHAR_ENCODING;
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
Base64.decodeBase64(privateKey.getBytes()));
KeyFactory keyf = KeyFactory.getInstance("Rsa");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
Signature signature = Signature.getInstance("SHA1WithRSA");
signature.initSign(priKey);
signature.update(content.getBytes(charset));
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed));
} catch (Exception e) {
}
return null;
}
public static boolean checkSign(String content, String sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("Rsa");
byte[] encodedKey = Base64.decode2(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
Signature signature = Signature
.getInstance("SHA1WithRSA");
signature.initVerify(pubKey);
signature.update(content.getBytes("utf-8"));
boolean bverify = signature.verify(Base64.decode2(sign));
return bverify;
} catch (Exception e) {
log.error("{}", e);
}
return false;
}
}
package cn.qg.holmes.entity.mock;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
@Data
@TableName(value = "mock")
public class Mock {
@TableId(type = IdType.AUTO)
private Integer id;
private String url;
private String description;
private String success;
private String fail;
/**
* 0-返回失败,1-返回成功
*/
private Integer flag;
/**
* 0-不加密,1-加密
*/
private Integer encrypt;
/**
* 1-json,2-字符串
*/
private Integer type;
/**
* 所属模块
*/
private Integer module;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
This diff is collapsed.
package cn.qg.holmes.mapper.mock;
import cn.qg.holmes.entity.mock.Mock;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface MockMapper extends BaseMapper<Mock> {
}
package cn.qg.holmes.service.mock;
import cn.qg.holmes.entity.mock.Mock;
import com.baomidou.mybatisplus.extension.service.IService;
public interface MockService extends IService<Mock> {
}
package cn.qg.holmes.service.mock.impl;
import cn.qg.holmes.entity.mock.Mock;
import cn.qg.holmes.mapper.mock.MockMapper;
import cn.qg.holmes.service.mock.MockService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class MockServiceImpl extends ServiceImpl<MockMapper, Mock> implements MockService {
}
package cn.qg.holmes.utils;
import com.alibaba.fastjson.JSONObject;
public class BankCardUtils {
public static String getCardCode(String cardNo) {
String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=" + cardNo + "&cardBinCheck=true";
JSONObject resposne = HttpClientUtils.doGetReturnJson(url);
return resposne.get("bank").toString();
}
public static void main(String[] args) {
System.out.println(getBankName("CCB"));
}
public static String getBankName(String code){
int a = 0;
for (int i = 0; i < bankBin.length-165; i++) {
if(code.equals(bankBin[i+a])){
return bankBin[i+a+1];
}
a++;
}
return "";
}
private final static String[] bankBin = {
"SRCB", "深圳农村商业银行",
"BGB", "广西北部湾银行",
"SHRCB", "上海农村商业银行",
"BJBANK", "北京银行",
"WHCCB", "威海市商业银行",
"BOZK", "周口银行",
"KORLABANK", "库尔勒市商业银行",
"SPABANK", "平安银行",
"SDEB", "顺德农商银行",
"HURCB", "湖北省农村信用社",
"WRCB", "无锡农村商业银行",
"BOCY", "朝阳银行",
"CZBANK", "浙商银行",
"HDBANK", "邯郸银行",
"BOC", "中国银行",
"BOD", "东莞银行",
"CCB", "中国建设银行",
"ZYCBANK", "遵义市商业银行",
"SXCB", "绍兴银行",
"GZRCU", "贵州省农村信用社",
"ZJKCCB", "张家口市商业银行",
"BOJZ", "锦州银行",
"BOP", "平顶山银行",
"HKB", "汉口银行",
"SPDB", "上海浦东发展银行",
"NXRCU", "宁夏黄河农村商业银行",
"NYNB", "广东南粤银行",
"GRCB", "广州农商银行",
"BOSZ", "苏州银行",
"HZCB", "杭州银行",
"HSBK", "衡水银行",
"HBC", "湖北银行",
"JXBANK", "嘉兴银行",
"HRXJB", "华融湘江银行",
"BODD", "丹东银行",
"AYCB", "安阳银行",
"EGBANK", "恒丰银行",
"CDB", "国家开发银行",
"TCRCB", "江苏太仓农村商业银行",
"NJCB", "南京银行",
"ZZBANK", "郑州银行",
"DYCB", "德阳商业银行",
"YBCCB", "宜宾市商业银行",
"SCRCU", "四川省农村信用",
"KLB", "昆仑银行",
"LSBANK", "莱商银行",
"YDRCB", "尧都农商行",
"CCQTGB", "重庆三峡银行",
"FDB", "富滇银行",
"JSRCU", "江苏省农村信用联合社",
"JNBANK", "济宁银行",
"CMB", "招商银行",
"JINCHB", "晋城银行JCBANK",
"FXCB", "阜新银行",
"WHRCB", "武汉农村商业银行",
"HBYCBANK", "湖北银行宜昌分行",
"TZCB", "台州银行",
"TACCB", "泰安市商业银行",
"XCYH", "许昌银行",
"CEB", "中国光大银行",
"NXBANK", "宁夏银行",
"HSBANK", "徽商银行",
"JJBANK", "九江银行",
"NHQS", "农信银清算中心",
"MTBANK", "浙江民泰商业银行",
"LANGFB", "廊坊银行",
"ASCB", "鞍山银行",
"KSRB", "昆山农村商业银行",
"YXCCB", "玉溪市商业银行",
"DLB", "大连银行",
"DRCBCL", "东莞农村商业银行",
"GCB", "广州银行",
"NBBANK", "宁波银行",
"BOYK", "营口银行",
"SXRCCU", "陕西信合",
"GLBANK", "桂林银行",
"BOQH", "青海银行",
"CDRCB", "成都农商银行",
"QDCCB", "青岛银行",
"HKBEA", "东亚银行",
"HBHSBANK", "湖北银行黄石分行",
"WZCB", "温州银行",
"TRCB", "天津农商银行",
"QLBANK", "齐鲁银行",
"GDRCC", "广东省农村信用社联合社",
"ZJTLCB", "浙江泰隆商业银行",
"GZB", "赣州银行",
"GYCB", "贵阳市商业银行",
"CQBANK", "重庆银行",
"DAQINGB", "龙江银行",
"CGNB", "南充市商业银行",
"SCCB", "三门峡银行",
"CSRCB", "常熟农村商业银行",
"SHBANK", "上海银行",
"JLBANK", "吉林银行",
"CZRCB", "常州农村信用联社",
"BANKWF", "潍坊银行",
"ZRCBANK", "张家港农村商业银行",
"FJHXBC", "福建海峡银行",
"ZJNX", "浙江省农村信用社联合社",
"LZYH", "兰州银行",
"JSB", "晋商银行",
"BOHAIB", "渤海银行",
"CZCB", "浙江稠州商业银行",
"YQCCB", "阳泉银行",
"SJBANK", "盛京银行",
"XABANK", "西安银行",
"BSB", "包商银行",
"JSBANK", "江苏银行",
"FSCB", "抚顺银行",
"HNRCU", "河南省农村信用",
"COMM", "交通银行",
"XTB", "邢台银行",
"CITIC", "中信银行",
"HXBANK", "华夏银行",
"HNRCC", "湖南省农村信用社",
"DYCCB", "东营市商业银行",
"ORBANK", "鄂尔多斯银行",
"BJRCB", "北京农村商业银行",
"XYBANK", "信阳银行",
"ZGCCB", "自贡市商业银行",
"CDCB", "成都银行",
"HANABANK", "韩亚银行",
"CMBC", "中国民生银行",
"LYBANK", "洛阳银行",
"GDB", "广东发展银行",
"ZBCB", "齐商银行",
"CBKF", "开封市商业银行",
"H3CB", "内蒙古银行",
"CIB", "兴业银行",
"CRCBANK", "重庆农村商业银行",
"SZSBK", "石嘴山银行",
"DZBANK", "德州银行",
"SRBANK", "上饶银行",
"LSCCB", "乐山市商业银行",
"JXRCU", "江西省农村信用",
"ICBC", "中国工商银行",
"JZBANK", "晋中市商业银行",
"HZCCB", "湖州市商业银行",
"NHB", "南海农村信用联社",
"XXBANK", "新乡银行",
"JRCB", "江苏江阴农村商业银行",
"YNRCC", "云南省农村信用社",
"ABC", "中国农业银行",
"GXRCU", "广西省农村信用",
"PSBC", "中国邮政储蓄银行",
"BZMD", "驻马店银行",
"ARCU", "安徽省农村信用社",
"GSRCU", "甘肃省农村信用",
"LYCB", "辽阳市商业银行",
"JLRCU", "吉林农信",
"URMQCCB", "乌鲁木齐市商业银行",
"XLBANK", "中山小榄村镇银行",
"CSCB", "长沙银行",
"JHBANK", "金华银行",
"BHB", "河北银行",
"NBYZ", "鄞州银行",
"LSBC", "临商银行",
"BOCD", "承德银行",
"SDRCU", "山东农信",
"NCB", "南昌银行",
"TCCB", "天津银行",
"WJRCB", "吴江农商银行",
"CBBQS", "城市商业银行资金清算中心",
"HBRCU", "河北省农村信用社"
};
}
This diff is collapsed.
This diff is collapsed.
spring:
datasource:
url: jdbc:mysql://172.17.5.5:32178/holmes
username: qa
password: qatest
driver-class-name: com.mysql.jdbc.Driver
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
redis:
host: 172.17.5.12
port: 32236
database: 0
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
application:
name: holmes
server:
port: 8084
mybatis-plus:
mapper-locations: classpath:mapper/*/*.xml
type-aliases-package: cn.qg.holmes.entity
configuration:
map-underscore-to-camel-case: true
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 日志配置 -->
<configuration>
<property name="DEV_HOME" value="."/>
<springProperty name="spring.application.name" source="spring.application.name"/>
<property name="LOG_LEVEL_PATTERN"
value="%clr(%5p) %clr([${spring.application.name:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]){yellow}"/>
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%10.10t]){faint} [%40.40file:%4.4line] %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 这里面定义了 CONSOLE_LOG_PATTERN, FILE_LOG_PATTERN 等日志格式, 还定义了一些日志级别 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--滚动文件日志-->
<appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DEV_HOME}/debug.log</file>
<append>true</append>
<encoder>
<!--日志输出格式-->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${DEV_HOME}/debug.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>300MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<logger name="com.example.demo" level="DEBUG"/>
<logger name="org.apache" level="warn"/>
<logger name="org.springframework" level="warn"/>
<logger name="ch.qos.logback" level="warn"/>
<!--基础的日志输出-->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="fileLog"/>
</root>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 日志配置 -->
<configuration>
<springProperty name="spring.application.name" source="spring.application.name"/>
<property name="LOG_LEVEL_PATTERN" value="%5p [${spring.application.name:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]"/>
<property name="FILE_LOG_PATTERN"
value="${FILE_LOG_PATTERN:-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} --- [%thread] [%file:%line] %logger - %msg%n}"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/home/quant_group/logs/qa-platform.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/home/quant_group/logs/qa-platform.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="Sentry" class="cn.quantgroup.sentry.appender.StandardSentryAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
<!-- level:基本建议ERROR or WARN -->
</filter>
</appender>
<logger name="org.springframework" level="warn"/>
<logger name="org.hibernate" level="warn"/>
<logger name="org.apache" level="warn"/>
<logger name="ch.qos.logback" level="warn"/>
<!--基础的日志输出-->
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="Sentry"/>
</root>
</configuration>
\ No newline at end of file
package cn.qg.holmes;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class HolmesApplicationTests {
@Test
void contextLoads() {
}
}
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