如何在java中使用jackson将json反序列化为enum?

时间:2016-10-02 05:51:16

标签: java json jackson

我有一个名为Field的接口,如下所示:

public interface Field {
}

此界面位于 A 模块中。 我有一个名为BField的枚举,它位于 B 模块中,实现如下:

public enum BField implements Field {
    SOME_FIELD
}

模块 A 中有一个名为C的类,如下所示:

public class C implements Serializable {
    private Set<Field> f;

    public Set<Field> getF() { return f; }
    public void setF(Set<Field> f) { this f = f; }
}

我有一个REST方法如下:

@RequestMapping(method=RequestMethod.Post, value="/save")
@ResponseBody
public void save (@RequestBody C c) {
    //save c
}

我将此JSON对象发送到此方法:

{
    "f": ["SOME_FIELD"]
}

然后我得到HTTP 400错误请求错误代码,并带有以下异常日志:

  

抽象类型只能使用其他类型进行实例化   信息

模块的层次结构是模块 B 依赖于模块 A 。我尝试使用@JsonTypeInfo,但模块之间的依赖关系起限制作用,不允许我在@JsonSubTypes注释中使用BField.class作为C类中的字段f。

2 个答案:

答案 0 :(得分:1)

此处的问题不是enum,而是SetField接口。

你需要告诉杰克逊你想要什么样的SetField,你可以通过以下方式注释该属性来做到这一点:

@JsonDeserialize(as = EnumSet.class, contentAs = BField.class)

答案 1 :(得分:0)

最后我找到了解决方案。

  1. 我在上下文中删除<mvc:annotation-driven/>
  2. 在C类中为字段@JsonDeserialize(as = EnumSet.class)添加private Set<Field> f;注释。
  3. 在模块 B 中创建一个名为JsonBFieldDeserializer的类,如下所示:

    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);
        }
    }
    
  4. 在模块 B 中创建一个名为BConfiguration的类,如下所示:

    @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;
        }
    }
    
  5. 小心使用 fasterxml jackson 而不是 codehaus库!