Проверка Javax не работает для Hashmap со значением в виде массива или списка - PullRequest
0 голосов
/ 17 апреля 2020

Я работаю на Kotlin с пружинной загрузкой.

У меня есть сущность Hours

data class Hours(
         @get: Max(value=3) val value : Long)

И в моем конструкторе у меня есть следующее

fun postHours(@RequestBody @Valid hours: @Valid LinkedHashMap<String,  Array<Hours>>): String {
        return service.addHours(hours)
    }

Но проверка не работает вообще.

Я могу отправлять запросы с value > 3, хотя я установил максимальное значение как 3. и ошибки нет.

Может кто-нибудь сказать мне, что здесь не так?

Ответы [ 2 ]

0 голосов
/ 18 апреля 2020

Наконец-то нашел исправление для этого. Написал класс оболочки Array

   class ArrayWrapper<E>( elements: Array<E>?) {

        @Valid var _array: Array<E>? = elements

        override fun equals(other: Any?): Boolean {
            return if (other !is ArrayWrapper<*>) {
                false
            } else Arrays.equals(_array, other._array)
        }

        override fun hashCode(): Int {
            return Arrays.hashCode(_array)
        }
    }

, а затем изменил метод контроллера следующим образом.

fun postHours(@RequestBody @Valid hours: LinkedHashMap<String, ArrayWrapper<Hours>>): String {
        return service.addHours(hours)
    }

Теперь проверка работает отлично!

0 голосов
/ 17 апреля 2020

У меня похожий случай, который работает в Java (вы можете переписать в Kotlin). Пожалуйста, попробуйте:

определить новый bean-компонент в вашем классе конфигурации, аннотированный @Configuration:

@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
    return new MethodValidationPostProcessor();
}

, аннотируйте свой контроллер с помощью:

@RestController
@Validated

Затем вы можете проверить вас класс с:

postHours(@RequestBody LinkedHashMap<String, @Valid Hours> hours)

----- МОДИФИКАЦИЯ ДЛЯ ПРЕДОСТАВЛЕНИЯ ПОЛНОГО ПРИМЕРА -----

Вы можете использовать этот полный пример. Я использую: spring-boot-starter-web 2.2.6 с lombok.

Вот класс для проверки:

@Data
public class Foo {
    @Max(value = 3)
    private Integer count;
}

Контроллер:

@RestController
@Validated
public class FooController {
    @PostMapping("/validate")
    public String validate(@RequestBody LinkedHashMap<String, List<@Valid Foo>> foos) {
        return "foo";
    }
}

Класс конфигурации:

@Configuration
public class AppConfig {
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
}

Рекомендация контроллера (для отправки исключения как json):

@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    @Data
    @AllArgsConstructor
    class ApiError {
        private HttpStatus status;
        private String message;
        private List<String> errors;
    }

    @ExceptionHandler({ ConstraintViolationException.class })
    public ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex, WebRequest request) {
        List<String> errors = new ArrayList<>();
        for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
            errors.add(violation.getRootBeanClass().getName() + " " +
                    violation.getPropertyPath() + ": " + violation.getMessage());
        }

        ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors);
        return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus());
    }
}

Класс теста:

@WebMvcTest(FooController.class)
public class FooControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    public void test() throws Exception {
        LinkedHashMap<String, Foo> foos = new LinkedHashMap<>();
        Foo foo = new Foo();
        foo.setCount(4);
        foos.put("foo", foo);
        this.mockMvc.perform(post("/validate")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(bars)))
                .andExpect(status().isBadRequest())
                .andExpect(content().string(containsString("validate.foos[foo].<map value>[0].count: must be less than or equal to 3")));
    }
}

Модульный тест показывает, что проверка внутри связанного хэш-карты работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...