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

Spring@ControllerAdvise messageSource不能使用Hibernate消息参数

微生毅
2023-03-14

我试图在Spring Boot REST控制器中添加一些自定义bean验证,使用@ControllerAdvision注释扩展ResponseEntityExceptionHandler类,并重写#HandleMethodArgumentNotValid(MethodArgumentNotValidException e,HttpHeaders headers,HttpStatus status,WebRequest request)方法。在此方法中,我试图通过MessageSource将给定的FielderRor转换为本地化消息。虽然我在尝试使用消息参数时收到了NumberFormatException,但通过Hibernate验证器是可能的。

我正在使用以下依赖项:

  • org.hibernate.validator:hibernate-validator(6.0.11.final)
  • org.springframework:spring-web(5.0.8.release)
  • org.springframework:spring-webmvc(5.0.8.release)

所有这些都是通过org.springframework.boot:spring-boot-starter-web(2.0.4.release)提供的。

考虑使用以下REST控制器:

@RestController
public class FooController {

    @PostMapping(value = "/foo")
    public void submitFooRequest(@Validated @RequestBody FooRequest fooRequest) {
        // ....
    }
}
@Getter
@Setter
@ValidBarRequest
public class FooRequest {

    private String fieldFoo;
    private BarRequest barRequest;
}
@Getter
@Setter
public class BarRequest {

    private String fieldBar;
}

验证注释:

@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = BarRequestValidator.class)
@Documented
public @interface ValidBarRequest {

    String message() default "{org.example.validation.constraints.ValidBarRequest.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    String fieldFoo() default "fieldFoo";

    String barRequestFieldBar() default "barRequest.fieldBar";
}

验证约束验证器:

@Log4j2
public class BarRequestValidator implements ConstraintValidator<ValidBarRequest, Object> {

    // ....

    @Override
    public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
        if (/* some condition */) {
            HibernateConstraintValidatorContext hibernateValidatorContext = constraintValidatorContext.unwrap(HibernateConstraintValidatorContext.class);
            hibernateValidatorContext.disableDefaultConstraintViolation();
            hibernateValidatorContext.addMessageParameter("fieldFoo", "some value...").buildConstraintViolationWithTemplate("{org.example.validation.constraints.ValidBarRequest.message}")
                .addPropertyNode("barRequest.fieldBar").addConstraintViolation();
            return false;
        }

        return true;
    }
}

但是,通过@ControllerAdvice注释bean并使用Spring messageSource,将在以下消息上抛出NumberFormatException(在messages.properties中):

@ControllerAdvice
public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {

    @Autowired private MessageSource messageSource;

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException e, HttpHeaders headers, HttpStatus status, WebRequest request) {
        List<ErrorDetails> errorDetails = new ArrayList<>();
        for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
            errorDetails.add(new ErrorDetails(fieldError.getField(), messageSource.getMessage(fieldError, Locale.getDefault())));
        }

        return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
    }

    @Getter
    @AllArgsConstructor
    class ErrorDetails {

        private String field;
        private String message;
    }
}
@Bean
public LocalValidatorFactoryBean validator(MessageSource messageSource) {
    LocalValidatorFactoryBean localValidatorFactory = new LocalValidatorFactoryBean();
    localValidatorFactory.setValidationMessageSource(messageSource);

    return localValidatorFactory;
}

共有1个答案

闻人鸿飞
2023-03-14

填充消息源MessageFormat.Format中的变量,并且必须使用花括号中的数字。

ValidBarRequest.fooRequest.barRequest.fieldBar=must be lower or equal than {0}
 类似资料:
  • 问题内容: 我正在使用Hibernate Validator,并且想在错误消息中解析类别的名称。考虑以下简单情况: 假设我有一个HazardousCategoryConstraint的有效实现。验证器根据受限名称列表检查每个类别的名称。当我调用validate(InventoryReport)时,我得到了我期望的错误数量,但它们是相同的字符串。我希望看到类别名称解析为每条消息。有人可以给我指出一个

  • 问题内容: 我在这里尝试了答案中的步骤:HibernateValidator,自定义ResourceBundleLocator和Spring 但是仍然只是作为输出而不是消息。 dispatcher-servlet.xml /WEB-INF/validationMessages.properties: 表格(上课地点) 这是怎么了 问题答案: 得到它了!:-) 我在我的计算机中添加了以下bean而不

  • 我已经在我的nuxtjs项目中使用了nuxt auth。在此处输入图像描述

  • 我已经更新了我的Kafka从版本0.10.2.0到版本2.1.0,现在Kafka不能消费消息。我使用Spring引导,这是我的配置: 我已经更改了组id,以避免旧组id出现问题。我当前的spring版本是2.1。2.释放。在我的应用程序中,我可以看到我的客户是如何不断地重新连接的 你知道这个问题吗?

  • 我使用的是JBoss,因此需要排除JBoss自己的日志子系统,以便进行日志记录,我使用的是jboss-deployment-structure.xml文件: 我使用的是JPA,因此如果这可能有所帮助,这是我的persistence.xml文件:

  • 我无法使用Spring MVC 4.2.5版本来处理hibernate validation 5.1.0.Final。 我的WebConfig: 我有一个ExceptionHanlder,它获取验证消息,并将其作为JSON推回: 在controller中,我使用@org.springframework.validation.annotation.validated。 PS2.我确信我的messag