在 Spring Boot 应用程序的 REST 调用中接受 Enum 的空字符串

Posted

技术标签:

【中文标题】在 Spring Boot 应用程序的 REST 调用中接受 Enum 的空字符串【英文标题】:Accept empty String for Enum in REST calls in Spring Boot application 【发布时间】:2018-10-29 13:56:57 【问题描述】:

我制作了一个 Spring Boot 2 REST 应用程序。我正在使用 Angular 来使用 REST。我的枚举有问题。

典型的枚举服务器端是:

public enum EngineType 
    DIESEL, METHANE, ELECTRIC;

    @Nullable
    public static EngineType valueOfNullable(String value) 
        try 
            return valueOf(value);
         catch (Exception e) 
            return null;
        
    

一些实体使用这些枚举作为字段,当然它们可以为空。不幸的是,当客户端为枚举发送“”(空字符串)的实体的 POST 时(因为它可以为空),我有一个错误服务器端:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `server.model.enums.EngineType` from String "": value not one of declared Enum instance names: [DIESEL, METHANE, ELECTRIC]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `server.model.enums.EngineType` from String "": value not one of declared Enum instance names: [DIESEL, METHANE, ELECTRIC]
 at [Source: (PushbackInputStream); line: 1, column: 153] (through reference chain: server.model.tickets.Ticket["engineType2"])

我理解消息的含义,我可以像这样解决创建自定义反序列化器的问题:

@Component
public class EngineTypeDeserializer extends JsonDeserializer<EngineType> 

    @Override
    public EngineType deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException 
        JsonNode node = jp.getCodec().readTree(jp);
        return EngineType.valueOfNullable(node.asText());
    


但我应该将此注释 @JsonDeserialize(using = EngineTypeDeserializer.class) 放在我的 bean 的所有 EngineType 字段中。

我一直在寻找更好的方法来解决这个问题。你有什么建议吗?

【问题讨论】:

如果您在ObjectMapper 上有自定义反序列化器怎么办? 【参考方案1】:

您可以通过编程方式注册您的自定义序列化程序。

在您的@Configuration 班级中:

@Bean
@Primary // Use this to shadow other objectmappers, if anny
public ObjectMapper objectMapper()
    ObjectMapper objMapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addDeserializer(EngineType.class, new EngineTypeDeserializer());
    objMapper.registerModule(module);

【讨论】:

以上是关于在 Spring Boot 应用程序的 REST 调用中接受 Enum 的空字符串的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot / REST - 示例代码在启动后终止

在 Spring Boot REST 应用程序中处理 gzipped 请求

在 Spring Boot 2.2.0 应用程序中命中 REST 端点的问题

docker 镜像正在运行,但无法在 Spring Boot 应用程序中访问 REST 端点

Spring boot - 如何在 rest 应用程序中验证 Multipartfile

如何在 Spring Boot 应用程序中实现长轮询 REST 端点?