如何用java中的jackson将json反序列化为enum?
我有一个与名称字段的接口,如下所示:如何用java中的jackson将json反序列化为enum?,java,json,jackson,Java,Json,Jackson,我有一个与名称字段的接口,如下所示: public interface Field { } public enum BField implements Field { SOME_FIELD } public class C implements Serializable { private Set<Field> f; public Set<Field> getF() { return f; } public void setF(Set
public interface Field {
}
public enum BField implements Field {
SOME_FIELD
}
public class C implements Serializable {
private Set<Field> f;
public Set<Field> getF() { return f; }
public void setF(Set<Field> f) { this f = f; }
}
@RequestMapping(method=RequestMethod.Post, value="/save")
@ResponseBody
public void save (@RequestBody C c) {
//save c
}
public class JsonBFieldDeserializer extends StdDeserializer<Field> {
public JsonBFieldDeserializer() {
this(null);
}
public JsonBFieldDeserializer(Class<?> vc) {
super(vc);
}
@Overrid
public Field deserialize(JsonParser jsonParser, DeserializationContext dC) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree();
String text = node.asText();
return BField.valueOf(text);
}
}
@Configuration
public class BConfiguration extends WebMVCConfigurationSupport {
protected void configureMessageConverters(List<HttpMessageConverters<?>> converters){
converters.add(convert());
addDefaultHttpMessageConverters(converters);
}
@Bean
MappingJackson2HttpMessageConverter convert(){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Field.class, new JsonBFieldDeserializer());
objectMapper.registerModule(module);
converter.setObjectMapper(objectMapper);
return converter;
}
}
此接口位于模块A中。
我有一个名为BField的枚举,它位于模块B中,实现如下:
public interface Field {
}
public enum BField implements Field {
SOME_FIELD
}
public class C implements Serializable {
private Set<Field> f;
public Set<Field> getF() { return f; }
public void setF(Set<Field> f) { this f = f; }
}
@RequestMapping(method=RequestMethod.Post, value="/save")
@ResponseBody
public void save (@RequestBody C c) {
//save c
}
public class JsonBFieldDeserializer extends StdDeserializer<Field> {
public JsonBFieldDeserializer() {
this(null);
}
public JsonBFieldDeserializer(Class<?> vc) {
super(vc);
}
@Overrid
public Field deserialize(JsonParser jsonParser, DeserializationContext dC) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree();
String text = node.asText();
return BField.valueOf(text);
}
}
@Configuration
public class BConfiguration extends WebMVCConfigurationSupport {
protected void configureMessageConverters(List<HttpMessageConverters<?>> converters){
converters.add(convert());
addDefaultHttpMessageConverters(converters);
}
@Bean
MappingJackson2HttpMessageConverter convert(){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Field.class, new JsonBFieldDeserializer());
objectMapper.registerModule(module);
converter.setObjectMapper(objectMapper);
return converter;
}
}
模块a中有一个名为C的类,如下所示:
public interface Field {
}
public enum BField implements Field {
SOME_FIELD
}
public class C implements Serializable {
private Set<Field> f;
public Set<Field> getF() { return f; }
public void setF(Set<Field> f) { this f = f; }
}
@RequestMapping(method=RequestMethod.Post, value="/save")
@ResponseBody
public void save (@RequestBody C c) {
//save c
}
public class JsonBFieldDeserializer extends StdDeserializer<Field> {
public JsonBFieldDeserializer() {
this(null);
}
public JsonBFieldDeserializer(Class<?> vc) {
super(vc);
}
@Overrid
public Field deserialize(JsonParser jsonParser, DeserializationContext dC) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree();
String text = node.asText();
return BField.valueOf(text);
}
}
@Configuration
public class BConfiguration extends WebMVCConfigurationSupport {
protected void configureMessageConverters(List<HttpMessageConverters<?>> converters){
converters.add(convert());
addDefaultHttpMessageConverters(converters);
}
@Bean
MappingJackson2HttpMessageConverter convert(){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Field.class, new JsonBFieldDeserializer());
objectMapper.registerModule(module);
converter.setObjectMapper(objectMapper);
return converter;
}
}
我将此JSON对象发送到此方法:
{
"f": ["SOME_FIELD"]
}
然后,我得到HTTP 400错误请求错误代码和以下异常日志:
抽象类型只能用其他类型实例化
信息
模块的层次结构为模块B依赖于模块A。我试图使用@JsonTypeInfo,但模块之间的依赖关系是一个限制,不允许我在@JsonSubTypes注释中为类C中的字段f使用BField.class。这里的问题不是
枚举
,而是集合
和字段
接口
您需要告诉Jackson您想要什么类型的集合
和什么类型的字段
,您可以通过以下方式注释该属性:
@JsonDeserialize(as = EnumSet.class, contentAs = BField.class)
最后我找到了解决办法
私有集f添加@JsonDeserialize(as=EnumSet.class)
注释代码>在C类中
public interface Field {
}
public enum BField implements Field {
SOME_FIELD
}
public class C implements Serializable {
private Set<Field> f;
public Set<Field> getF() { return f; }
public void setF(Set<Field> f) { this f = f; }
}
@RequestMapping(method=RequestMethod.Post, value="/save")
@ResponseBody
public void save (@RequestBody C c) {
//save c
}
public class JsonBFieldDeserializer extends StdDeserializer<Field> {
public JsonBFieldDeserializer() {
this(null);
}
public JsonBFieldDeserializer(Class<?> vc) {
super(vc);
}
@Overrid
public Field deserialize(JsonParser jsonParser, DeserializationContext dC) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree();
String text = node.asText();
return BField.valueOf(text);
}
}
@Configuration
public class BConfiguration extends WebMVCConfigurationSupport {
protected void configureMessageConverters(List<HttpMessageConverters<?>> converters){
converters.add(convert());
addDefaultHttpMessageConverters(converters);
}
@Bean
MappingJackson2HttpMessageConverter convert(){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Field.class, new JsonBFieldDeserializer());
objectMapper.registerModule(module);
converter.setObjectMapper(objectMapper);
return converter;
}
}
公共类JsonBFieldDeserializer扩展了StdDeserializer{
公共JsonBFieldDeserializer(){
这个(空);
}
公共JsonBFieldDeserializer(类vc){
超级(vc);
}
@凌驾
公共字段反序列化(JsonParser、JsonParser、反序列化上下文dC)引发IOException、JsonProcessingException{
JsonNode节点=jsonParser.getCodec().readTree();
String text=node.asText();
返回BField.valueOf(文本);
}
}
public interface Field {
}
public enum BField implements Field {
SOME_FIELD
}
public class C implements Serializable {
private Set<Field> f;
public Set<Field> getF() { return f; }
public void setF(Set<Field> f) { this f = f; }
}
@RequestMapping(method=RequestMethod.Post, value="/save")
@ResponseBody
public void save (@RequestBody C c) {
//save c
}
public class JsonBFieldDeserializer extends StdDeserializer<Field> {
public JsonBFieldDeserializer() {
this(null);
}
public JsonBFieldDeserializer(Class<?> vc) {
super(vc);
}
@Overrid
public Field deserialize(JsonParser jsonParser, DeserializationContext dC) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree();
String text = node.asText();
return BField.valueOf(text);
}
}
@Configuration
public class BConfiguration extends WebMVCConfigurationSupport {
protected void configureMessageConverters(List<HttpMessageConverters<?>> converters){
converters.add(convert());
addDefaultHttpMessageConverters(converters);
}
@Bean
MappingJackson2HttpMessageConverter convert(){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Field.class, new JsonBFieldDeserializer());
objectMapper.registerModule(module);
converter.setObjectMapper(objectMapper);
return converter;
}
}
@配置
公共类B配置扩展了WebMVCConfigurationSupport{
受保护的无效配置MessageConverters(ListXcuse我忘了注意接口字段有多个实现。例如模块B中的BField和模块D中的DField。谢谢。当我只使用接口字段的一个实现来测试它时,您的解决方案是有效的,但我也必须依赖模块A到模块B。我的问题有点不同。首先,我不想依赖模块A到模块B,第二个接口字段在多个模块中有多个实现。只有从模块中收集Jackson片段并将其聚合,您才可能需要它;一个示例是Druid如何允许您注册自定义解析器和其他内容: