马府强
2 years ago
34 changed files with 1466 additions and 0 deletions
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |
||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> |
||||
|
<output url="file://$MODULE_DIR$/target/classes" /> |
||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" /> |
||||
|
<content url="file://$MODULE_DIR$"> |
||||
|
<excludeFolder url="file://$MODULE_DIR$/target" /> |
||||
|
</content> |
||||
|
<orderEntry type="inheritedJdk" /> |
||||
|
<orderEntry type="sourceFolder" forTests="false" /> |
||||
|
</component> |
||||
|
</module> |
@ -0,0 +1,62 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |
||||
|
<component name="FacetManager"> |
||||
|
<facet type="Spring" name="Spring"> |
||||
|
<configuration /> |
||||
|
</facet> |
||||
|
<facet type="web" name="Web"> |
||||
|
<configuration> |
||||
|
<webroots /> |
||||
|
</configuration> |
||||
|
</facet> |
||||
|
</component> |
||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> |
||||
|
<output url="file://$MODULE_DIR$/target/classes" /> |
||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" /> |
||||
|
<content url="file://$MODULE_DIR$"> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |
||||
|
<excludeFolder url="file://$MODULE_DIR$/target" /> |
||||
|
</content> |
||||
|
<orderEntry type="inheritedJdk" /> |
||||
|
<orderEntry type="sourceFolder" forTests="false" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.10" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.10" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.33" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.33" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.0.Final" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.22" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: commons-io:commons-io:1.3.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.15" level="project" /> |
||||
|
</component> |
||||
|
</module> |
@ -0,0 +1,40 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<parent> |
||||
|
<artifactId>spring-boot-interface-crypto</artifactId> |
||||
|
<groupId>xyz.hlh</groupId> |
||||
|
<version>1.0-SNAPSHOT</version> |
||||
|
</parent> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<artifactId>crypto-common</artifactId> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||
|
</properties> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-validation</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.projectlombok</groupId> |
||||
|
<artifactId>lombok</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.commons</groupId> |
||||
|
<artifactId>commons-io</artifactId> |
||||
|
<version>1.3.2</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||
|
<optional>true</optional> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
|
||||
|
</project> |
@ -0,0 +1,27 @@ |
|||||
|
package xyz.hlh.crypto.common.entity; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.Builder; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import lombok.NoArgsConstructor; |
||||
|
import org.springframework.http.HttpStatus; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description 统一的返回结果 |
||||
|
*/ |
||||
|
@Data |
||||
|
@NoArgsConstructor |
||||
|
@AllArgsConstructor |
||||
|
@EqualsAndHashCode |
||||
|
@Builder |
||||
|
public class Result<T> { |
||||
|
|
||||
|
@Builder.Default |
||||
|
private int status = HttpStatus.OK.value(); |
||||
|
private T data; |
||||
|
@Builder.Default |
||||
|
private String message = "成功"; |
||||
|
|
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
package xyz.hlh.crypto.common.entity; |
||||
|
|
||||
|
import org.springframework.http.HttpStatus; |
||||
|
import org.springframework.http.ResponseEntity; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description 返回值构造 |
||||
|
*/ |
||||
|
public interface ResultBuilder { |
||||
|
|
||||
|
/** |
||||
|
* 成功的构造 |
||||
|
* @param data 数据 |
||||
|
* @return Result |
||||
|
*/ |
||||
|
default ResponseEntity<Result<?>> success(Object data) { |
||||
|
return ResponseEntity.ok(Result.builder() |
||||
|
.status(HttpStatus.OK.value()).data(data) |
||||
|
.build()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 400的构造 |
||||
|
* @param errorMsg 错误信息 |
||||
|
* @return Result |
||||
|
*/ |
||||
|
default ResponseEntity<Result<?>> badRequest(String errorMsg) { |
||||
|
return ResponseEntity.badRequest().body(Result.builder() |
||||
|
.status(HttpStatus.BAD_REQUEST.value()) |
||||
|
.message(errorMsg) |
||||
|
.build()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 404的构造 |
||||
|
* @param errorMsg 错误信息 |
||||
|
* @return Result |
||||
|
*/ |
||||
|
default ResponseEntity<Result<?>> notFound(String errorMsg) { |
||||
|
return ResponseEntity |
||||
|
.status(HttpStatus.NOT_FOUND.value()) |
||||
|
.body(Result.builder() |
||||
|
.status(HttpStatus.NOT_FOUND.value()) |
||||
|
.message(errorMsg) |
||||
|
.build()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 500的构造 |
||||
|
* @param errorMsg 错误信息 |
||||
|
* @return Result |
||||
|
*/ |
||||
|
default ResponseEntity<Result<?>> internalServerError(String errorMsg) { |
||||
|
return ResponseEntity |
||||
|
.status(HttpStatus.INTERNAL_SERVER_ERROR.value()) |
||||
|
.body(Result.builder() |
||||
|
.status(HttpStatus.INTERNAL_SERVER_ERROR.value()) |
||||
|
.message(errorMsg) |
||||
|
.build()); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package xyz.hlh.crypto.common.exception; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: 自定义异常 |
||||
|
*/ |
||||
|
public class CryptoException extends CustomizeException { |
||||
|
|
||||
|
public CryptoException(String message, Throwable cause) { |
||||
|
super(message, cause); |
||||
|
} |
||||
|
|
||||
|
public CryptoException(String message) { |
||||
|
super(message); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package xyz.hlh.crypto.common.exception; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: 自定义异常 |
||||
|
*/ |
||||
|
public class CustomizeException extends Exception { |
||||
|
|
||||
|
public CustomizeException(String message, Throwable cause) { |
||||
|
super(message, cause); |
||||
|
} |
||||
|
|
||||
|
public CustomizeException(String message) { |
||||
|
super(message); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,61 @@ |
|||||
|
package xyz.hlh.crypto.common.exception; |
||||
|
|
||||
|
import org.springframework.http.ResponseEntity; |
||||
|
import org.springframework.validation.BindException; |
||||
|
import org.springframework.validation.FieldError; |
||||
|
import org.springframework.web.bind.annotation.ExceptionHandler; |
||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice; |
||||
|
import xyz.hlh.crypto.common.entity.Result; |
||||
|
import xyz.hlh.crypto.common.entity.ResultBuilder; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description 统一异常处理类 |
||||
|
*/ |
||||
|
@RestControllerAdvice // 返回json
|
||||
|
public class GlobExceptionHandler implements ResultBuilder { |
||||
|
|
||||
|
@ExceptionHandler(value = BindException.class) |
||||
|
public ResponseEntity<Result<?>> bindExceptionHandler(BindException ex) { |
||||
|
ex.printStackTrace(); |
||||
|
// 获取所有错误信息,拼接
|
||||
|
List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors(); |
||||
|
String errorMsg = fieldErrors.stream() |
||||
|
.map(fieldError -> fieldError.getField() + ":" + fieldError.getDefaultMessage()) |
||||
|
.collect(Collectors.joining(",")); |
||||
|
// 返回统一处理类
|
||||
|
return badRequest(errorMsg); |
||||
|
} |
||||
|
|
||||
|
@ExceptionHandler(value = ParamException.class) |
||||
|
public ResponseEntity<Result<?>> paramExceptionHandler(ParamException ex) { |
||||
|
ex.printStackTrace(); |
||||
|
// 返回统一处理类
|
||||
|
return badRequest(ex.getMessage()); |
||||
|
} |
||||
|
|
||||
|
@ExceptionHandler(value = CryptoException.class) |
||||
|
public ResponseEntity<Result<?>> cryptoExceptionHandler(CryptoException ex) { |
||||
|
ex.printStackTrace(); |
||||
|
// 返回统一处理类
|
||||
|
return internalServerError(ex.getMessage()); |
||||
|
} |
||||
|
|
||||
|
@ExceptionHandler(value = CustomizeException.class) |
||||
|
public ResponseEntity<Result<?>> customizeExceptionHanlder(CustomizeException ex) { |
||||
|
ex.printStackTrace(); |
||||
|
// 返回统一处理类
|
||||
|
return internalServerError(ex.getMessage()); |
||||
|
} |
||||
|
|
||||
|
@ExceptionHandler(value = Exception.class) |
||||
|
public ResponseEntity<Result<?>> exceptionHanlder(Exception ex) { |
||||
|
ex.printStackTrace(); |
||||
|
// 返回统一处理类
|
||||
|
return internalServerError(ex.getMessage()); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,57 @@ |
|||||
|
package xyz.hlh.crypto.common.exception; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import org.springframework.util.CollectionUtils; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description 自定义参数异常 |
||||
|
*/ |
||||
|
@Getter |
||||
|
public class ParamException extends CustomizeException { |
||||
|
|
||||
|
private List<String> fieldList; |
||||
|
private List<String> msgList; |
||||
|
|
||||
|
public ParamException(String message) { |
||||
|
super(message); |
||||
|
} |
||||
|
|
||||
|
public ParamException(String message, Throwable cause) { |
||||
|
super(message, cause); |
||||
|
} |
||||
|
|
||||
|
public ParamException(List<String> fieldList, List<String> msgList) throws CustomizeException { |
||||
|
super(generatorMessage(fieldList, msgList)); |
||||
|
this.fieldList = fieldList; |
||||
|
this.msgList = msgList; |
||||
|
} |
||||
|
|
||||
|
public ParamException(List<String> fieldList, List<String> msgList, Exception ex) throws CustomizeException { |
||||
|
super(generatorMessage(fieldList, msgList), ex); |
||||
|
this.fieldList = fieldList; |
||||
|
this.msgList = msgList; |
||||
|
} |
||||
|
|
||||
|
private static String generatorMessage(List<String> fieldList, List<String> msgList) throws CustomizeException { |
||||
|
if (CollectionUtils.isEmpty(fieldList) || CollectionUtils.isEmpty(msgList) || fieldList.size() != msgList.size()) { |
||||
|
return "参数错误"; |
||||
|
} |
||||
|
|
||||
|
StringBuilder message = new StringBuilder(); |
||||
|
for (int i = 0; i < fieldList.size(); i++) { |
||||
|
String field = fieldList.get(i); |
||||
|
String msg = msgList.get(i); |
||||
|
if (i == fieldList.size() - 1) { |
||||
|
message.append(field).append(":").append(msg); |
||||
|
} else { |
||||
|
message.append(field).append(":").append(msg).append(","); |
||||
|
} |
||||
|
} |
||||
|
return message.toString(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
package xyz.hlh.crypto.common.filter; |
||||
|
|
||||
|
import org.springframework.core.Ordered; |
||||
|
import org.springframework.core.annotation.Order; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import xyz.hlh.crypto.common.utils.InputStreamHttpServletRequestWrapper; |
||||
|
|
||||
|
import javax.servlet.Filter; |
||||
|
import javax.servlet.FilterChain; |
||||
|
import javax.servlet.ServletException; |
||||
|
import javax.servlet.ServletRequest; |
||||
|
import javax.servlet.ServletResponse; |
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import java.io.IOException; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: |
||||
|
* 请求流转换为多次读取的请求流 过滤器 |
||||
|
*/ |
||||
|
@Component |
||||
|
@Order(Ordered.HIGHEST_PRECEDENCE + 1) // 优先级最高
|
||||
|
public class HttpServletRequestInputStreamFilter implements Filter { |
||||
|
|
||||
|
@Override |
||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
||||
|
|
||||
|
// 转换为可以多次获取流的request
|
||||
|
HttpServletRequest httpServletRequest = (HttpServletRequest) request; |
||||
|
InputStreamHttpServletRequestWrapper inputStreamHttpServletRequestWrapper = new InputStreamHttpServletRequestWrapper(httpServletRequest); |
||||
|
|
||||
|
// 放行
|
||||
|
chain.doFilter(inputStreamHttpServletRequestWrapper, response); |
||||
|
} |
||||
|
} |
@ -0,0 +1,89 @@ |
|||||
|
package xyz.hlh.crypto.common.utils; |
||||
|
|
||||
|
import org.apache.commons.io.IOUtils; |
||||
|
|
||||
|
import javax.servlet.ReadListener; |
||||
|
import javax.servlet.ServletInputStream; |
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import javax.servlet.http.HttpServletRequestWrapper; |
||||
|
import java.io.BufferedReader; |
||||
|
import java.io.ByteArrayInputStream; |
||||
|
import java.io.ByteArrayOutputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.io.InputStreamReader; |
||||
|
|
||||
|
/** |
||||
|
* 请求流支持多次获取 |
||||
|
*/ |
||||
|
public class InputStreamHttpServletRequestWrapper extends HttpServletRequestWrapper { |
||||
|
|
||||
|
/** |
||||
|
* 用于缓存输入流 |
||||
|
*/ |
||||
|
private ByteArrayOutputStream cachedBytes; |
||||
|
|
||||
|
public InputStreamHttpServletRequestWrapper(HttpServletRequest request) { |
||||
|
super(request); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ServletInputStream getInputStream() throws IOException { |
||||
|
if (cachedBytes == null) { |
||||
|
// 首次获取流时,将流放入 缓存输入流 中
|
||||
|
cacheInputStream(); |
||||
|
} |
||||
|
|
||||
|
// 从 缓存输入流 中获取流并返回
|
||||
|
return new CachedServletInputStream(cachedBytes.toByteArray()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public BufferedReader getReader() throws IOException { |
||||
|
return new BufferedReader(new InputStreamReader(getInputStream())); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 首次获取流时,将流放入 缓存输入流 中 |
||||
|
*/ |
||||
|
private void cacheInputStream() throws IOException { |
||||
|
// 缓存输入流以便多次读取。为了方便, 我使用 org.apache.commons IOUtils
|
||||
|
cachedBytes = new ByteArrayOutputStream(); |
||||
|
IOUtils.copy(super.getInputStream(), cachedBytes); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 读取缓存的请求正文的输入流 |
||||
|
* <p> |
||||
|
* 用于根据 缓存输入流 创建一个可返回的 |
||||
|
*/ |
||||
|
public static class CachedServletInputStream extends ServletInputStream { |
||||
|
|
||||
|
private final ByteArrayInputStream input; |
||||
|
|
||||
|
public CachedServletInputStream(byte[] buf) { |
||||
|
// 从缓存的请求正文创建一个新的输入流
|
||||
|
input = new ByteArrayInputStream(buf); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isFinished() { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isReady() { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void setReadListener(ReadListener listener) { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int read() throws IOException { |
||||
|
return input.read(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,91 @@ |
|||||
|
package xyz.hlh.crypto.common.utils; |
||||
|
|
||||
|
import xyz.hlh.crypto.common.exception.CustomizeException; |
||||
|
import xyz.hlh.crypto.common.exception.ParamException; |
||||
|
|
||||
|
import javax.validation.ConstraintViolation; |
||||
|
import javax.validation.Validation; |
||||
|
import javax.validation.Validator; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.List; |
||||
|
import java.util.Set; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description 验证工具类 |
||||
|
*/ |
||||
|
public class ValidationUtils { |
||||
|
|
||||
|
private static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator(); |
||||
|
|
||||
|
/** |
||||
|
* 验证数据 |
||||
|
* @param object 数据 |
||||
|
*/ |
||||
|
public static void validate(Object object) throws CustomizeException { |
||||
|
|
||||
|
Set<ConstraintViolation<Object>> validate = VALIDATOR.validate(object); |
||||
|
|
||||
|
// 验证结果异常
|
||||
|
throwParamException(validate); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证数据(分组) |
||||
|
* @param object 数据 |
||||
|
* @param groups 所在组 |
||||
|
*/ |
||||
|
public static void validate(Object object, Class<?> ... groups) throws CustomizeException { |
||||
|
|
||||
|
Set<ConstraintViolation<Object>> validate = VALIDATOR.validate(object, groups); |
||||
|
|
||||
|
// 验证结果异常
|
||||
|
throwParamException(validate); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证数据中的某个字段(分组) |
||||
|
* @param object 数据 |
||||
|
* @param propertyName 字段名称 |
||||
|
*/ |
||||
|
public static void validate(Object object, String propertyName) throws CustomizeException { |
||||
|
Set<ConstraintViolation<Object>> validate = VALIDATOR.validateProperty(object, propertyName); |
||||
|
|
||||
|
// 验证结果异常
|
||||
|
throwParamException(validate); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证数据中的某个字段(分组) |
||||
|
* @param object 数据 |
||||
|
* @param propertyName 字段名称 |
||||
|
* @param groups 所在组 |
||||
|
*/ |
||||
|
public static void validate(Object object, String propertyName, Class<?> ... groups) throws CustomizeException { |
||||
|
|
||||
|
Set<ConstraintViolation<Object>> validate = VALIDATOR.validateProperty(object, propertyName, groups); |
||||
|
|
||||
|
// 验证结果异常
|
||||
|
throwParamException(validate); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证结果异常 |
||||
|
* @param validate 验证结果 |
||||
|
*/ |
||||
|
private static void throwParamException(Set<ConstraintViolation<Object>> validate) throws CustomizeException { |
||||
|
if (validate.size() > 0) { |
||||
|
List<String> fieldList = new LinkedList<>(); |
||||
|
List<String> msgList = new LinkedList<>(); |
||||
|
for (ConstraintViolation<Object> next : validate) { |
||||
|
fieldList.add(next.getPropertyPath().toString()); |
||||
|
msgList.add(next.getMessage()); |
||||
|
} |
||||
|
|
||||
|
throw new ParamException(fieldList, msgList); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |
||||
|
<component name="FacetManager"> |
||||
|
<facet type="Spring" name="Spring"> |
||||
|
<configuration /> |
||||
|
</facet> |
||||
|
<facet type="web" name="Web"> |
||||
|
<configuration> |
||||
|
<webroots /> |
||||
|
</configuration> |
||||
|
</facet> |
||||
|
</component> |
||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> |
||||
|
<output url="file://$MODULE_DIR$/target/classes" /> |
||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" /> |
||||
|
<content url="file://$MODULE_DIR$"> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> |
||||
|
<excludeFolder url="file://$MODULE_DIR$/target" /> |
||||
|
</content> |
||||
|
<orderEntry type="inheritedJdk" /> |
||||
|
<orderEntry type="sourceFolder" forTests="false" /> |
||||
|
<orderEntry type="module" module-name="crypto-common" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.0.Final" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.22" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: commons-io:commons-io:1.3.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.20" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.10" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.10" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.33" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.33" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" /> |
||||
|
</component> |
||||
|
</module> |
@ -0,0 +1,45 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<parent> |
||||
|
<artifactId>spring-boot-interface-crypto</artifactId> |
||||
|
<groupId>xyz.hlh</groupId> |
||||
|
<version>1.0-SNAPSHOT</version> |
||||
|
</parent> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<artifactId>cry-spring-boot-starter</artifactId> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||
|
</properties> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>xyz.hlh</groupId> |
||||
|
<artifactId>crypto-common</artifactId> |
||||
|
<version>1.0-SNAPSHOT</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-all</artifactId> |
||||
|
<version>5.7.20</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||
|
<optional>true</optional> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.apache.commons</groupId> |
||||
|
<artifactId>commons-lang3</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
</dependencies> |
||||
|
|
||||
|
</project> |
@ -0,0 +1,146 @@ |
|||||
|
package xyz.hlh.crypto.advice; |
||||
|
|
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import lombok.SneakyThrows; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.core.MethodParameter; |
||||
|
import org.springframework.http.HttpInputMessage; |
||||
|
import org.springframework.http.converter.HttpMessageConverter; |
||||
|
import org.springframework.web.bind.annotation.ControllerAdvice; |
||||
|
import org.springframework.web.context.request.RequestAttributes; |
||||
|
import org.springframework.web.context.request.RequestContextHolder; |
||||
|
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; |
||||
|
import xyz.hlh.crypto.annotation.DecryptionAnnotation; |
||||
|
import xyz.hlh.crypto.common.exception.ParamException; |
||||
|
import xyz.hlh.crypto.constant.CryptoConstant; |
||||
|
import xyz.hlh.crypto.entity.RequestBase; |
||||
|
import xyz.hlh.crypto.entity.RequestData; |
||||
|
import xyz.hlh.crypto.util.AESUtil; |
||||
|
|
||||
|
import javax.servlet.ServletInputStream; |
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import java.io.IOException; |
||||
|
import java.lang.reflect.Type; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: requestBody 自动解密 |
||||
|
*/ |
||||
|
@ControllerAdvice |
||||
|
public class DecryptRequestBodyAdvice implements RequestBodyAdvice { |
||||
|
|
||||
|
@Autowired |
||||
|
private ObjectMapper objectMapper; |
||||
|
|
||||
|
/** |
||||
|
* 方法上有DecryptionAnnotation注解的,进入此拦截器 |
||||
|
* @param methodParameter 方法参数对象 |
||||
|
* @param targetType 参数的类型 |
||||
|
* @param converterType 消息转换器 |
||||
|
* @return true,进入,false,跳过 |
||||
|
*/ |
||||
|
@Override |
||||
|
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { |
||||
|
return methodParameter.hasMethodAnnotation(DecryptionAnnotation.class); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException { |
||||
|
return inputMessage; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 转换之后,执行此方法,解密,赋值 |
||||
|
* @param body spring解析完的参数 |
||||
|
* @param inputMessage 输入参数 |
||||
|
* @param parameter 参数对象 |
||||
|
* @param targetType 参数类型 |
||||
|
* @param converterType 消息转换类型 |
||||
|
* @return 真实的参数 |
||||
|
*/ |
||||
|
@SneakyThrows |
||||
|
@Override |
||||
|
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { |
||||
|
|
||||
|
// 获取request
|
||||
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); |
||||
|
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; |
||||
|
if (servletRequestAttributes == null) { |
||||
|
throw new ParamException("request错误"); |
||||
|
} |
||||
|
|
||||
|
HttpServletRequest request = servletRequestAttributes.getRequest(); |
||||
|
|
||||
|
// 获取数据
|
||||
|
ServletInputStream inputStream = request.getInputStream(); |
||||
|
RequestData requestData = objectMapper.readValue(inputStream, RequestData.class); |
||||
|
|
||||
|
if (requestData == null || StringUtils.isBlank(requestData.getText())) { |
||||
|
throw new ParamException("参数错误"); |
||||
|
} |
||||
|
|
||||
|
// 获取加密的数据
|
||||
|
String text = requestData.getText(); |
||||
|
|
||||
|
// 放入解密之前的数据
|
||||
|
request.setAttribute(CryptoConstant.INPUT_ORIGINAL_DATA, text); |
||||
|
|
||||
|
// 解密
|
||||
|
String decryptText = null; |
||||
|
try { |
||||
|
decryptText = AESUtil.decrypt(text); |
||||
|
} catch (Exception e) { |
||||
|
throw new ParamException("解密失败"); |
||||
|
} |
||||
|
|
||||
|
if (StringUtils.isBlank(decryptText)) { |
||||
|
throw new ParamException("解密失败"); |
||||
|
} |
||||
|
|
||||
|
// 放入解密之后的数据
|
||||
|
request.setAttribute(CryptoConstant.INPUT_DECRYPT_DATA, decryptText); |
||||
|
|
||||
|
// 获取结果
|
||||
|
Object result = objectMapper.readValue(decryptText, body.getClass()); |
||||
|
|
||||
|
// 强制所有实体类必须继承RequestBase类,设置时间戳
|
||||
|
if (result instanceof RequestBase) { |
||||
|
// 获取时间戳
|
||||
|
Long currentTimeMillis = ((RequestBase) result).getCurrentTimeMillis(); |
||||
|
// 有效期 60秒
|
||||
|
long effective = 60*1000; |
||||
|
|
||||
|
// 时间差
|
||||
|
long expire = System.currentTimeMillis() - currentTimeMillis; |
||||
|
|
||||
|
// 是否在有效期内
|
||||
|
if (Math.abs(expire) > effective) { |
||||
|
throw new ParamException("时间戳不合法"); |
||||
|
} |
||||
|
|
||||
|
// 返回解密之后的数据
|
||||
|
return result; |
||||
|
} else { |
||||
|
throw new ParamException(String.format("请求参数类型:%s 未继承:%s", result.getClass().getName(), RequestBase.class.getName())); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 如果body为空,转为空对象 |
||||
|
* @param body spring解析完的参数 |
||||
|
* @param inputMessage 输入参数 |
||||
|
* @param parameter 参数对象 |
||||
|
* @param targetType 参数类型 |
||||
|
* @param converterType 消息转换类型 |
||||
|
* @return 真实的参数 |
||||
|
*/ |
||||
|
@SneakyThrows |
||||
|
@Override |
||||
|
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { |
||||
|
String typeName = targetType.getTypeName(); |
||||
|
Class<?> bodyClass = Class.forName(typeName); |
||||
|
return bodyClass.newInstance(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,96 @@ |
|||||
|
package xyz.hlh.crypto.advice; |
||||
|
|
||||
|
import cn.hutool.json.JSONUtil; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import lombok.SneakyThrows; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.core.MethodParameter; |
||||
|
import org.springframework.http.MediaType; |
||||
|
import org.springframework.http.ResponseEntity; |
||||
|
import org.springframework.http.converter.HttpMessageConverter; |
||||
|
import org.springframework.http.server.ServerHttpRequest; |
||||
|
import org.springframework.http.server.ServerHttpResponse; |
||||
|
import org.springframework.web.bind.annotation.ControllerAdvice; |
||||
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; |
||||
|
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; |
||||
|
import xyz.hlh.crypto.annotation.EncryptionAnnotation; |
||||
|
import xyz.hlh.crypto.common.entity.Result; |
||||
|
import xyz.hlh.crypto.common.exception.CryptoException; |
||||
|
import xyz.hlh.crypto.entity.RequestBase; |
||||
|
import xyz.hlh.crypto.util.AESUtil; |
||||
|
|
||||
|
import java.lang.reflect.Type; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: responseBody自动加密 |
||||
|
*/ |
||||
|
@ControllerAdvice |
||||
|
public class EncryptResponseBodyAdvice implements ResponseBodyAdvice<Result<?>> { |
||||
|
|
||||
|
@Autowired |
||||
|
private ObjectMapper objectMapper; |
||||
|
|
||||
|
@Override |
||||
|
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { |
||||
|
ParameterizedTypeImpl genericParameterType = (ParameterizedTypeImpl)returnType.getGenericParameterType(); |
||||
|
|
||||
|
// 如果直接是Result并且有解密注解,则处理
|
||||
|
if (genericParameterType.getRawType() == Result.class && returnType.hasMethodAnnotation(EncryptionAnnotation.class)) { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// 如果不是ResponseBody或者是Result,则放行
|
||||
|
if (genericParameterType.getRawType() != ResponseEntity.class) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// 如果是ResponseEntity<Result>并且有解密注解,则处理
|
||||
|
for (Type type : genericParameterType.getActualTypeArguments()) { |
||||
|
if (((ParameterizedTypeImpl) type).getRawType() == Result.class && returnType.hasMethodAnnotation(EncryptionAnnotation.class)) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
@SneakyThrows |
||||
|
@Override |
||||
|
public Result<?> beforeBodyWrite(Result<?> body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { |
||||
|
|
||||
|
// 真实数据
|
||||
|
Object data = body.getData(); |
||||
|
|
||||
|
// 如果data为空,直接返回
|
||||
|
if (data == null) { |
||||
|
return body; |
||||
|
} |
||||
|
|
||||
|
// 如果是实体,并且继承了Request,则放入时间戳
|
||||
|
if (data instanceof RequestBase) { |
||||
|
((RequestBase)data).setCurrentTimeMillis(System.currentTimeMillis()); |
||||
|
} |
||||
|
|
||||
|
String dataText = JSONUtil.toJsonStr(data); |
||||
|
|
||||
|
// 如果data为空,直接返回
|
||||
|
if (StringUtils.isBlank(dataText)) { |
||||
|
return body; |
||||
|
} |
||||
|
|
||||
|
// 如果位数小于16,报错
|
||||
|
if (dataText.length() < 16) { |
||||
|
throw new CryptoException("加密失败,数据小于16位"); |
||||
|
} |
||||
|
|
||||
|
String encryptText = AESUtil.encryptHex(dataText); |
||||
|
|
||||
|
return Result.builder() |
||||
|
.status(body.getStatus()) |
||||
|
.data(encryptText) |
||||
|
.message(body.getMessage()) |
||||
|
.build(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package xyz.hlh.crypto.annotation; |
||||
|
|
||||
|
import java.lang.annotation.Documented; |
||||
|
import java.lang.annotation.ElementType; |
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
import java.lang.annotation.Target; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: 解密生成类 |
||||
|
*/ |
||||
|
@Target(ElementType.METHOD) |
||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||
|
@Documented |
||||
|
public @interface DecryptionAnnotation { |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package xyz.hlh.crypto.annotation; |
||||
|
|
||||
|
import java.lang.annotation.Documented; |
||||
|
import java.lang.annotation.ElementType; |
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
import java.lang.annotation.Target; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: 加密生成类 |
||||
|
*/ |
||||
|
@Target(ElementType.METHOD) |
||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||
|
@Documented |
||||
|
public @interface EncryptionAnnotation { |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
package xyz.hlh.crypto.config; |
||||
|
|
||||
|
import cn.hutool.crypto.symmetric.AES; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
|
||||
|
import javax.annotation.Resource; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: 自动配置类 |
||||
|
*/ |
||||
|
@Configuration |
||||
|
public class AppConfig { |
||||
|
|
||||
|
@Resource |
||||
|
private CryptConfig cryptConfig; |
||||
|
|
||||
|
@Bean |
||||
|
public AES aes() { |
||||
|
return new AES(cryptConfig.getMode(), cryptConfig.getPadding(), cryptConfig.getKey().getBytes(StandardCharsets.UTF_8), cryptConfig.getIv().getBytes(StandardCharsets.UTF_8)); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
package xyz.hlh.crypto.config; |
||||
|
|
||||
|
import cn.hutool.crypto.Mode; |
||||
|
import cn.hutool.crypto.Padding; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import lombok.Getter; |
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.context.annotation.PropertySource; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: AES需要的配置参数 |
||||
|
*/ |
||||
|
@Configuration |
||||
|
@ConfigurationProperties(prefix = "crypto") |
||||
|
@PropertySource("classpath:crypto.properties") |
||||
|
@Data |
||||
|
@EqualsAndHashCode |
||||
|
@Getter |
||||
|
public class CryptConfig implements Serializable { |
||||
|
|
||||
|
private Mode mode; |
||||
|
private Padding padding; |
||||
|
private String key; |
||||
|
private String iv; |
||||
|
|
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
package xyz.hlh.crypto.constant; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: 加密解密用到的常量 |
||||
|
*/ |
||||
|
public class CryptoConstant { |
||||
|
|
||||
|
/** 请求解密之前的数据存放key */ |
||||
|
public static final String INPUT_ORIGINAL_DATA = "inputOriginalData"; |
||||
|
/** 请求解密之后的数据存放key */ |
||||
|
public static final String INPUT_DECRYPT_DATA = "inputDescryptData"; |
||||
|
|
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
package xyz.hlh.crypto.entity; |
||||
|
|
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: |
||||
|
*/ |
||||
|
@Getter |
||||
|
@Setter |
||||
|
@EqualsAndHashCode |
||||
|
public class RequestBase { |
||||
|
|
||||
|
private Long currentTimeMillis; |
||||
|
|
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
package xyz.hlh.crypto.entity; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.Builder; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import lombok.NoArgsConstructor; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: |
||||
|
*/ |
||||
|
@Data |
||||
|
@NoArgsConstructor |
||||
|
@AllArgsConstructor |
||||
|
@Builder |
||||
|
@EqualsAndHashCode |
||||
|
public class RequestData implements Serializable { |
||||
|
|
||||
|
// 加密的文本
|
||||
|
private String text; |
||||
|
|
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
package xyz.hlh.crypto.util; |
||||
|
|
||||
|
import cn.hutool.crypto.symmetric.AES; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import javax.annotation.PostConstruct; |
||||
|
import javax.annotation.Resource; |
||||
|
import java.io.InputStream; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: |
||||
|
*/ |
||||
|
@Component |
||||
|
public class AESUtil { |
||||
|
|
||||
|
private static AES aes; |
||||
|
|
||||
|
@Resource |
||||
|
private AES iocAes; |
||||
|
@PostConstruct |
||||
|
public void setAes() { |
||||
|
AESUtil.aes = this.iocAes; |
||||
|
} |
||||
|
|
||||
|
public static AES getAes() { |
||||
|
return aes; |
||||
|
} |
||||
|
|
||||
|
public static String encryptHex(byte[] data) { |
||||
|
return aes.encryptHex(data); |
||||
|
} |
||||
|
public static String encryptHex(InputStream data) { |
||||
|
return aes.encryptHex(data); |
||||
|
} |
||||
|
|
||||
|
public static String encryptHex(String data) { |
||||
|
return aes.encryptHex(data, StandardCharsets.UTF_8); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 解密 |
||||
|
*/ |
||||
|
|
||||
|
public static String decrypt(byte[] data) { |
||||
|
return aes.decryptStr(data, StandardCharsets.UTF_8); |
||||
|
} |
||||
|
|
||||
|
public static String decrypt(InputStream data) { |
||||
|
return aes.decryptStr(data); |
||||
|
} |
||||
|
|
||||
|
public static String decrypt(String data) { |
||||
|
return aes.decryptStr(data, StandardCharsets.UTF_8); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
# \u6A21\u5F0F cn.hutool.crypto.Mode |
||||
|
crypto.mode=CTS |
||||
|
# \u8865\u7801\u65B9\u5F0F cn.hutool.crypto.Mode |
||||
|
crypto.padding=PKCS5Padding |
||||
|
# \u79D8\u94A5 |
||||
|
crypto.key=testkey123456789 |
||||
|
# \u76D0 |
||||
|
crypto.iv=testiv1234567890 |
@ -0,0 +1,2 @@ |
|||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ |
||||
|
xyz.hlh.crypto.config.AppConfig |
@ -0,0 +1,102 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |
||||
|
<component name="FacetManager"> |
||||
|
<facet type="Spring" name="Spring"> |
||||
|
<configuration /> |
||||
|
</facet> |
||||
|
<facet type="web" name="Web"> |
||||
|
<configuration> |
||||
|
<webroots /> |
||||
|
<sourceRoots> |
||||
|
<root url="file://$MODULE_DIR$/src/main/java" /> |
||||
|
<root url="file://$MODULE_DIR$/src/main/resources" /> |
||||
|
</sourceRoots> |
||||
|
</configuration> |
||||
|
</facet> |
||||
|
</component> |
||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> |
||||
|
<output url="file://$MODULE_DIR$/target/classes" /> |
||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" /> |
||||
|
<content url="file://$MODULE_DIR$"> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> |
||||
|
<excludeFolder url="file://$MODULE_DIR$/target" /> |
||||
|
</content> |
||||
|
<orderEntry type="inheritedJdk" /> |
||||
|
<orderEntry type="sourceFolder" forTests="false" /> |
||||
|
<orderEntry type="module" module-name="crypto-common" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.0.Final" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.22" level="project" /> |
||||
|
<orderEntry type="module" module-name="crypto-spring-boot-starter" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: commons-io:commons-io:1.3.2" level="project" /> |
||||
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.13.2" level="project" /> |
||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:2.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.20" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-test:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.10" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.10" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.33" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-test:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.jayway.jsonpath:json-path:2.6.0" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: net.minidev:json-smart:2.4.7" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: net.minidev:accessors-smart:2.4.7" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.ow2.asm:asm:9.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.33" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.assertj:assertj-core:3.21.0" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest:2.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.junit.jupiter:junit-jupiter:5.8.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.junit.jupiter:junit-jupiter-api:5.8.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.junit.platform:junit-platform-commons:1.8.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apiguardian:apiguardian-api:1.1.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.junit.jupiter:junit-jupiter-params:5.8.2" level="project" /> |
||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.8.2" level="project" /> |
||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.junit.platform:junit-platform-engine:1.8.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.mockito:mockito-core:4.0.0" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.11.22" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy-agent:1.11.22" level="project" /> |
||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.objenesis:objenesis:3.2" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.mockito:mockito-junit-jupiter:4.0.0" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-test:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.xmlunit:xmlunit-core:2.8.4" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.1" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.6.3" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.56" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.15" level="project" /> |
||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.15" level="project" /> |
||||
|
</component> |
||||
|
</module> |
@ -0,0 +1,62 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<parent> |
||||
|
<artifactId>spring-boot-interface-crypto</artifactId> |
||||
|
<groupId>xyz.hlh</groupId> |
||||
|
<version>1.0-SNAPSHOT</version> |
||||
|
</parent> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<artifactId>crypto-test</artifactId> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||
|
</properties> |
||||
|
|
||||
|
<dependencies> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>xyz.hlh</groupId> |
||||
|
<artifactId>crypto-common</artifactId> |
||||
|
<version>1.0-SNAPSHOT</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>xyz.hlh</groupId> |
||||
|
<artifactId>cry-spring-boot-starter</artifactId> |
||||
|
<version>1.0-SNAPSHOT</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.apache.commons</groupId> |
||||
|
<artifactId>commons-io</artifactId> |
||||
|
<version>1.3.2</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>junit</groupId> |
||||
|
<artifactId>junit</artifactId> |
||||
|
<scope>test</scope> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-all</artifactId> |
||||
|
<version>5.7.20</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-test</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
</dependencies> |
||||
|
|
||||
|
</project> |
@ -0,0 +1,15 @@ |
|||||
|
package xyz.hlh.crypto; |
||||
|
|
||||
|
import org.springframework.boot.SpringApplication; |
||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: 启动类 |
||||
|
*/ |
||||
|
@SpringBootApplication |
||||
|
public class CryptoTestApplication { |
||||
|
public static void main(String[] args) { |
||||
|
SpringApplication.run(CryptoTestApplication.class, args); |
||||
|
} |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
package xyz.hlh.crypto.controller; |
||||
|
|
||||
|
import org.springframework.http.ResponseEntity; |
||||
|
import org.springframework.validation.annotation.Validated; |
||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
import xyz.hlh.crypto.annotation.DecryptionAnnotation; |
||||
|
import xyz.hlh.crypto.annotation.EncryptionAnnotation; |
||||
|
import xyz.hlh.crypto.common.entity.Result; |
||||
|
import xyz.hlh.crypto.common.entity.ResultBuilder; |
||||
|
import xyz.hlh.crypto.entity.Teacher; |
||||
|
|
||||
|
/** |
||||
|
* springboot一个注解实现接口加解密!新姿势! |
||||
|
*/ |
||||
|
@RestController |
||||
|
public class TestController implements ResultBuilder { |
||||
|
|
||||
|
/** |
||||
|
* 返回加密后的数据 |
||||
|
* @param teacher Teacher对象 |
||||
|
* @return 返回加密后的数据 ResponseBody<Result>格式 |
||||
|
*/ |
||||
|
@PostMapping("/encrypt") |
||||
|
@EncryptionAnnotation |
||||
|
public ResponseEntity<Result<?>> encrypt(@Validated @RequestBody Teacher teacher) { |
||||
|
return success(teacher); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 返回解密后的数据 |
||||
|
* @param teacher Teacher对象 |
||||
|
* @return 返回解密后的数据 |
||||
|
*/ |
||||
|
@PostMapping("/decrypt") |
||||
|
@DecryptionAnnotation |
||||
|
public ResponseEntity<Result<?>> decrypt(@Validated @RequestBody Teacher teacher) { |
||||
|
return success(teacher); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
package xyz.hlh.crypto.entity; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import lombok.NoArgsConstructor; |
||||
|
import org.hibernate.validator.constraints.Range; |
||||
|
import org.springframework.format.annotation.DateTimeFormat; |
||||
|
|
||||
|
import javax.validation.constraints.NotBlank; |
||||
|
import javax.validation.constraints.NotNull; |
||||
|
import java.io.Serializable; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: Teacher实体类,使用SpringBoot的validation校验 |
||||
|
*/ |
||||
|
@Data |
||||
|
@NoArgsConstructor |
||||
|
@AllArgsConstructor |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
public class Teacher extends RequestBase implements Serializable { |
||||
|
|
||||
|
@NotBlank(message = "姓名不能为空") |
||||
|
private String name; |
||||
|
@NotNull(message = "年龄不能为空") |
||||
|
@Range(min = 0, max = 150, message = "年龄不合法") |
||||
|
private Integer age; |
||||
|
@NotNull(message = "生日不能为空") |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
||||
|
private Date birthday; |
||||
|
|
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
spring: |
||||
|
mvc: |
||||
|
format: |
||||
|
date-time: yyyy-MM-dd HH:mm:ss |
||||
|
date: yyyy-MM-dd |
||||
|
# 日期格式化 |
||||
|
jackson: |
||||
|
date-format: yyyy-MM-dd HH:mm:ss |
||||
|
time-zone: GMT+8 |
||||
|
|
||||
|
|
@ -0,0 +1,29 @@ |
|||||
|
package xyz.hlh.crypto.controller; |
||||
|
|
||||
|
import cn.hutool.json.JSONUtil; |
||||
|
import org.junit.Test; |
||||
|
import org.junit.runner.RunWith; |
||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||
|
import org.springframework.test.context.junit4.SpringRunner; |
||||
|
import xyz.hlh.crypto.common.entity.Result; |
||||
|
import xyz.hlh.crypto.util.AESUtil; |
||||
|
|
||||
|
/** |
||||
|
* @author wn |
||||
|
* @description: |
||||
|
*/ |
||||
|
@SpringBootTest |
||||
|
@RunWith(SpringRunner.class) |
||||
|
public class TestControllerTest { |
||||
|
|
||||
|
@Test |
||||
|
public void test1() { |
||||
|
|
||||
|
System.out.println(AESUtil.getAes()); |
||||
|
|
||||
|
String data = JSONUtil.toJsonStr(new Result<String>()); |
||||
|
System.out.println(AESUtil.encryptHex(data)); |
||||
|
System.out.println(AESUtil.decrypt(AESUtil.encryptHex(data))); |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<groupId>xyz.hlh</groupId> |
||||
|
<artifactId>spring-boot-interface-crypto</artifactId> |
||||
|
<packaging>pom</packaging> |
||||
|
<version>1.0-SNAPSHOT</version> |
||||
|
<modules> |
||||
|
<module>cry-spring-boot-starter</module> |
||||
|
<module>cry-test</module> |
||||
|
<module>cry-common</module> |
||||
|
</modules> |
||||
|
|
||||
|
<parent> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-parent</artifactId> |
||||
|
<version>2.6.3</version> |
||||
|
<relativePath/> |
||||
|
</parent> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||
|
</properties> |
||||
|
|
||||
|
|
||||
|
|
||||
|
</project> |
Loading…
Reference in new issue