我有一个使用这种方法的休息 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]
我觉得还可以。
关于java - Spring MVC @RequestBody 映射 Optional<Enum>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31543756/