🎨 引入spring-java-format插件,代码格式管理

This commit is contained in:
b2baccline
2020-06-25 00:19:21 +08:00
parent 2b01fb6f5b
commit 89add5d79a
329 changed files with 6464 additions and 6260 deletions

View File

@@ -8,21 +8,19 @@ package com.hccake.ballcat.common.core.constant;
public class GlobalConstants {
/**
* 未被逻辑删除的标识,即有效数据标识
* 逻辑删除标识,普通情况下可以使用 1 标识删除0 标识存活
* 但在有唯一索引的情况下,会导致索引冲突,所以用 0 标识存活, 已删除数据记录为删除时间戳
* 未被逻辑删除的标识,即有效数据标识 逻辑删除标识,普通情况下可以使用 1 标识删除0 标识存活 但在有唯一索引的情况下,会导致索引冲突,所以用 0 标识存活,
* 已删除数据记录为删除时间戳
*/
public static final Long NOT_DELETED_FLAG = 0L;
/**
* 生产环境
*/
public final static String ENV_PROD = "prod";
/**
* 树根节点ID
*/
public static final Integer TREE_ROOT_ID = 0;
}

View File

@@ -7,18 +7,22 @@ package com.hccake.ballcat.common.core.constant;
*/
public final class HeaderConstants {
private HeaderConstants(){}
private HeaderConstants() {
}
/**
* 请求时间戳
*/
public static final String REQ_TIME = "reqTime";
/**
* 请求sign
*/
public static final String SIGN = "sign";
/**
* SECRET_ID
*/
public static final String SECRET_ID = "secretId";
/**
* 请求时间戳
*/
public static final String REQ_TIME = "reqTime";
/**
* 请求sign
*/
public static final String SIGN = "sign";
/**
* SECRET_ID
*/
public static final String SECRET_ID = "secretId";
}

View File

@@ -12,14 +12,15 @@ import lombok.Getter;
@AllArgsConstructor
public enum BooleanEnum {
/**
* 是
*/
TRUE(1),
/**
* 否
*/
FALSE(0);
/**
* 是
*/
TRUE(1),
/**
* 否
*/
FALSE(0);
private final int value;
private final int value;
}

View File

