杰克逊阵列元素到POJO

时间:2014-11-20 20:46:27

标签: java json jackson

我正在尝试使用Jackson反序列化现有的JSON文档,并且想知道是否可以执行以下转换而无需使用自定义反序列化堆栈。

输入JSON如下所示:

{
    "type": "foo",
    "content": ["a", "b", {"some": "object", "goes": "here"}, 4]
}

content中的前3个元素不会改变,并且总是String,String,SomeDataStructure,Integer(可选)

我想反序列化为这样的事情:

class Foo {
    public static class FooContent {
        String some;
        String goes;
    }

    String aString;
    String bString;
    FooContent content;
    Integer cInt;      
}

现在我已经遇到了BeanAsArrayDeserializer,听起来就像它可能是我想要的,但我似乎无法找到任何东西,就像一段示例代码一样让我开始

那么,有什么想法吗?

2 个答案:

答案 0 :(得分:0)

您始终可以实施自定义反序列化程序。见下面的源代码:

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

;

public class JacksonTest {

    public static void main(String[] args) throws Exception {
        String json = "{\"type\": \"foo\",\"content\": [\"a\", \"b\", {\"some\": \"object\", \"goes\": \"here\"}, 4]}";

        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, true);

        Root pojo = mapper.readValue(json, Root.class);
        System.out.println(pojo);
    }
}

class Root {
    public String type;
    @JsonDeserialize(using = FooDeserializer.class)
    public Foo content;

    @Override
    public String toString() {
        return content.toString();
    }
}

class Foo {
    public static class FooContent {
        public String some;
        public String goes;

        @Override
        public String toString() {
            return "{" + some + ", " + goes + "}";
        }
    }

    String aString;
    String bString;
    FooContent content;
    Integer cInt;

    @Override
    public String toString() {
        return "Foo [aString=" + aString + ", bString=" + bString + ", content=" + content
                + ", cInt=" + cInt + "]";
    }
}

class FooDeserializer extends JsonDeserializer<Foo> {

    @Override
    public Foo deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
            JsonProcessingException {
        Foo f = new Foo();
        int index = 0;
        while (jp.nextToken() != JsonToken.END_ARRAY) {
            JsonToken token = jp.getCurrentToken();
            if (token.isStructStart()) {
                f.content = jp.readValueAs(Foo.FooContent.class);
                index++;
            } else {
                switch (index++) {
                case 0:
                    f.aString = jp.getText();
                    break;
                case 1:
                    f.bString = jp.getText();
                    break;
                case 3:
                    f.cInt = Integer.parseInt(jp.getText());
                    break;
                }
            }
        }
        return f;
    }
}

以上应用打印:

Foo [aString=a, bString=b, content={object, here}, cInt=4]

答案 1 :(得分:0)

允许使用BeanAsArrayDeserializer(内部)的功能是@JsonFormat。您可以在this博文中阅读有关它的一些信息。

我最近刚刚了解了它,但我认为适用于您的情况的映射看起来如下所示。您需要一个包装器来保存content字段,然后该字段的类型为Foo

@JsonFormat(shape = Shape.ARRAY)
@JsonPropertyOrder({ "aString", "bString", "content", "cInt" })
class Foo {
    public static class FooContent {
        String some;
        String goes;
    }

    @JsonFormat(shape = Shape.STRING)
    String aString;

    @JsonFormat(shape = Shape.STRING)
    String bString;

    FooContent content;

    @JsonFormat(shape = Shape.NUMBER)
    Integer cInt;      
}