当前位置: 首页 > 知识库问答 >
问题:

spring boot自定义验证器注释对参数不起作用

黄博艺
2023-03-14

我创建了一个新的注释来验证控制器上的参数:

@Constraint(validatedBy = ValueValidator.class)
@Target( { ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidValue {
    String message() default "Invalid value";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

这是我的验证器:

public class ValueValidator implements ConstraintValidator<ValidValue, String> {
    @Override
    public void initialize(ValidValue constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        if (s.contains("hello")) {
            throw new IllegalArgumentException("hello is not valid");
        }
        return true;
    }
}

这是我的控制器:

@GetMapping(value = "/extraction-date", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Find  customers by extraction date")
public ResponseEntity<List<Customer>> findAllCustomersByExtractionDate(@RequestParam @ValidValue String value)
{
    System.out.println(value);
    return null;
}

我的控制器注释为:

@RestController
@RequestMapping("api/v1/customers")
@AllArgsConstructor
@Controller
@Validated
@CrossOrigin
@Tag(name = "customer-controller", description = "Controller managing operations related to customers ")

我还有一个建议控制器,我打算用它来捕捉抛出的异常:

@ControllerAdvice()
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * @param ex a Throwable
     * @return a responseEntity with a descriptive message and some other information
     */
    @ExceptionHandler(Throwable.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public ErrorMessage globalExceptionHandler(Throwable ex) {
        LOG.error(ex.getMessage());
        return getErrorMessage();
    }

    /**
     * @param ex a Exception
     * @return a responseEntity with a descriptive message and some other information
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public ErrorMessage globalExceptionHandler(Exception ex) {
        LOG.error(ex.getMessage());
        return getErrorMessage();
    }

    /**
     * @param ex      an InvalidInputException
     * @return a responseEntity with a descriptive message and some other information
     */
    @ExceptionHandler({InvalidInputException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ErrorMessage invalidInputExceptionHandler(Exception ex) {
        LOG.error(ex.getMessage());
        return getErrorMessage(ex, ErrorCode.INVALID_INPUT_ERROR);
    }

    /**
     * @param ex      an ResourceNotFoundException
     * @param request the request from the client
     * @return a responseEntity with a descriptive message and some other information
     */
    @ExceptionHandler({ResourceNotFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ResponseBody
    public ErrorMessage resourceNotFoundException(Exception ex, WebRequest request) {
        LOG.error(ex.getMessage());
        return getErrorMessage(ex, ErrorCode.RESOURCE_NOT_FOUND);
    }

    /**
     * @param ex thrown exception
     * @param errorCode to be returned to the client in message
     * @return the error message with all attributes
     */
    private ErrorMessage getErrorMessage(Exception ex, ErrorCode errorCode) {
        return new ErrorMessage(
                errorCode.code,
                new Date(),
                ex.getMessage(),
                errorCode.description);
    }

    /**
     * @return the error message with all attributes
     */
    private ErrorMessage getErrorMessage() {
        return new ErrorMessage(
                ErrorCode.INTERNAL_ERROR.code,
                new Date(),
                "Error while proceeding a joinPoint, unhandled exception: see log messages for more details.",
                ErrorCode.INTERNAL_ERROR.description);
    }
} 

我在控制台上得到的是:

INFO |2021-11-17T08:51:48,898|88D0657C2A8042FDBD32C05E96280791| [http-nio-8080-exec-1] com.obs.dqsc.api.controller.CustomerController - Entered in CustomerController.findAllCustomersByExtractionDate(hello)
hello
INFO |2021-11-17T08:51:48,903|88D0657C2A8042FDBD32C05E96280791| [http-nio-8080-exec-1] com.obs.dqsc.api.controller.CustomerController - Exit from CustomerController.findAllCustomersByExtractionDate(..); Execution time: 2 ms;

pom.xml中的依赖关系:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-ui</artifactId>
        <version>1.5.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

谁能告诉我我错过了什么?

共有1个答案

子车睿
2023-03-14

我缺少启动验证器来使其工作,所以我所要做的就是添加这个依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency> 
 类似资料:
  • 执行控制器方法时,我收到以下日志: ObjECT:[字段名称上的对象目录中的字段错误:拒绝值[safasf];代码[Pattern.catalog.name, Pattern.name, Pattern.java.lang.String, Pattern];参数[org.springframework.context.support.DefaultMessageSourceResolable:代码

  • 我正在开发spring mvc应用程序,我应该在spring mvc validator的基础上应用验证。第一步,我为类和设置控制器添加了注释,效果很好。现在我需要实现自定义验证器来执行复杂的逻辑,但我想使用现有的注释并添加额外的检查。 我的用户类: 我的验证器: 我的控制器: 那么,有可能同时使用自定义验证器和注释吗?如果是,怎么做?

  • 我有一个自定义注释,如下所示 我定义了一个方面来包装实际的方法调用 注释的用法如下所示 到目前为止,这工作得很好,我可以在TestableAspect#InvkeAndLog中实现我的登录。 现在我需要验证eg的索引值不大于10。 我可以在运行时通过更改方面实现来实现,如下所示 但这需要至少调用一次API,而且效率不高。是否有一种方法可以在spring启动应用程序启动时执行此操作?

  • 我在Angular中有一个自定义验证的表单构建器,但我在自定义验证中读取文件后无法获取文件的类型。 下面是StackBlitz: https://stackblitz.com/edit/Angular-ivy-atwqqc?file=src%2fapp%2fapp.component.ts TS文件

  • 我的springboot版本是2.3.7。我知道spring boot starter验证不是spring boot starter web的可传递依赖项。但即使单独添加了它,我的注释也不起作用。 //下面的依赖我已经添加build.gradle编译'org.springframework.boot: spring-boot-starter-validation' //我希望在请求时出错的示例类

  • 我有一个名为的下拉字段,其中包含电话、电子邮件等值,还有一个名为的输入字段。如果选择了下拉值,我想验证输入字段的有效电子邮件地址。。。 我试图创建一个自定义约束,将验证字段对电子邮件正则表达式,如果字段将具有值 我有以下自定义约束的代码 验证器就像 问题是它没有在表单上触发...我使用模型对话框,其中要验证的bean被呈现 参考:使用Hibernate验证器进行跨域验证(JSR 303) 期待您的