我在java中使用了Class選項來替代使用null的更好的類型檢查。 http://functionaljava.googlecode.com/svn/artifacts/2.20/javadoc/fj/data/Option.html如何使用JSON序列化/反序列化Option <>類(功能性java)?
我的問題是如何在JSON中序列化/反序列化我的下面的代碼?
public Option<? extends ClassA> a;
使用ObjectMapper序列化的結果總是:
"a" : [ "Option$Some", {
"none" : false,
"some" : true
} ]
和反序列化不起作用。
感謝您的任何迴應。
P/S:我貼我的完整的代碼如下所示:
public class TestOption {
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@JsonSubTypes({
@JsonSubTypes.Type(value = SoundDog.class, name = "soundDog"),
@JsonSubTypes.Type(value = SoundCat.class, name = "soundCat"), })
public static abstract class Sound {
abstract String getSound();
}
public static class SoundDog extends Sound {
@Override
String getSound() {
return "gau gau";
}
}
public static class SoundCat extends Sound {
@Override
String getSound() {
return "meo meo";
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({ @JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat"), })
public static abstract class Animal {
public Animal() {
}
public Animal(String name) {
this.name = name;
}
public String name;
public Animal parent;
public Option<? extends Sound> sound;
}
@JsonTypeName("dog")
public static class Dog extends Animal {
public Dog() {
}
public Dog(String name) {
super(name);
}
}
@JsonTypeName("cat")
public static class Cat extends Animal {
public Cat() {
}
public Cat(String name) {
super(name);
}
}
public static void main(String... args) throws Exception {
TestOption zoo = createZoo();
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
String json1 = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(zoo);
System.out.println("+++>>>" + json1);
zoo = mapper.readValue(json1, TestOption.class);
for(Animal animal : zoo.animals){
System.out.println("Animal name = " + animal.name);
if(animal.sound != null){
System.out.println("Animal sound = " + animal.sound.some().getSound());
}
}
String json2 = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(zoo);
System.out.println("Equals: " + json1.equals(json2));
}
private static TestOption createZoo() {
TestOption zoo = new TestOption();
Dog dog1 = new Dog("Dog1");
dog1.sound = Option.some(new SoundDog());
Dog dog2 = new Dog("Dog2");
dog2.sound = Option.some(new SoundDog());
Cat cat1 = new Cat("Cat1");
cat1.sound = Option.some(new SoundCat());
Cat cat2 = new Cat("Cat2");
dog2.parent = dog1;
cat2.parent = cat1;
zoo.add(dog1);
zoo.add(dog2);
zoo.add(cat1);
zoo.add(cat2);
return zoo;
}
public void add(Animal animal) {
animals.add(animal);
}
public void setAnimals(List<Animal> list) {
this.animals = list;
}
public List<Animal> getAnimals() {
return this.animals;
}
public List<Animal> animals = new ArrayList<Animal>();
}
更新:
我的解決辦法是這樣的:
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import eu.cea.ladis.tools.serializableFJ.Option;
public class TestClass {
public static class MyJsonSerializer extends JsonSerializer<MyObject> {
@Override
public void serialize(MyObject value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeStartObject();
Option<String> myString = value.getMyString();
if(myString.isNone()){
jgen.writeStringField("myString", "null");
}
if(myString.isSome()){
jgen.writeStringField("myString", myString.some());
}
jgen.writeEndObject();
}
}
public static class MyJsonDeserializer extends JsonDeserializer<MyObject> {
@Override
public MyObject deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectCodec oc = jp.getCodec();
JsonNode node = oc.readTree(jp);
return new MyObject(node.get("myString").asText());
}
}
@JsonSerialize(using = MyJsonSerializer.class)
@JsonDeserialize(using = MyJsonDeserializer.class)
public static class MyObject {
public Option<String> myString;
public MyObject() {
super();
myString = Option.some("test string");
}
public MyObject(String myString) {
super();
if(myString != null){
this.myString = Option.some(myString);
}else{
this.myString = Option.none();
}
}
public Option<String> getMyString() {
return myString;
}
}
public static void main(String[] args) throws IOException {
MyObject obj = new MyObject();
ObjectMapper objectMapper = new ObjectMapper();
String json1 = objectMapper.writeValueAsString(obj);
System.out.println("json1>>"+json1);
MyObject obj2 = objectMapper.readValue(json1, MyObject.class);
String json2 = objectMapper.writeValueAsString(obj2);
System.out.println("json2>>"+json2);
System.out.println("Equals: " + json1.equals(json2));
}
}
哪一種JSON庫你使用?如果你使用Jackson marshaller,你可以使用你自己的序列化器/反序列化器,然後實現你自己的序列化/反序列化代碼 –
我使用Jackson ObjectMapper序列化/反序列化。你能用傑克遜編組給你一個例子(或者鏈接)嗎?感謝Angelo Immediata。 –
你可能需要你自己的'JsonDeserializer'。或者,查看mixin。 –