Разрешение сообщения проверки Spring Boot 2.1 не работает в @RepositoryRestController - PullRequest
0 голосов
/ 18 апреля 2019

Я борюсь с проектом Spring Boot 2.1.4, использующим Hibernate / Validator, Spring Data REST, Spring HATEOAS.

Я переопределяю LocalValidatorFactoryBean для поиска сообщений в определенной папке:

@Configuration
@EnableRetry
@EnableTransactionManagement
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
public class CustomConfiguration {


 @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasenames("classpath:/i18n/messages");
        // messageSource.setDefaultEncoding("UTF-8");
        // set to true only for debugging
        messageSource.setUseCodeAsDefaultMessage(false);
        messageSource.setCacheSeconds((int) TimeUnit.HOURS.toSeconds(1));
        messageSource.setFallbackToSystemLocale(false);
        return messageSource;
    }

    @Bean
    public MessageSourceAccessor messageSourceAccessor() {
        return new MessageSourceAccessor(messageSource());
    }

    /**
     * Enable Spring bean validation https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation
     *
     * @return
     */
    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
        factoryBean.setValidationMessageSource(messageSource());
        return factoryBean;
    }

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator());
        return methodValidationPostProcessor;
    }

Я также позаботился о том, чтобы переопределить getValidator ():

@Configuration
@EnableHypermediaSupport(type = {HypermediaType.HAL})
public class WebMvcConfiguration implements WebMvcConfigurer {


    @Autowired
    private LocalValidatorFactoryBean validator;


    @Override
    public Validator getValidator() {
        return validator;
    }

Я прочитал много обсуждений по этой проблеме, например, https://github.com/spring-projects/spring-boot/issues/3071 и связанных тем.

Iдобавлен этот пользовательский Совет:

/**
 * Workaround class for making JSR-303 annotation validation work for controller method parameters. Check the issue
 * <a href="https://jira.spring.io/browse/DATAREST-593">DATAREST-593</a>
 */
@ControllerAdvice
public class RequestBodyValidationProcessor extends RequestBodyAdviceAdapter {

    @Autowired
    private LocalValidatorFactoryBean validator;

    @Override
    public boolean supports(final MethodParameter methodParameter, final Type targetType,
                            final Class<? extends HttpMessageConverter<?>> converterType) {
        final Annotation[] parameterAnnotations = methodParameter.getParameterAnnotations();
        for (final Annotation annotation : parameterAnnotations) {
            if (annotation.annotationType().equals(Valid.class)) {
                return true;
            }
        }

        return false;
    }

    @Override
    public Object afterBodyRead(final Object body, final HttpInputMessage inputMessage, final MethodParameter parameter,
                                final Type targetType, final Class<? extends HttpMessageConverter<?>> converterType) {
        final Object obj = super.afterBodyRead(body, inputMessage, parameter, targetType, converterType);

        //TODO Il messaggio come ad esempio {eyeexam.pupillarydistance.missing} non viene interpolato tramite il file di properties
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(obj);
        if (!constraintViolations.isEmpty()) {
            throw new ConstraintViolationException(constraintViolations);
        }
        return obj;
    }

}

Я испытываю пропущенное разрешение сообщения при вызове конечной точки контроллера покоя:

@RepositoryRestController
@PreAuthorize("isAuthenticated()")
public class EyeExamController {

@PostMapping(path = "/eyeExams/saveWithNote")
    public ResponseEntity<?> save(@Valid @RequestBody EyeExamNote eyeExamNote, Locale locale,
                                  PersistentEntityResourceAssembler resourceAssembler) {
        return new ResponseEntity<Resource<?>>(resourceAssembler.toResource(eyeExamService.save(eyeExamNote)), HttpStatus.OK);
    }

Я ожидаю, что результат проверки ScriptAsserts моего компонентаразрешено правильно:

@ScriptAssert(lang = "javascript", script = "(_.pupillaryDistanceIntermediate2Tot != null && _.pupillaryDistanceFarTot != null) ? (_.pupillaryDistanceIntermediate2Tot < _.pupillaryDistanceFarTot) :true", alias = "_", reportOn = "pupillaryDistanceIntermediate2Tot", message = "{eyeexam.pupillarydistance.intermediate.lower}"),

Вместо этого, когда я вызываю конечную точку, я получаю строку {eyeexam.pupillarydistance.intermediate.lower} как интерполированное сообщение вместо моего текста (он находится в файле messages.properties в папке i18n согласно моему определению).

Кто-то предложил переместить ключи проверки в ValidationMessages.properties, но это не работает для меня.Я делаю что-то неправильно?Любая подсказка приветствуется.

...