如何在Java中反序列化列表元素的JSON数组?

时间:2014-06-27 09:48:10

标签: java json jackson

我有一个给定的JSON:

    {
  "facility-no": "2011",
  "standard-counter": [
    {
      "id": "0",
      "type": "0",
      "text": "Gebucht",
      "free": "0",
      "present": "0",
      "percent": "100",
      "max": "0",
      "status": "Frei",
      "status-value": "0"
    }, ...
], ...
}

我希望它反序列化到我的课程中......

包装类:

public class Counters {

    @JsonProperty("facility-no")
    private String facilityId;

    @JsonProperty("standard-counter")
    private List<XCounter> xCounters;
}

实现由包装类中的列表保存的对象的类:

public class XCounter {

    protected String id;
    @JsonIgnore
    public static final CounterTypeEnum type = CounterTypeEnum.X_COUNTER;

    // standard & level counter properties
    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
    String text;
    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
    int free;
    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
    int present;
    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
    float percent;
    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
    int max;
    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
    String status;
    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
    @JsonProperty("status-value")
    int statusValue;
    ...(all getters and setters...)

这是我的CounterTypeEnum:

public enum CounterTypeEnum {
    X_COUNTER(0), Y_COUNTER(1), Z_COUNTER(2);
    private int type;
    private CounterTypeEnum(final int type) {
        this.type = type;
    }
    public int getType() {
        return this.type;
    }
}

但是,我总是得到一个UnrecognizedPropertyException:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "type" (Class com.foo.bar.XCounter), not marked as ignorable
 at [Source: java.io.StringReader@42077608; line: 1, column: 61] (through reference chain: com.foo.bar.Counters["standard-counter"]->com.foo.bar.XCounter["type"])

如果我不在SuBStandardCounters的类级别上使用 @JsonIgnoreProperties(ignoreUnknown = true)

如何在不使用 @JsonIgnoreProperties(ignoreUnknown = true)的情况下避免此异常?

3 个答案:

答案 0 :(得分:0)

这里的主要问题是,在反序列化期间,默认的反序列化器将尝试将整个Json映射到您的Object。 但它不知道应该映射的类型&#34;

如果只想映射一些字段,使用自定义串行器和反串行器是很好的方法。

希望这有帮助!

祝你好运

答案 1 :(得分:0)

如果您希望反序列化字段但未序列化,则必须在getter和属性声明中使用@JsonIgnore并在使用Jackson时使用设置器中的@JsonProperty

答案 2 :(得分:0)

您可以考虑使用the Jackson's polymorphic deserialization的实际类类型替换枚举类型。在这种情况下,Jackson将根据type属性的值创建某种类型的实例。

以下是一个例子:

public class JacksonPolymorphic {
    public static String JSON = "{\n" +
            "  \"facility-no\": \"2011\",\n" +
            "  \"standard-counter\": [\n" +
            "    {\n" +
            "      \"id\": \"0\",\n" +
            "      \"type\": \"0\",\n" +
            "      \"text\": \"Gebucht\",\n" +
            "      \"free\": \"0\",\n" +
            "      \"present\": \"0\",\n" +
            "      \"percent\": \"100\",\n" +
            "      \"max\": \"0\",\n" +
            "      \"status\": \"Frei\",\n" +
            "      \"status-value\": \"0\"\n" +
            "    }\n" +
            "]\n" +
            "}";

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
    public static abstract class Counter {
        private final String id;

        public Counter(String id) {
            this.id = id;
        }
    }

    public static class Counters {
        private final String facilityId;
        private final List<Counter> counters;

        public Counters(@JsonProperty("facility-no") String facilityId,
                        @JsonProperty("standard-counter") List<Counter> counters) {
            this.facilityId = facilityId;
            this.counters = counters;
        }

        @Override
        public String toString() {
            return "Counters{" +
                    "facilityId='" + facilityId + '\'' +
                    ", counters=" + counters +
                    '}';
        }
    }

    @JsonTypeName("0")
    public static class XCounter extends Counter {
        private final String text;
        private final int free;
        private final int present;
        private final float percent;
        private final int max;
        private final String status;
        private final int statusValue;

        public XCounter(@JsonProperty("id") String id,
                        @JsonProperty("text") String text,
                        @JsonProperty("free") int free,
                        @JsonProperty("present") int present,
                        @JsonProperty("percent") float percent,
                        @JsonProperty("max") int max,
                        @JsonProperty("status") String status,
                        @JsonProperty("status-value") int statusValue) {
            super(id);
            this.text = text;
            this.free = free;
            this.present = present;
            this.percent = percent;
            this.max = max;
            this.status = status;
            this.statusValue = statusValue;
        }

        @Override
        public String toString() {
            return "XCounter{" +
                    "text='" + text + '\'' +
                    ", free=" + free +
                    ", present=" + present +
                    ", percent=" + percent +
                    ", max=" + max +
                    ", status='" + status + '\'' +
                    ", statusValue=" + statusValue +
                    '}';
        }
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerSubtypes(XCounter.class);
        System.out.println(mapper.readValue(JSON, Counters.class));
    }

}

输出:

Counters{facilityId='2011', counters=[XCounter{text='Gebucht', free=0, present=0, percent=100.0, max=0, status='Frei', statusValue=0}]}