@@ -5,35 +5,38 @@ import lombok.Getter;
/**
* 通用业务异常
*
* @author Hccake
*/
@Getter
public class BusinessException extends RuntimeException {
private final String msg;
private final int code;
public BusinessException(ResultCode resultCode) {
private final String msg;
private final int code;
public BusinessException(ResultCode resultCode) {
super(resultCode.getMessage());
this.code = resultCode.getCode();
this.msg = resultCode.getMessage();
}
public BusinessException(ResultCode resultCode, Throwable e) {
super(resultCode.getMessage(), e);
this.code = resultCode.getCode();
this.msg = resultCode.getMessage();
}
public BusinessException(int code, String msg) {
super(msg);
this.msg = msg;
this.code = code;
}
public BusinessException(int code, String msg, Throwable e) {
super(msg, e);
this.msg = msg;
this.code = code;
}
}

View File

@@ -5,23 +5,24 @@ import com.hccake.ballcat.common.core.result.SystemResultCode;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/19 16:52
* sql防注入校验异常
* @date 2019/10/19 16:52 sql防注入校验异常
*/
public class SqlCheckedException extends BusinessException {
public SqlCheckedException(SystemResultCode systemResultMsg) {
super(systemResultMsg);
}
public SqlCheckedException(SystemResultCode systemResultMsg, Throwable e) {
super(systemResultMsg, e);
}
public SqlCheckedException(SystemResultCode systemResultMsg) {
super(systemResultMsg);
}
public SqlCheckedException(int code, String msg) {
super(code, msg);
}
public SqlCheckedException(SystemResultCode systemResultMsg, Throwable e) {
super(systemResultMsg, e);
}
public SqlCheckedException(int code, String msg) {
super(code, msg);
}
public SqlCheckedException(int code, String msg, Throwable e) {
super(code, msg, e);
}
public SqlCheckedException(int code, String msg, Throwable e) {
super(code, msg, e);
}
}

View File

@@ -3,16 +3,14 @@ package com.hccake.ballcat.common.core.exception.handler;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/18 17:05
* 异常日志处理类
* @date 2019/10/18 17:05 异常日志处理类
*/
public interface GlobalExceptionHandler {
/**
* 在此处理错误信息
* 进行落库入ES 发送报警通知等信息
* @param throwable 异常
*/
void handle(Throwable throwable);
/**
* 在此处理错误信息 进行落库入ES 发送报警通知等信息
* @param throwable 异常
*/
void handle(Throwable throwable);
}

View File

@@ -25,68 +25,71 @@ import java.io.IOException;
*/
public class ActuatorFilter extends OncePerRequestFilter {
private final String secretId;
private final String secretKey;
private final String secretId;
private final String secretKey;
/**
* Instantiates a new Actuator filter.
*
* @param secretId the secret id
* @param secretId the secret id
* @param secretKey the secret key
*/
public ActuatorFilter(String secretId, String secretKey){
this.secretId = secretId;
this.secretKey = secretKey;
}
public ActuatorFilter(String secretId, String secretKey) {
this.secretId = secretId;
this.secretKey = secretKey;
}
/**
* Same contract as for {@code doFilter}, but guaranteed to be
* just invoked once per request within a single request thread.
* See {@link #shouldNotFilterAsyncDispatch()} for details.
* <p>Provides HttpServletRequest and HttpServletResponse arguments instead of the
* default ServletRequest and ServletResponse ones.
*
* @param request 请求信息
* @param response 响应信息
* @param filterChain 过滤器链
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
/**
* Same contract as for {@code doFilter}, but guaranteed to be just invoked once per
* request within a single request thread. See {@link #shouldNotFilterAsyncDispatch()}
* for details.
* <p>
* Provides HttpServletRequest and HttpServletResponse arguments instead of the
* default ServletRequest and ServletResponse ones.
* @param request 请求信息
* @param response 响应信息
* @param filterChain 过滤器链
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 检验签名是否正确
String reqSecretId = request.getHeader(HeaderConstants.SECRET_ID);
String sign = request.getHeader(HeaderConstants.SIGN);
String reqTime = request.getHeader(HeaderConstants.REQ_TIME);
if (verifySign(reqSecretId, sign, reqTime)) {
filterChain.doFilter(request, response);
}else {
response.setHeader("Content-Type", MediaType.APPLICATION_JSON.toString());
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().write(JSONUtil.toJsonStr(R.failed(SystemResultCode.UNAUTHORIZED)));
}
}
// 检验签名是否正确
String reqSecretId = request.getHeader(HeaderConstants.SECRET_ID);
String sign = request.getHeader(HeaderConstants.SIGN);
String reqTime = request.getHeader(HeaderConstants.REQ_TIME);
if (verifySign(reqSecretId, sign, reqTime)) {
filterChain.doFilter(request, response);
}
else {
response.setHeader("Content-Type", MediaType.APPLICATION_JSON.toString());
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().write(JSONUtil.toJsonStr(R.failed(SystemResultCode.UNAUTHORIZED)));
}
}
/**
* 校验sign
* @param reqSecretId secretId
* @param sign 签名
* @param reqTime 请求时间戳 ms
* @param reqTime 请求时间戳 ms
* @return boolean 通过返回true
*/
private boolean verifySign(String reqSecretId, String sign, String reqTime) {
if (StrUtil.isNotBlank(sign) && StrUtil.isNotBlank(reqTime) && StrUtil.isNotBlank(reqSecretId)) {
if(!reqSecretId.equals(secretId)){
return false;
}
// 过期时间 30秒失效
long expireTime = 30 * 1000;
long nowTime = System.currentTimeMillis();
if (nowTime - Long.parseLong(reqTime) <= expireTime) {
String reverse = StrUtil.reverse(reqTime);
String checkSign = SecureUtil.md5(reverse + secretId + secretKey);
return StrUtil.equalsIgnoreCase(checkSign, sign);
}
}
return false;
}
private boolean verifySign(String reqSecretId, String sign, String reqTime) {
if (StrUtil.isNotBlank(sign) && StrUtil.isNotBlank(reqTime) && StrUtil.isNotBlank(reqSecretId)) {
if (!reqSecretId.equals(secretId)) {
return false;
}
// 过期时间 30秒失效
long expireTime = 30 * 1000;
long nowTime = System.currentTimeMillis();
if (nowTime - Long.parseLong(reqTime) <= expireTime) {
String reverse = StrUtil.reverse(reqTime);
String checkSign = SecureUtil.md5(reverse + secretId + secretKey);
return StrUtil.equalsIgnoreCase(checkSign, sign);
}
}
return false;
}
}

View File

@@ -16,19 +16,21 @@ import java.io.IOException;
*/
public class XSSFilter extends OncePerRequestFilter {
/**
* Same contract as for {@code doFilter}, but guaranteed to be
* just invoked once per request within a single request thread.
* See {@link #shouldNotFilterAsyncDispatch()} for details.
* <p>Provides HttpServletRequest and HttpServletResponse arguments instead of the
* default ServletRequest and ServletResponse ones.
*
* @param request
* @param response
* @param filterChain
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
filterChain.doFilter(new XSSRequestWrapper(request), response);
}
/**
* Same contract as for {@code doFilter}, but guaranteed to be just invoked once per
* request within a single request thread. See {@link #shouldNotFilterAsyncDispatch()}
* for details.
* <p>
* Provides HttpServletRequest and HttpServletResponse arguments instead of the
* default ServletRequest and ServletResponse ones.
* @param request
* @param response
* @param filterChain
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(new XSSRequestWrapper(request), response);
}
}

View File

@@ -16,44 +16,46 @@ import java.util.Map;
* @date 2019/10/17 23:19
*/
public class ArraySerializerModifier extends BeanSerializerModifier {
private final JsonSerializer<Object> nullArrayJsonSerializer = new NullArrayJsonSerializer();
private final JsonSerializer<Object> nullMapJsonSerializer = new NullMapJsonSerializer();
private final JsonSerializer<Object> nullArrayJsonSerializer = new NullArrayJsonSerializer();
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
List<BeanPropertyWriter> beanProperties) {
// 循环所有的beanPropertyWriter
private final JsonSerializer<Object> nullMapJsonSerializer = new NullMapJsonSerializer();
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
List<BeanPropertyWriter> beanProperties) {
// 循环所有的beanPropertyWriter
for (BeanPropertyWriter writer : beanProperties) {
// 判断字段的类型如果是arraylistset则注册nullSerializer
if (isArrayType(writer)) {
writer.assignNullSerializer(this.nullArrayJsonSerializer);
} else if (isMapType(writer)) {
}
else if (isMapType(writer)) {
writer.assignNullSerializer(this.nullMapJsonSerializer);
}
}
return beanProperties;
}
return beanProperties;
}
/**
* 是否是Map类型
* @param writer BeanPropertyWriter
* @return boolean
*/
private boolean isMapType(BeanPropertyWriter writer) {
Class<?> clazz = writer.getType().getRawClass();
return Map.class.isAssignableFrom(clazz);
}
/**
* 是否是Map类型
* @param writer BeanPropertyWriter
* @return boolean
*/
private boolean isMapType(BeanPropertyWriter writer) {
Class<?> clazz = writer.getType().getRawClass();
return Map.class.isAssignableFrom(clazz);
}
/**
* 是否是集合类型
* @param writer BeanPropertyWriter
* @return boolean
*/
private boolean isArrayType(BeanPropertyWriter writer) {
Class<?> clazz = writer.getType().getRawClass();
return clazz.isArray() || Collection.class.isAssignableFrom(clazz);
/**
* 是否是集合类型
* @param writer BeanPropertyWriter
* @return boolean
*/
private boolean isArrayType(BeanPropertyWriter writer) {
Class<?> clazz = writer.getType().getRawClass();
return clazz.isArray() || Collection.class.isAssignableFrom(clazz);
}
}
}

