簡體   English   中英

從JSON反序列化java枚舉

[英]Deserialize java enum from JSON

我們使用Jackson 1.9.1對JSON請求響應字符串進行序列化和反序列化。 原始Java類型,集合類型和自定義對象(序列化)沒有問題。 但是,我在嘗試將JSON字符串反序列化為java枚舉時遇到問題。 JSON字符串是這樣序列化的:

"wt":{"wt":100.5,"unit":{"LBS":3}}

wt的Java類型是這樣的:

public class Weight {

    protected double weight;
    protected Unit unit;
}

我提到了這個這個 ,以及這個在SO上,並提出了重量單位的枚舉,如下:

public enum Unit {

    KG("kg"),
    GM("gm"),
    LBS("lbs"),
    OZ("oz");

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

    @JsonValue
    public String getValue() { return this.value; }

    @JsonCreator
    public static Unit create(String val) {
        Unit[] units = Unit.values();
        for (Unit unit : units) {
            if (unit.getValue().equals(val)) {
                return unit;
            }
        }
        return LBS;
    }
}

問題是,當我嘗試反序列化上面提到的JSON時,我得到這個錯誤說:“無法識別的字段”LBS“(類abcdWeight),沒有標記為可忽略”異常堆棧跟蹤是這樣的:

Caused by: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "LBS" (Class a.b.c.d.Weight), not marked as ignorable
 at [Source: java.io.ByteArrayInputStream@20172017; line: 1, column: 464] (through reference chain: a.b.c.d.MyRequest["blah"]->a.b.c.d.AnotherType["wt"]->a.b.c.d.Weight["LBS"])
    at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
    at org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673)
    at org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659)
    at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365)

...

我的問題是:枚舉的序列化JSON字符串是否正確? 我還應該包括(或注釋)枚舉是否正確反序列化?

我假設在public enum Unit代碼塊中,你的意思是Unit而不是WeightMeasurementUnit

Weight類只有一個weight和一個unit ,所以如果你傳遞{"wt":100.5,"unit":"lbs"} ,它應該有效,因為一個unit只是一個沒有價值的單位。 因此,解串器無法將{"LBS":3}解析為一個Unit 什么是3

另一個問題是你的值是“lbs”,而你傳遞的是“LBS”。 所以要么你需要標准化,要么你需要使用unit.getValue().equalsIgnoreCase(val)

我建議你將你的jackson版本更新到2.7.0-rc2(也可能在之前),然后按如下方式配置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 Unit {
    KG,
    GM,
    LBS,
    OZ;

    // UPDATE: implicitly already the default so override not needed in this case
    @Override
    public String toString() {
        return name();
    }
}

您不需要任何注釋或自定義反序列化器。 這將是將簡單枚舉映射到json的方法,反之亦然。

如果你的枚舉應該從一個特殊的字符串映射,你必須添加一個值字段和一個構造函數,它分配這個字段並返回toString方法中的值。

public enum Unit {
    KG("kilogram"),
    GM("gram"),
    LBS("blah"),
    OZ("anything");

    Unit(final String value) {
        this.value = value;
    }

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM