jackson 如何在SpringBoot/Swagger中使枚举参数小写?

nhjlsmyf  于 2022-11-09  发布在  Spring
关注(0)|答案(1)|浏览(266)

我有以下终结点

@GetMapping(value = "/mypath/{mychoice}")
public ResponseClass generateEndpoint(
        @PathVariable("mychoice") FormatEnum format,
    )  {

...

和后面的enum(用Jackson注解)

@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
public enum Format {
    AVRO,
    ORC,
    PARQUET,
    PROTOBUF
}

我希望,@JsonNaming注解将告诉swagger以小写显示大小写,但它没有

在每个案例中添加@JsonProperty也没有帮助。
它也不接受带有错误的小写URL

org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'FormatEnum'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam FormatEnum] for value 'avro'; nested exception is java.lang.IllegalArgumentException: No enum constant FormatEnum.avro

设置

spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_ENUMS = true

没有任何作用(而且在程式码中是true)。
看起来它只是没有使用Jackson来反序列化枚举!

kuarbcqp

kuarbcqp1#

回答不区分大小写的枚举序列化部分

设置spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_ENUMS=true不起作用的原因可以在Konstantin Zyubin的回答中找到。
从上面的答案中得到启发,我们可以有一个更通用的方法来处理请求参数中不区分大小写的枚举。
转换器类别

import org.springframework.core.convert.converter.Converter;

public class CaseInsensitiveEnumConverter<T extends Enum<T>> implements Converter<String, T> {
    private Class<T> enumClass;

    public CaseInsensitiveEnumConverter(Class<T> enumClass) {
        this.enumClass = enumClass;
    }

    @Override
    public T convert(String from) {
        return T.valueOf(enumClass, from.toUpperCase());
    }
}

添加配置

import com.example.enums.EnumA;
import com.example.enums.EnumB;
import com.example.enums.FormatEnum;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class AppConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        List<Class<? extends Enum>> enums = List.of(EnumA.class, EnumB.class, FormatEnum.class);
        enums.forEach(enumClass -> registry.addConverter(String.class, enumClass,
                      new CaseInsensitiveEnumConverter<>(enumClass)));
    }
}

相关:Jackson databind enum case insensitive

相关问题