如何让Jackson反序列化为我自己的Array实现

时间:2016-03-03 17:15:12

标签: java json jackson json-deserialization

鉴于我自己的数组实现MyArray<T>,我怎样才能让杰克逊知道它,以便它能够从JSON数组反序列化为MyArray<T>?到目前为止,我只得到了这个例外:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of MyArray out of START_ARRAY token

3 个答案:

答案 0 :(得分:2)

libgdx中的Array类有一个构造函数,它接受一个数组:<ul class="ul-trending-list" id="products-carousel"> <li> <div class="single-trending-list"> <span>$90.00</span> <h3>Leather Clutch, Gray Distressed</h3> </div> </li> <li> <div class="single-trending-list"> <span>$91.00</span> <h3>Sori Yanagi Butterfly Y Wenge Stool</h3> </div> </li> <li> <div class="single-trending-list"> <span>$31.00</span> <h3>BOTTLIT Canister, 600ml</h3> </div> </li> </ul> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

不是尝试序列化libgdx数组,而是使用一个带有数组的简单类作为序列化/去序列化的基础,然后根据反序列化的数据创建一个libgdx数组。

通常,仅序列化POJO类型的对象是一个很好的规则。

简而言之:

public Array (T[] array)

答案 1 :(得分:2)

正如Dariusz所说,利用Array类具有接受正常数组的构造函数这一事实是很好的。

看,如果使用默认序列化程序 - 序列化为JSON的数组将如下所示:

{"items":["item1","item2"],"size":2,"ordered":true}
除非您希望保留sizeordered字段,否则显然是浪费空间。

我建议您更改序列化对象的方式,使其看起来更像普通数组,另一方面 - 反序列化可以再次构建Array对象。

如果添加以下一对序列化器和反序列化器:

SimpleModule module = new SimpleModule();
module.addDeserializer(Array.class, new StdDelegatingDeserializer<>(
    new StdConverter<Object[], Array>() {
        @Override
        public Array convert(Object[] value) {
            return new Array(value);
        }
}));

module.addSerializer(Array.class, new StdDelegatingSerializer(
    new StdConverter<Array, Object>() {
        @Override
        public Object convert(Array value) {
            return value.toArray();
        }
}));

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);

您将在这些类型之间进行透明转换

答案 2 :(得分:1)

一种方法是编写像

这样的序列化器
import java.io.IOException;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.ser.std.SerializerBase;

public class MyArraySerializer extends SerializerBase<MyArray> {

    protected MyArraySerializer() {
        super(MyArray.class);
    }

    @Override
    public void serialize(MyArray myArray, JsonGenerator gen, SerializerProvider p)
            throws IOException, JsonGenerationException {
        gen.writeStartArray();
        Iterator<MyObject> it = myArray.iterator();
        while (it.hasNext()) {
            MyObject ob = it.next();
            gen.writeObject(p);
            if (it.hasNext()) {
                gen.writeRaw(',');
            }
        }
        gen.writeEndArray();
    }
}

这样的反序列化器
import java.io.IOException;

import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;

public class MyArrayDeserializer extends JsonDeserializer<MyArray> {

    @Override
    public MyArray deserialize(JsonParser parser, DeserializationContext ctx)
            throws IOException, JsonProcessingException {
        MyObject[] obs = parser.readValueAs(MyObject[].class);
        return new MyArray(obs); //presuming you have a copy-constructor
    }
}

然后使用@JsonSerialize(using = MyArraySerializer.class) @JsonDeserialize(using = MyArrayDeserializer.class)注释包含此类数组的属性 如果您直接使用数组实现,而不是在容器类中,此页面有一个如何在运行时注册序列化处理程序的示例http://wiki.fasterxml.com/JacksonHowToCustomSerializers

我应该注意,在这个答案中,我使用的是Jackson 1.9 API,而2.x可能略有不同。根据{{​​3}},最显着的差异是包名称的变化以及某些类所在的位置。否则,此代码应不受影响。