Проверка не работает на ключах карты в RestController - PullRequest
0 голосов
/ 30 апреля 2020

Используя Spring Boot 2.2.6, для данного контроллера:

@RestController
@Validated
class MyController {
    @GetMapping("foo")
    fun getFirmwareVersionDifference(
        @RequestParam @Valid versions: @Valid Map<
            @Pattern(regexp = "a|b|c")
            String, String>
    ): String {
       // …
    }
}

Я бы ожидал, что запрос foo?d=any выдаст ConstraintViolationException, но контроллер вызывается нормально.

У меня есть MethodValidationPostProcessor в моем контексте, и это работает для других проверок. Если я изменю RequestParam на @RequestParam @Valid @Length(min=3) installedFirmwareVersion: String, он будет работать как обычно.

Что мне не хватает?

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Это kotlin ошибка компилятора / отсутствующая функция: https://youtrack.jetbrains.com/issue/KT-13228

Как описано в https://youtrack.jetbrains.com/issue/KT-35843, это частично решается в kotlin 1.3.70.

Вот как вы можете установить флаг компилятора в build.gradle.kts

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xemit-jvm-type-annotations")
        jvmTarget = "11" // at least 8 should work, I only tested 11
    }
}
1 голос
/ 30 апреля 2020

Возможно, мой ответ не является исправлением того, который вы ищете, но он, безусловно, проверяет проверку, которую вы пытаетесь выполнить в вашем контроллере.

import in.silentsudo.validators.annotations.RequestMap;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Map;

public class MapParamValidator implements ConstraintValidator<RequestMap, Map<String, String>> {

    @Override
    public boolean isValid(Map<String, String> stringStringMap, ConstraintValidatorContext constraintValidatorContext) {
        return stringStringMap.containsKey("a") || stringStringMap.containsKey("c") || stringStringMap.containsKey("b");
    }
}

import in.silentsudo.validators.MapParamValidator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = {MapParamValidator.class})
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMap {
    String message() default "Invalid Request Map";

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

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

Реализация контроллера:

@GetMapping("foo")
    public String getFirmwareVersionDifference(
            @RequestParam @Valid
            @RequestMap
                    Map<String, String> versions) {

        return "OK";
    }

Пожалуйста, обязательно добавьте @Validated на контроллер следующим образом:

@RestController
@Validated
@RequestMapping("/somepath")
public class StatusController {
...
}

Если все работает хорошо, вы должны получить что-то вроде этого

There was an unexpected error (type=Internal Server Error, status=500).
getFirmwareVersionDifference.versions: Invalid Request Map
javax.validation.ConstraintViolationException: getFirmwareVersionDifference.versions: Invalid Request Map
...
...