From 75c35369fc3701480c5c54e9235ae4560000c4f8 Mon Sep 17 00:00:00 2001
From: yulinling <2712495353@qq.com>
Date: Tue, 5 Aug 2025 23:02:47 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A0=A1?=
=?UTF-8?q?=E9=AA=8C=20fix:=20=E4=BF=AE=E5=A4=8Dvalid?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 19 ++++
.../workflow/annotation/FieldMatch.java | 39 ++++++++
.../validator/FieldMatchValidator.java | 41 ++++++++
.../workflow/controller/AuthController.java | 26 ++---
.../workflow/dto/request/LoginRequest.java | 2 +
.../workflow/dto/request/RegisterRequest.java | 2 +
.../handler/GlobalExceptionHandler.java | 97 +++++++++++++------
.../workflow/service/AuthService.java | 2 +-
.../service/impl/AuthServiceImpl.java | 49 ++++------
9 files changed, 204 insertions(+), 73 deletions(-)
create mode 100644 src/main/java/asia/yulinling/workflow/annotation/FieldMatch.java
create mode 100644 src/main/java/asia/yulinling/workflow/annotation/validator/FieldMatchValidator.java
diff --git a/pom.xml b/pom.xml
index f41f6cf..87359ee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -201,6 +201,25 @@
+ * 字段校验 + *
+ * + * @author YLL + * @since 2025/8/5 + */ +@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = FieldMatchValidator.class) +public @interface FieldMatch { + String message() default "字段值不匹配"; + + Class>[] groups() default {}; + + Class extends Payload>[] payload() default {}; + + String first(); + + String second(); + + @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) + @Retention(RetentionPolicy.RUNTIME) + @interface List { + FieldMatch[] value(); + } +} diff --git a/src/main/java/asia/yulinling/workflow/annotation/validator/FieldMatchValidator.java b/src/main/java/asia/yulinling/workflow/annotation/validator/FieldMatchValidator.java new file mode 100644 index 0000000..b5556cf --- /dev/null +++ b/src/main/java/asia/yulinling/workflow/annotation/validator/FieldMatchValidator.java @@ -0,0 +1,41 @@ +package asia.yulinling.workflow.annotation.validator; + +import asia.yulinling.workflow.annotation.FieldMatch; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.beanutils.BeanUtils; + +/** + *+ * 校验逻辑 + *
+ * + * @author YLL + * @since 2025/8/5 + */ +@Slf4j +public class FieldMatchValidator implements ConstraintValidator@@ -27,5 +28,6 @@ public class LoginRequest { /** * 记住我 */ + @NotNull(message = "记住我不能为空") private Boolean rememberMe = false; } diff --git a/src/main/java/asia/yulinling/workflow/dto/request/RegisterRequest.java b/src/main/java/asia/yulinling/workflow/dto/request/RegisterRequest.java index 0adcb5c..a121cf3 100644 --- a/src/main/java/asia/yulinling/workflow/dto/request/RegisterRequest.java +++ b/src/main/java/asia/yulinling/workflow/dto/request/RegisterRequest.java @@ -1,5 +1,6 @@ package asia.yulinling.workflow.dto.request; +import asia.yulinling.workflow.annotation.FieldMatch; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; @@ -15,6 +16,7 @@ import lombok.Data; * @since 2025/6/19 */ @Data +@FieldMatch(first = "password", second = "confirmPassword", message = "密码不一致") public class RegisterRequest { /** diff --git a/src/main/java/asia/yulinling/workflow/exception/handler/GlobalExceptionHandler.java b/src/main/java/asia/yulinling/workflow/exception/handler/GlobalExceptionHandler.java index 0c568d7..56ad670 100644 --- a/src/main/java/asia/yulinling/workflow/exception/handler/GlobalExceptionHandler.java +++ b/src/main/java/asia/yulinling/workflow/exception/handler/GlobalExceptionHandler.java @@ -4,11 +4,23 @@ import asia.yulinling.workflow.exception.PageException; import asia.yulinling.workflow.exception.ServiceException; import asia.yulinling.workflow.model.ApiResponse; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.support.DefaultMessageSourceResolvable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.servlet.ModelAndView; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Collectors; + /** *
* 全局异常处理
@@ -22,6 +34,63 @@ import org.springframework.web.servlet.ModelAndView;
public class GlobalExceptionHandler {
private static final String DEFAULT_ERROR_VIEW = "error";
+ /**
+ * 统一 ServiceException 异常处理
+ *
+ * @param e ServiceException
+ * @return 统一返回 json 格式
+ */
+ @ExceptionHandler(ServiceException.class)
+ @ResponseBody
+ public ApiResponse> catchErrorHandler(ServiceException e) {
+ log.error("service error:{}", e.getMessage());
+ return ApiResponse.of(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage(), null);
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public ResponseEntity