如何使用Jackson json注释enum字段以进行反序列化

时间:2012-02-15 19:45:20

标签: java json jackson

杰克逊1.6.2 REST Web服务/ Apache Wink

如何对枚举字段进行注释以便杰克逊对其进行反序列化?

内部课程

public enum BooleanField
{
    BOOLEAN_TRUE        { public String value() { return "1";} },
    BOOLEAN_FALSE       { public String value() { return "0";} },

Java Bean / Request对象

BooleanField locked;
public BooleanField getLocked() {return locked;}

Jackson文档声明它可以通过@JsonValue / @JsonCreator执行此操作,但不提供示例(如何有用!)。我敢肯定他们只是不想让太多人使用他们的框架,所以他们保守这个秘密。

任何愿意溢出(java)bean的人都会这样吗?

6 个答案:

答案 0 :(得分:44)

如果您使用的是Jackson 1.9,序列化将通过以下方式完成:

public enum BooleanField {
   BOOLEAN_TRUE("1")
   ;

   // either add @JsonValue here (if you don't need getter)
   private final String value;

   private BooleanField(String value) { this.value = value; }

   // or here
   @JsonValue public String value() { return value; }

所以你需要改变的方法是向Enum类型本身添加方法,所以所有值都有它。不确定它是否适用于子类型。

对于@JsonCreator,使用静态工厂方法会这样做;所以添加如下内容:

@JsonCreator
public static BooleanField forValue(String v) { ... }

Jackson 2.0实际上支持仅使用@JsonValue,包括反序列化。

答案 1 :(得分:26)

Jackson 2.7.2 或更新

public enum BooleanField
{
    @JsonProperty("1")
    BOOLEAN_TRUE,
    @JsonProperty("0")
    BOOLEAN_FALSE
}

答案 2 :(得分:14)

不要注释它们,只需配置你的ObjectMapper实例:

private ObjectMapper createObjectMapper() {
    final ObjectMapper mapper = new ObjectMapper();
    // enable toString method of enums to return the value to be mapped
    mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
    mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
    return mapper;
}

并在你的枚举中覆盖toString()方法:

public enum SectionType {
START("start"),
MORE("more");

    // the value which is used for matching
    // the json node value with this enum
    private final String value;

    SectionType(final String type) {
        value = type;
    }

    @Override
    public String toString() {
        return value;
    }
}

您不需要任何注释或自定义反序列化器。

答案 3 :(得分:3)

实际上,根据JsonValue(Jackson 2.3.3)的文档:

NOTE: when use for Java enums, one additional feature is
 * that value returned by annotated method is also considered to be the
 * value to deserialize from, not just JSON String to serialize as.
 * This is possible since set of Enum values is constant and it is possible
 * to define mapping, but can not be done in general for POJO types; as such,
 * this is not used for POJO deserialization. 

因此对于枚举,您的反序列化将无法使用JsonCreator,因为JsonValue将用于序列化和反序列化。 对枚举执行此操作的一种方法是使用JsonSetter和JsonGetter。

答案 4 :(得分:0)

public enum BooleanField
{
    BOOLEAN_TRUE("1"),      
    BOOLEAN_FALSE("0");
    
    private final String value;

    BooleanField( int value ) { this.value = value; }
    
}

解串器

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;

public class BooleanFieldDeserializer extends Json Deserializer<BooleanField> {
    
    public BooleanField deserialize( JsonParser p, DeserializationContext ctx )
    throws IOException 
    {
        // boilerplate code for every deserializer
        ObjectCodec objectCodec = p.getCodec();
        JsonNode node = objectCodec.readTree(p);

        // customizable part for your impl
        String booleanFieldString = node.asText();
        return valueOf( booleanFieldString ); <- Enum-supplied method
    }

然后,在您的JavaBean中...

@JsonDeserialize(using = BooleanFieldDeserializer.class)
BooleanField locked;

答案 5 :(得分:-1)

如果枚举是数组,则以下内容可能有效。 (仅用于反序列化)

package com.stack.model;

import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import lombok.Data;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder({ "success", "my-enums" })
public class MyObjectJSON {

    @JsonProperty("sucess")
    private boolean success;

    @JsonProperty("my-enums")
    private MyEnum[] myEnums;


    static enum MyEnum {
        Enum1, Enum2, Enum3, Enum4, EnumN;

        private static Map<String, MyEnum> myEnumsMap = new HashMap<String, MyEnum>(5);

        static {
            myEnumsMap.put("enum1-val", Enum1);
            myEnumsMap.put("enum2-val", Enum2);
            myEnumsMap.put("enum3-val", Enum3);
            myEnumsMap.put("enum4-val", Enum4);
            myEnumsMap.put("enumn-val", EnumN);
        }

        @JsonCreator
        public static MyEnum forValue(String value) {
            return myEnumsMap.get(value.toLowerCase());
        }
    }
}

考虑:

  1. @Data注释生成setter,getters,toString等
  2. @JsonProperty(“my-enums”)私人MyEnum [] myEnums,这是用杰克逊注释Enum类型字段的方法( 如果它是一个数组,它是否有效。)

  3. MyEnum是要映射的JSON对象的值的枚举,假设以下对象:

    {     “成功”:是的,     “my-enums”:[“enum1-val”,“enum3-val”] }

  4. forValue函数允许将数组的字符串值映射到Enum,它使用@JsonCreator注释以指示反序列化中使用的构造工厂。