方法级别的自定义约束未在Spring控制器REST方法上触发。

huangapple 未分类评论47阅读模式
英文:

Method level custom constraint not fired on Spring controller REST method

问题

我正在为一个Spring REST方法创建一个自定义的方法级约束但验证器根本没有被触发。`isValid` 方法从未被调用

//
// 控制器
//

@PostMapping("/{id}")
@DTOParametersMatch
public ResponseEntity<DTO> createDTO(
    @PathVariable("id") @SuppressWarnings("unused") UUID id,
    @Validated(CreateValidation.class) @RequestBody DTO dto
) {
  System.out.println("***** createDTO 被调用");
  DTO created = dtosService.createDTO(dto);
  return ResponseEntity.status(HttpStatus.CREATED).body(created);
}

//
// DTOParametersMatch
//

@Constraint(validatedBy = DTOParametersMatchValidator.class)
@Target({ METHOD, CONSTRUCTOR })
@Retention(RUNTIME)
@Documented
public @interface DTOParametersMatch {

  String message() default "路径中的DTO ID必须与请求体中的DTO ID相匹配";
  Class<?>[] groups() default {};
  Class<? extends Payload>[] payload() default {};
}

//
// DTOParametersMatchValidator
//

@SupportedValidationTarget(PARAMETERS)
public class DTOParametersMatchValidator implements ConstraintValidator<DTOParametersMatch, Object[]> {

  private static final String ILLEGAL_ARGS_BASE =
      "DTOParametersMatch的使用不正确;需要两个参数,第一个是UUID,第二个是DTO。";

  @Override
  public boolean isValid(Object[] values, ConstraintValidatorContext context) {
    System.out.println("***** DTOParametersMatchValidator isValid 被调用");

    var pathId = (UUID) values[0];
    var body = (DTO) values[1];

    return pathId.equals(body.getId());
  }
}

我不确定是否漏掉了什么或者设置有误...

英文:

I'm creating a custom method level constraint for a Spring REST method but the validator is not being triggered at all. The isValid method is never called.

//
// Controller
//

@PostMapping(&quot;/{id}&quot;)
@DTOParametersMatch
public ResponseEntity&lt;DTO&gt; createDTO(
    @PathVariable(&quot;id&quot;) @SuppressWarnings(&quot;unused&quot;) UUID id,
    @Validated(CreateValidation.class) @RequestBody DTO dto
) {
  System.out.println(&quot;***** createDTO called&quot;);
  DTO created = dtosService.createDTO(dto);
  return ResponseEntity.status(HttpStatus.CREATED).body(created);
}


//
// DTOParametersMatch
//

@Constraint(validatedBy = DTOParametersMatchValidator.class)
@Target({ METHOD, CONSTRUCTOR })
@Retention(RUNTIME)
@Documented
public @interface DTOParametersMatch {

  String message() default &quot;DTO ID in path must match DTO ID in body&quot;;
  Class&lt;?&gt;[] groups() default {};
  Class&lt;? extends Payload&gt;[] payload() default {};
}


//
// DTOParametersMatchValidator
//

@SupportedValidationTarget(PARAMETERS)
public class DTOParametersMatchValidator implements ConstraintValidator&lt;DTOParametersMatch, Object[]&gt; {

  private static final String ILLEGAL_ARGS_BASE =
      &quot;Illegal usage of DTOParametersMatch; &quot;
          + &quot;requires two parameters where first is a UUID and second is a DTO.&quot;;

  @Override
  public boolean isValid(Object[] values, ConstraintValidatorContext context) {
    System.out.println(&quot;***** DTOParametersMatchValidator isValid called&quot;);

    var pathId = (UUID)v0;
    var body = (DTO)v1;

    return pathId.equals(body.getId());
  }
}

I'm not sure if I missed something or set it up wrong..

答案1

得分: 0

我的其中一位同事指出我在控制器类上缺少了@Validated注解。一旦我添加了这个注解,一切都正常工作了。

英文:

One of my colleagues pointed out I was missing the @Validated annotation on the controller class. Once I added that, everything worked.

huangapple
  • 本文由 发表于 2020年7月23日 23:46:11
  • 转载请务必保留本文链接:https://java.coder-hub.com/63058136.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定