View File

@@ -17,17 +17,25 @@ import java.time.format.DateTimeFormatter;
/**
* 自定义java8新增时间类型的序列化
*
* @author Hccake
*/
public class JavaTimeModule extends SimpleModule {
public JavaTimeModule() {
super(PackageVersion.VERSION);
this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
this.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));
this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));
this.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
this.addSerializer(LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
this.addSerializer(LocalTime.class,
new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));
this.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
this.addDeserializer(LocalDate.class,
new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
this.addDeserializer(LocalTime.class,
new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));
}
}

View File

@@ -9,20 +9,19 @@ import java.io.IOException;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/17 23:17
* 空数组序列化处理器
* 如果 Array 为 null则序列化为 []
* @date 2019/10/17 23:17 空数组序列化处理器 如果 Array 为 null则序列化为 []
*/
public class NullArrayJsonSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
if (value == null) {
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
} else {
jsonGenerator.writeObject(value);
}
}
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
if (value == null) {
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
}
else {
jsonGenerator.writeObject(value);
}
}
}

View File

@@ -9,20 +9,19 @@ import java.io.IOException;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/17 23:17
* 空 Map 序列化处理器
* Map 为 null则序列化为 {}
* @date 2019/10/17 23:17 空 Map 序列化处理器 Map 为 null则序列化为 {}
*/
public class NullMapJsonSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
if (value == null) {
jsonGenerator.writeStartObject();
jsonGenerator.writeEndObject();
} else {
jsonGenerator.writeObject(value);
}
}
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
if (value == null) {
jsonGenerator.writeStartObject();
jsonGenerator.writeEndObject();
}
else {
jsonGenerator.writeObject(value);
}
}
}

View File

@@ -9,12 +9,13 @@ import java.io.IOException;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/17 22:19
* jackson NULL值序列化为 ""
* @date 2019/10/17 22:19 jackson NULL值序列化为 ""
*/
public class NullSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
jsonGenerator.writeString("");
}
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
jsonGenerator.writeString("");
}
}

View File

@@ -10,23 +10,22 @@ import java.io.IOException;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/17 22:23
* XSS过滤
* @date 2019/10/17 22:23 XSS过滤
*/
public class XssStringJsonSerializer extends JsonSerializer<String> {
@Override
public Class<String> handledType() {
return String.class;
}
@Override
public Class<String> handledType() {
return String.class;
}
@Override
public void serialize(String value, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
if (value != null) {
String encodedValue = HtmlUtils.htmlEscape(value);
jsonGenerator.writeString(encodedValue);
}
}
@Override
public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
if (value != null) {
String encodedValue = HtmlUtils.htmlEscape(value);
jsonGenerator.writeString(encodedValue);
}
}
}

View File

