🎨 引入spring-java-format插件,代码格式管理
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
// 判断字段的类型,如果是array,list,set则注册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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user