java - Spring MVC @RequestBody 映射 Optional<Enum>

标签 java json spring enums jackson

我有一个使用这种方法的休息 Controller :

@RequestMapping(value = "", method = { RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<?> add(@Valid @RequestBody MyModel myModel, Errors errors) {

        ...
        return new ResponseEntity<SomeObject>(someObject, HttpStatus.OK);
    }

MyModel有一个字段 isMeetingOrSale那是枚举(MeetingSaleFlag):

public enum MeetingSaleFlag {
    MEETING("MEETING"),
    SALE("SALE");
    private final String name;       
    private MeetingSaleFlag(String s) { name = s; }
    public boolean equalsName(String otherName) {
       return (otherName == null) ? false : name.equals(otherName);
    }
    public String toString() { return this.name; }
}

它可以映射一个包含字段 "isMeetingOrSale" : "MEETING" 的 json

但json中的值可以是"isMeetingOrSale" : ""或完全丢失,所以在那种情况下,我希望该字段映射到 null。如果我将归档更改为 Optional<MeetingSaleFlag>

我得到了

Could not read JSON: Can not instantiate value of type [simple type, class java.util.Optional<MeetingSaleFlag>] from String value ('MEETING'); no single-String constructor/factory method\\n at [Source: java.io.PushbackInputStream@32b21158; line: 17, column: 18] (through reference chain: MyModel[\"isMeetingOrSale\"]);

所以问题是如何从 json 映射可选枚举?

最佳答案

感谢 Sotirios Delimanolis 的评论,我得以解决问题。

1) 添加

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jdk8</artifactId>
        </dependency>

作为依赖项。

2) 重新配置 Jackson 映射器。注册:

    @Bean
    @Primary
    public ObjectMapper jacksonObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        return mapper;
    }

这样做来注册jdk8模块

/**
 * @return Jackson jdk8 module to be registered with every bean of type
 *         {@link ObjectMapper}
 */
@Bean
public Module jdk8JacksonModule() {
    return new Jdk8Module();
}

Another way to customize Jackson is to add beans of type com.fasterxml.jackson.databind.Module to your context. They will be registered with every bean of type ObjectMapper, providing a global mechanism for contributing custom modules when you add new features to your application.

这样做只会注册额外的模块并保留 Spring Boot 提供的内置 Jackson 配置。

3) 结果

现在,当发送的 json 中缺少该属性时,它会映射为 null (这不是很好。我原以为它会给我一个可选的,我将能够使用 .isPresent())。 当它是一个空字符串 ("isMeetingOrSale": "") 时,Jackson 返回一个错误:

Could not read JSON: Can not construct instance of MyModel from String value '': value not one of declared Enum instance names: [VAL1, VAL2]

我觉得还可以。

有用的链接:Jackson jdk8 module , Spring MVC configure Jackson

关于java - Spring MVC @RequestBody 映射 Optional<Enum>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31543756/

相关文章:

javascript - jquery .each() 不工作

java - Spring 与 Struts 1 集成 - 将依赖项注入(inject)到 ActionForm

angularjs - 无法使用 Angular 和 Spring Security 设置身份验证 header

java - 用另一个泛型扩展一个泛型集合

java - 如何在JOOQ中清除批处理?

javascript - Websocket : send messages and notifications to all clients except sender

java - 如何使用 Hibernate 和 Spring Boot 启用批量插入

java - 从实例方法写入静态字段

java - setOnFocusChangeListener 重新添加提示

javascript - 以python 'JSON Array of arrays'格式遍历 'List of lists'