Проверьте определенные значения перечисления в RequestParam Springboot

У меня есть Spring Boot API с некоторыми контроллерами, которые используют перечисление в качестве RequestParam. Это все работает нормально. Если я использую значение, которого нет в перечислении, я получу ошибку. Однако я нигде не могу найти, можно ли проверить, является ли requestParam частью подмножества перечисления.

Перечисление выглядит примерно так:

public enum Type {
    @JsonProperty("een")
    ONE("een"),

    @JsonProperty("twee")
    TWO("twee"),

    @JsonProperty("drie")
    THREE("drie");

    private final String value;

    private static final Map<String, Type> lookup = new HashMap<String, Type>();

    static {
        for (Type type : Type.values()) {
            lookup.put(type.value, type);
        }
    }

    private Type(String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }

    public static Type get(String value) {
        return lookup.get(value);
    }

    @Override
    public String toString() {
        return this.value;
    }
}

Я создал org.springframework.core.convert.converter.Converter, чтобы использовать такое перечисление (значение с другим именем перечисления).

Конечные точки выглядят примерно так:

@GetMapping("/my-endpoint")
    public ResponseEntity<Set<Item>> getItems(
        @RequestParam Type type
    ) {
        <... etc>
    return new ResponseEntity<Set<Item>>(items, HttpStatus.OK);
}

Так, например, я хотел бы проверить для одной из моих конечных точек, имеет ли RequestParam значение «een» или «twee» и должен вернуть неверный запрос, если он имеет значение «drie». И для другой конечной точки я хотел бы проверить, имеет ли RequestParam значение «twee» или «drie». Это упрощенный пример, на самом деле у меня гораздо больше параметров в перечислении и множество конечных точек, которые используют все перечисление или его подмножество. Я знаю, что могу создавать разные перечисления с подмножествами, но поскольку они часто используются в разных подмножествах каждый раз, это не вариант.

Есть ли другой способ сделать это?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
1
0
1 580
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я понял, как это сделать, благодаря этой статье: https://www.baeldung.com/javax-validations-enums.

По сути, я создал аннотацию, специфичную для моего перечисления (я не уверен, что ее можно сделать более общей).

@Constraint(validatedBy = TypeSubsetValidator.class)
@Target({ ElementType.TYPE, ElementType.PARAMETER, ElementType.FIELD })
@Retention(RUNTIME)
public @interface TypeSubset {
    Type[] anyOf();

    String message() default "error.wrongType";

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

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

И создал сопутствующий валидатор:

 public class TypeSubsetValidator implements ConstraintValidator<TypeSubset, Type> {
    private Type[] subset;

    @Override
    public void initialize(TypeSubset annotation) {
        this.subset = annotation.anyOf();
    }

    @Override
    public boolean isValid(Type value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }

        return Arrays.asList(subset).contains(value);
    }
}

Затем валидацию можно использовать следующим образом:

@GetMapping("/my-endpoint")
    public ResponseEntity<Set<Item>> getItems(
        @TypeSubset(anyOf = { Type.ONE, Type.TWO}) @RequestParam  Type type
    ) {
        <... etc>
    return new ResponseEntity<Set<Item>>(items, HttpStatus.OK);
}

Теперь в качестве RequestParam можно использовать только Type.ONE и Type.TWO, другие значения вернут неверный запрос.

Другие вопросы по теме