@@ -10,20 +10,27 @@ import java.util.regex.Pattern;
/**
* 生成 markdown 文本
*
* @author lingting 2020/6/10 22:43
* @author lingting 2020/6/10 22:43
*/
public class MarkdownBuilder {
public static final String TITLE_PREFIX = "#";
public static final String QUOTE_PREFIX = "> ";
public static final String BOLD_PREFIX = "**";
public static final String ITALIC_PREFIX = "*";
public static final String UNORDERED_LIST_PREFIX = "- ";
public static final String ORDER_LIST_PREFIX = ". ";
/**
* 存放内容
*/
private final List<String> content = new ArrayList<>();
/**
* 当前操作行文本
*/
@@ -35,7 +42,6 @@ public class MarkdownBuilder {
/**
* 添加自定义内容
*
* @param content 自定义内容
* @author lingting 2020-06-10 23:14:54
*/
@@ -46,7 +52,6 @@ public class MarkdownBuilder {
/**
* 有序列表 自动生成 索引
*
* @param content 文本
* @author lingting 2020-06-10 23:13:41
*/
@@ -70,8 +75,7 @@ public class MarkdownBuilder {
/**
* 有序列表
*
* @param index 索引
* @param index 索引
* @param content 文本
* @author lingting 2020-06-10 23:13:41
*/
@@ -82,11 +86,9 @@ public class MarkdownBuilder {
}
/**
* 无序列表
* - item1
* - item2
* 无序列表 - item1 - item2
*
* @author lingting 2020-06-10 23:09:29
* @author lingting 2020-06-10 23:09:29
*/
public MarkdownBuilder unorderedList(String content) {
// 换行
@@ -97,7 +99,6 @@ public class MarkdownBuilder {
/**
* 图片
*
* @param url 图片链接
* @author lingting 2020-06-10 23:03:04
*/
@@ -107,9 +108,8 @@ public class MarkdownBuilder {
/**
* 图片
*
* @param title 图片标题
* @param url 图片路径
* @param url 图片路径
* @author lingting 2020-06-10 23:03:11
*/
public MarkdownBuilder pic(String title, String url) {
@@ -119,9 +119,8 @@ public class MarkdownBuilder {
/**
* 链接
*
* @param title 标题
* @param url http 路径
* @param url http 路径
* @author lingting 2020-06-10 23:01:15
*/
public MarkdownBuilder link(String title, String url) {
@@ -132,7 +131,7 @@ public class MarkdownBuilder {
/**
* 斜体
*
* @author lingting 2020-06-10 22:59:26
* @author lingting 2020-06-10 22:59:26
*/
public MarkdownBuilder italic(String content) {
lineTextBuilder.append(ITALIC_PREFIX).append(content).append(ITALIC_PREFIX);
@@ -142,7 +141,7 @@ public class MarkdownBuilder {
/**
* 加粗
*
* @author lingting 2020-06-10 22:58:39
* @author lingting 2020-06-10 22:58:39
*/
public MarkdownBuilder bold(String content) {
lineTextBuilder.append(BOLD_PREFIX).append(content).append(BOLD_PREFIX);
@@ -150,11 +149,9 @@ public class MarkdownBuilder {
}
/**
* 引用
* > 文本
*
* 引用 > 文本
* @param content 文本
* @author lingting 2020-06-10 22:58:04
* @author lingting 2020-06-10 22:58:04
*/
public MarkdownBuilder quote(String content) {
lineBreak();
@@ -165,7 +162,7 @@ public class MarkdownBuilder {
/**
* 添加引用后 强制换行
*
* @author lingting 2020-06-12 15:50:29
* @author lingting 2020-06-12 15:50:29
*/
public MarkdownBuilder quoteLineBreak(String content) {
quote(content);
@@ -175,7 +172,7 @@ public class MarkdownBuilder {
/**
* 强制换行
*
* @author lingting 2020-06-10 22:56:25
* @author lingting 2020-06-10 22:56:25
*/
public MarkdownBuilder forceLineBreak() {
content.add(lineTextBuilder.toString());
@@ -184,10 +181,9 @@ public class MarkdownBuilder {
}
/**
* 换行
* 当已编辑文本长度不为0时换行
* 换行 当已编辑文本长度不为0时换行
*
* @author lingting 2020-06-10 22:56:25
* @author lingting 2020-06-10 22:56:25
*/
public MarkdownBuilder lineBreak() {
if (lineTextBuilder.length() != 0) {
@@ -199,7 +195,7 @@ public class MarkdownBuilder {
/**
* 生成 i 级标题
*
* @author lingting 2020-06-10 22:55:39
* @author lingting 2020-06-10 22:55:39
*/
private MarkdownBuilder title(int i, String content) {
// 如果当前操作行已有字符,需要换行
@@ -240,7 +236,7 @@ public class MarkdownBuilder {
/**
* 构筑 Markdown 文本
*
* @author lingting 2020-06-11 22:55:40
* @author lingting 2020-06-11 22:55:40
*/
public String build() {
lineBreak();
@@ -248,4 +244,5 @@ public class MarkdownBuilder {
content.forEach(content -> res.append(content).append(" \n"));
return res.toString();
}
}

View File

@@ -7,21 +7,20 @@ import java.util.Map;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/17 21:57
* 修改parameterMap
* @date 2019/10/17 21:57 修改parameterMap
*/
public class ModifyParamMapRequestWrapper extends HttpServletRequestWrapper {
private final Map<String, String[]> parameterMap;
private final Map<String, String[]> parameterMap;
public ModifyParamMapRequestWrapper(HttpServletRequest request, Map<String, String[]> parameterMap) {
super(request);
this.parameterMap = parameterMap;
}
public ModifyParamMapRequestWrapper(HttpServletRequest request, Map<String, String[]> parameterMap) {
super(request);
this.parameterMap = parameterMap;
}
@Override
public Map<String, String[]> getParameterMap() {
return this.parameterMap;
}
@Override
public Map<String, String[]> getParameterMap() {
return this.parameterMap;
}
}

View File

@@ -16,56 +16,57 @@ import java.io.InputStreamReader;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/16 10:14
* Request包装类
* 1. body重复读取
* @date 2019/10/16 10:14 Request包装类 1. body重复读取
*/
@Slf4j
public class RepeatBodyRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
public RepeatBodyRequestWrapper(HttpServletRequest request) {
super(request);
this.body = getByteBody(request);
}
private final byte[] body;
@Override
public BufferedReader getReader() {
return ObjectUtils.isEmpty(body) ? null
: new BufferedReader(new InputStreamReader(getInputStream()));
}
public RepeatBodyRequestWrapper(HttpServletRequest request) {
super(request);
this.body = getByteBody(request);
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public BufferedReader getReader() {
return ObjectUtils.isEmpty(body) ? null : new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public boolean isReady() {
return false;
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {}
@Override
public boolean isReady() {
return false;
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
private static byte[] getByteBody(HttpServletRequest request) {
byte[] body = new byte[0];
try {
body = StreamUtils.copyToByteArray(request.getInputStream());
}
catch (IOException e) {
log.error("解析流中数据异常", e);
}
return body;
}
private static byte[] getByteBody(HttpServletRequest request) {
byte[] body = new byte[0];
try {
body = StreamUtils.copyToByteArray(request.getInputStream());
} catch (IOException e) {
log.error("解析流中数据异常", e);
}
return body;
}
}

View File

@@ -11,81 +11,77 @@ import java.util.Map;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/16 10:29
* Request包装类
* 1. XSS过滤
* @date 2019/10/16 10:29 Request包装类 1. XSS过滤
*/
@Slf4j
public class XSSRequestWrapper extends HttpServletRequestWrapper {
public XSSRequestWrapper(HttpServletRequest request) {
super(request);
}
public XSSRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String,String[]> map = new LinkedHashMap<>();
Map<String,String[]> parameters = super.getParameterMap();
for (String key : parameters.keySet()) {
String[] values = parameters.get(key);
for (int i = 0; i < values.length; i++) {
values[i] = HtmlUtils.htmlEscape(values[i]);
}
map.put(key, values);
}
return map;
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map = new LinkedHashMap<>();
Map<String, String[]> parameters = super.getParameterMap();
for (String key : parameters.keySet()) {
String[] values = parameters.get(key);
for (int i = 0; i < values.length; i++) {
values[i] = HtmlUtils.htmlEscape(values[i]);
}
map.put(key, values);
}
return map;
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = HtmlUtils.htmlEscape(values[i]);
}
return encodedValues;
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = HtmlUtils.htmlEscape(values[i]);
}
return encodedValues;
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null) {
return null;
}
return HtmlUtils.htmlEscape(value);
}
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (value instanceof String) {
HtmlUtils.htmlEscape((String) value);
}
return value;
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null) {
return null;
}
return HtmlUtils.htmlEscape(value);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null) {
return null;
}
return HtmlUtils.htmlEscape(value);
}
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (value instanceof String) {
HtmlUtils.htmlEscape((String) value);
}
return value;
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null) {
return null;
}
return HtmlUtils.htmlEscape(value);
}
@Override
public String getQueryString() {
String value = super.getQueryString();
if (value == null) {
return null;
}
return HtmlUtils.htmlEscape(value);
}
@Override
public String getQueryString() {
String value = super.getQueryString();
if (value == null) {
return null;
}
return HtmlUtils.htmlEscape(value);
}
}

View File

@@ -11,31 +11,34 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public enum BaseResultCode implements ResultCode {
/**
* 数据库保存/更新异常
*/
UPDATE_DATABASE_ERROR(90001, "Update Database Error"),
/**
* 通用的逻辑校验异常
*/
LOGIC_CHECK_ERROR(90004, "Logic Check Error"),
/**
* 数据库保存/更新异常
*/
UPDATE_DATABASE_ERROR(90001, "Update Database Error"),
/**
* 恶意请求
*/
MALICIOUS_REQUEST(90005, "Malicious Request"),
/**
* 通用的逻辑校验异常
*/
LOGIC_CHECK_ERROR(90004, "Logic Check Error"),
/**
* 文件上传异常
*/
FILE_UPLOAD_ERROR(90006, "File Upload Error"),
/**
* 恶意请求
*/
MALICIOUS_REQUEST(90005, "Malicious Request"),
/**
* 未知异常
*/
UNKNOWN_ERROR(99999, "Unknown Error");
/**
* 文件上传异常
*/
FILE_UPLOAD_ERROR(90006, "File Upload Error"),
/**
* 未知异常
*/
UNKNOWN_ERROR(99999, "Unknown Error");
private final Integer code;
private final String message;
private final Integer code;
private final String message;
}

View File

@@ -21,47 +21,41 @@ import java.io.Serializable;
@Accessors(chain = true)
@ApiModel(value = "返回体结构")
public class R<T> implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "返回状态码")
private int code;
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "返回信息")
private String msg;
@ApiModelProperty(value = "返回状态码")
private int code;
@ApiModelProperty(value = "数据")
private T data;
@ApiModelProperty(value = "返回信息")
private String msg;
public static <T> R<T> ok() {
return ok(null);
}
@ApiModelProperty(value = "数据")
private T data;
public static <T> R<T> ok(T data) {
return new R<T>().setCode(SystemResultCode.SUCCESS.getCode())
.setData(data)
.setMsg(SystemResultCode.SUCCESS.getMessage());
}
public static <T> R<T> ok() {
return ok(null);
}
public static <T> R<T> ok(T data, String msg) {
return new R<T>().setCode(SystemResultCode.SUCCESS.getCode())
.setData(data)
.setMsg(msg);
}
public static <T> R<T> ok(T data) {
return new R<T>().setCode(SystemResultCode.SUCCESS.getCode()).setData(data)
.setMsg(SystemResultCode.SUCCESS.getMessage());
}
public static <T> R<T> ok(T data, String msg) {
return new R<T>().setCode(SystemResultCode.SUCCESS.getCode()).setData(data).setMsg(msg);
}
public static <T> R<T> failed(int code, String msg) {
return new R<T>().setCode(code)
.setMsg(msg);
}
public static <T> R<T> failed(int code, String msg) {
return new R<T>().setCode(code).setMsg(msg);
}
public static <T> R<T> failed(ResultCode failMsg) {
return new R<T>().setCode(failMsg.getCode())
.setMsg(failMsg.getMessage());
}
public static <T> R<T> failed(ResultCode failMsg) {
return new R<T>().setCode(failMsg.getCode()).setMsg(failMsg.getMessage());
}
public static <T> R<T> failed(ResultCode failMsg, String msg) {
return new R<T>().setCode(failMsg.getCode())
.setMsg(msg);
}
public static <T> R<T> failed(ResultCode failMsg, String msg) {
return new R<T>().setCode(failMsg.getCode()).setMsg(msg);
}
}

View File

@@ -7,15 +7,16 @@ package com.hccake.ballcat.common.core.result;
*/
public interface ResultCode {
/**
* 获取业务码
* @return 业务码
*/
Integer getCode();
/**
* 获取业务码
* @return 业务码
*/
Integer getCode();
/**
* 获取信息
* @return 返回结构体中的信息
*/
String getMessage();
/**
* 获取信息
* @return 返回结构体中的信息
*/
String getMessage();
}

View File

@@ -12,29 +12,30 @@ import lombok.Getter;
@AllArgsConstructor
public enum SystemResultCode implements ResultCode {
// ================ 基础部分,参考 HttpStatus =============
/**
* 成功
*/
SUCCESS(200,"Success"),
/**
* 参数错误
*/
BAD_REQUEST(400, "Bad Request"),
/**
* 未认证
*/
UNAUTHORIZED(401, "Unauthorized"),
/**
* 未授权
*/
FORBIDDEN(403, "Forbidden"),
/**
* 服务异常
*/
SERVER_ERROR(500, "Internal Server Error");
// ================ 基础部分,参考 HttpStatus =============
/**
* 成功
*/
SUCCESS(200, "Success"),
/**
* 参数错误
*/
BAD_REQUEST(400, "Bad Request"),
/**
* 未认证
*/
UNAUTHORIZED(401, "Unauthorized"),
/**
* 未授权
*/
FORBIDDEN(403, "Forbidden"),
/**
* 服务异常
*/
SERVER_ERROR(500, "Internal Server Error");
private final Integer code;
private final String message;
private final Integer code;
private final String message;
}

View File

@@ -10,125 +10,120 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* 抽象的线程类,主要用于汇聚详情数据
* 做一些基础的处理后
* 进行批量插入
* 抽象的线程类,主要用于汇聚详情数据 做一些基础的处理后 进行批量插入
*
* @author Hccake
*/
@Slf4j
public abstract class AbstractQueueThread<T> extends Thread implements InitializingBean {
private final BlockingQueue<T> queue = new LinkedBlockingQueue<T>();
private final static long DEFAULT_BATCH_SIZE = 100;
private final static long DEFAULT_BATCH_TIMEOUT = 30000;
public void putObject(T t) {
try {
if (t != null) {
queue.put(t);
}
} catch (Exception e) {
log.error("{} putObject error, param: {}", this.getClass().toString(), t, e);
}
}
private final BlockingQueue<T> queue = new LinkedBlockingQueue<T>();
public long getBatchSize() {
return DEFAULT_BATCH_SIZE;
}
private final static long DEFAULT_BATCH_SIZE = 100;
public long getBatchTimeout() {
return DEFAULT_BATCH_TIMEOUT;
}
private final static long DEFAULT_BATCH_TIMEOUT = 30000;
@Override
public void run() {
public void putObject(T t) {
try {
if (t != null) {
queue.put(t);
}
}
catch (Exception e) {
log.error("{} putObject error, param: {}", this.getClass().toString(), t, e);
}
}
startLog();
public long getBatchSize() {
return DEFAULT_BATCH_SIZE;
}
while (!isInterrupted()) {
List<T> list = new ArrayList<T>();
public long getBatchTimeout() {
return DEFAULT_BATCH_TIMEOUT;
}
try {
preProcessor();
@Override
public void run() {
long ts = 0;
int i = 0;
startLog();
while (i < getBatchSize()) {
T tmp = null;
try {
tmp = queue.poll(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tmp != null) {
//记录第一次添加数据后的时间
if (i++ == 0) {
ts = System.currentTimeMillis();
}
//处理
processor(list, tmp);
}
//有数据 且从第一次插入数据已经过了 设定时间 则 执行插入
if (list.size() > 0 && System.currentTimeMillis() - ts >= getBatchTimeout()) {
break;
}
}
while (!isInterrupted()) {
List<T> list = new ArrayList<T>();
save(list);
} catch (Throwable e) {
errorLog(e, list);
}
}
}
try {
preProcessor();
private void preProcessor() {
long ts = 0;
int i = 0;
}
while (i < getBatchSize()) {
T tmp = null;
try {
tmp = queue.poll(5000, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
e.printStackTrace();
}
if (tmp != null) {
// 记录第一次添加数据后的时间
if (i++ == 0) {
ts = System.currentTimeMillis();
}
// 处理
processor(list, tmp);
}
// 有数据 且从第一次插入数据已经过了 设定时间 则 执行插入
if (list.size() > 0 && System.currentTimeMillis() - ts >= getBatchTimeout()) {
break;
}
}
save(list);
}
catch (Throwable e) {
errorLog(e, list);
}
}
}
/**
* 线程启动时的日志打印
*/
public abstract void startLog();
private void preProcessor() {
}
/**
* 错误日志打印
*
* @param e
* @param list
*/
public abstract void errorLog(Throwable e, List<T> list);
/**
* 线程启动时的日志打印
*/
public abstract void startLog();
/**
* 错误日志打印
* @param e
* @param list
*/
public abstract void errorLog(Throwable e, List<T> list);
/**
* 数据处理
*
* @param list
* @param elem
*/
public void processor(List<T> list, T elem) {
list.add(elem);
}
/**
* 数据处理
* @param list
* @param elem
*/
public void processor(List<T> list, T elem) {
list.add(elem);
}
/**
* 数据保存
* @param list
*/
public abstract void save(List<T> list) throws Exception;
/**
* 数据保存
*
* @param list
*/
public abstract void save(List<T> list) throws Exception;
/**
* 初始化后启动
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() {
this.start();
}
/**
* 初始化后启动
* @throws Exception
*/
@Override
public void afterPropertiesSet() {
this.start();
}
}

View File

@@ -10,17 +10,21 @@ import java.util.List;
* @date 2020/6/21 17:08
*/
@Data
public class SimpleTreeNode<T> implements TreeNode<T>{
public class SimpleTreeNode<T> implements TreeNode<T> {
/**
* 节点ID
*/
private T id;
/**
* 父节点ID
*/
private T parentId;
/**
* 子节点集合
*/
private List<? extends TreeNode<T>> children;
}

View File

@@ -8,31 +8,29 @@ import java.util.List;
* @date 2020/6/21 17:05
*/
public interface TreeNode<T> {
/**
* 获取节点id
*
* @return 树节点id
*/
T getId();
/**
* 获取该节点的父节点id
*
* @return 父节点id
*/
T getParentId();
/**
* 设置节点的子节点列表
*
* @param children 子节点
*/
void setChildren(List<? extends TreeNode<T>> children);
/**
* 获取所有子节点
*
* @return 子节点列表
*/
List<? extends TreeNode<T>> getChildren();
}

View File

@@ -7,10 +7,11 @@ import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
/**
* @author lingting 2020/6/12 16:36
* @author lingting 2020/6/12 16:36
*/
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
@@ -18,11 +19,10 @@ public class ApplicationContextUtil implements ApplicationContextAware {
context = applicationContext;
}
/**
* 获取环境
*
* @author lingting 2020-06-12 16:38:56
* @author lingting 2020-06-12 16:38:56
*/
public Environment getEnvironment() {
return context.getEnvironment();
@@ -31,4 +31,5 @@ public class ApplicationContextUtil implements ApplicationContextAware {
public ApplicationContext getContext() {
return context;
}
}

View File

@@ -7,21 +7,18 @@ import javax.servlet.http.HttpServletRequest;
/**
* IP 工具类
*
* @author Hccake
*/
public class IPUtil {
/**
* 如果在前端和服务端中间还有一层Node服务
* 在Node对前端数据进行处理并发起新请求时需携带此头部信息
* 便于获取真实IP
* 如果在前端和服务端中间还有一层Node服务 在Node对前端数据进行处理并发起新请求时需携带此头部信息 便于获取真实IP
*/
public static final String NODE_FORWARDED_IP = "Node-Forwarded-IP";
/**
* 获取客户端IP
* 获取客户端IP
*/
public static String getIpAddr(HttpServletRequest request) {
return getIpAddr(request, NODE_FORWARDED_IP);
@@ -33,7 +30,8 @@ public class IPUtil {
* 参考 huTool 稍微调整了下headers 顺序
*/
public static String getIpAddr(HttpServletRequest request, String... otherHeaderNames) {
String[] headers = {"X-Real-IP", "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR" };
String[] headers = { "X-Real-IP", "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP",
"HTTP_X_FORWARDED_FOR" };
if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
headers = ArrayUtil.addAll(headers, otherHeaderNames);
}

View File

@@ -18,52 +18,45 @@ import java.nio.charset.StandardCharsets;
*/
public class PasswordUtil {
public static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
public static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
public static String decodeAesAndEncodeBCrypt(String pass, String secretKey){
return encodeBCrypt(decodeAES(pass, secretKey));
}
public static String decodeAesAndEncodeBCrypt(String pass, String secretKey) {
return encodeBCrypt(decodeAES(pass, secretKey));
}
public static String decodeAES(String aesPass, String secretKey) {
public static String decodeAES(String aesPass, String secretKey){
AES aes = new AES(Mode.CBC, Padding.NoPadding, new SecretKeySpec(secretKey.getBytes(), "AES"),
new IvParameterSpec(secretKey.getBytes()));
byte[] result = aes.decrypt(Base64.decode(aesPass.getBytes(StandardCharsets.UTF_8)));
// 删除byte数组中补位产生的\u0000, 否则密码校验时会有问题
return new String(result, StandardCharsets.UTF_8).replaceAll("[\u0000]", "");
}
AES aes = new AES(Mode.CBC, Padding.NoPadding,
new SecretKeySpec(secretKey.getBytes(), "AES"),
new IvParameterSpec(secretKey.getBytes()));
byte[] result = aes.decrypt(Base64.decode(aesPass.getBytes(StandardCharsets.UTF_8)));
// 删除byte数组中补位产生的\u0000, 否则密码校验时会有问题
return new String(result, StandardCharsets.UTF_8).replaceAll("[\u0000]", "");
}
public static String encodeAESBase64(String pass, String secretKey) {
AES aes = new AES(Mode.CBC, Padding.NoPadding, new SecretKeySpec(secretKey.getBytes(), "AES"),
new IvParameterSpec(secretKey.getBytes()));
return aes.encryptBase64(pass, StandardCharsets.UTF_8);
}
public static String encodeBCrypt(String pass) {
return ENCODER.encode(pass);
}
public static String encodeAESBase64(String pass, String secretKey){
AES aes = new AES(Mode.CBC, Padding.NoPadding,
new SecretKeySpec(secretKey.getBytes(), "AES"),
new IvParameterSpec(secretKey.getBytes()));
return aes.encryptBase64(pass, StandardCharsets.UTF_8);
}
public static void main(String[] args) {
System.out.println(decodeAES("4Yj0Jfy+MjEW/RGafIoEJA==", "==BallCat-Auth=="));
;
public static String encodeBCrypt(String pass){
return ENCODER.encode(pass);
}
String pass = "a123456";
String password = ENCODER.encode(pass);
System.out.println(password);
public static void main(String[] args) {
System.out.println(ENCODER.matches(pass, password));
System.out.println(decodeAES("4Yj0Jfy+MjEW/RGafIoEJA==","==BallCat-Auth=="));;
System.out.println(ENCODER.matches(pass, "$2a$10$YJDXeAsk7FjQQVTdutIat.rPR3p3uUPWmZyhtnRDOrIjPujOAUrla"));
String pass = "a123456";
String password = ENCODER.encode(pass);
System.out.println(password);
System.out.println(ENCODER.matches(pass,password));
System.out.println(ENCODER.matches(pass,"$2a$10$YJDXeAsk7FjQQVTdutIat.rPR3p3uUPWmZyhtnRDOrIjPujOAUrla"));
}
}
}

View File

@@ -22,7 +22,7 @@ public class TreeUtil {
/**
* 根据一个TreeNode集合返回构建好的树列表
* @param nodes TreeNode集合
* @param rootId 根节点Id
* @param rootId 根节点Id
* @param <T> TreeNode的子类
* @param <I> TreeNodeId的类型
* @return 树列表
@@ -44,7 +44,7 @@ public class TreeUtil {
public <T extends TreeNode<I>, I, R> List<T> buildTree(List<R> list, I rootId, Function<R, T> convertToTree) {
List<T> roots = new ArrayList<>();
for (Iterator<R> ite = list.iterator(); ite.hasNext(); ) {
for (Iterator<R> ite = list.iterator(); ite.hasNext();) {
T node = convertToTree.apply(ite.next());
if (Objects.equals(rootId, node.getParentId())) {
roots.add(node);
@@ -58,17 +58,15 @@ public class TreeUtil {
return roots;
}
/**
* 从所有节点列表中查找并设置parent的所有子节点
*
* @param parent 父节点
* @param nodes 所有树节点列表
* @param nodes 所有树节点列表
*/
public <T extends TreeNode<I>, I, R> void setChildren(T parent, List<R> nodes, Function<R, T> convertToTree) {
List<T> children = new ArrayList<>();
Object parentId = parent.getId();
for (Iterator<R> ite = nodes.iterator(); ite.hasNext(); ) {
for (Iterator<R> ite = nodes.iterator(); ite.hasNext();) {
T node = convertToTree.apply(ite.next());
if (Objects.equals(node.getParentId(), parentId)) {
children.add(node);
@@ -87,12 +85,10 @@ public class TreeUtil {
});
}
/**
* 获取指定树节点下的所有叶子节点
*
* @param parent 父节点
* @param <T> 实际节点类型
* @param <T> 实际节点类型
* @return 叶子节点
*/
public <T extends TreeNode<?>> List<T> getLeafs(T parent) {
@@ -103,10 +99,9 @@ public class TreeUtil {
/**
* 将parent的所有叶子节点填充至leafs列表中
*
* @param parent 父节点
* @param leafs 叶子节点列表
* @param <T> 实际节点类型
* @param leafs 叶子节点列表
* @param <T> 实际节点类型
*/
@SuppressWarnings("rawtypes, unchecked")
public <T extends TreeNode> void fillLeaf(T parent, List<T> leafs) {
@@ -150,11 +145,10 @@ public class TreeUtil {
for (T treeNode : treeList) {
ids.add(treeNode.getId());
List<? extends TreeNode<I>> children = treeNode.getChildren();
if(CollectionUtil.isNotEmpty(children)){
if (CollectionUtil.isNotEmpty(children)) {
fillTreeNodeIds(ids, children);
}
}
}
}

View File

@@ -6,38 +6,40 @@ import java.util.Map;
/**
* 下拉框所对应的视图类
*
* @author Hccake
*/
@Data
public class SelectData <T> {
public class SelectData<T> {
/**
* 显示的数据
*/
private String name;
/**
* 显示的数据
*/
private String name;
/**
* 选中获取的属性
*/
private String value;
/**
* 选中获取的属性
*/
private String value;
/**
* 是否被选中
*/
private String selected;
/**
* 是否被选中
*/
private String selected;
/**
* 是否禁用
*/
private String disabled;
/**
* 是否禁用
*/
private String disabled;
/**
* 分组标识
*/
private String type;
/**
* 分组标识
*/
private String type;
/**
* 扩展对象
*/
private T extendObj;
/**
* 扩展对象
*/
private T extendObj;
}