2014-04-09 25 views
2

我在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)); 

} 

} 
+0

哪一種JSON庫你使用?如果你使用Jackson marshaller,你可以使用你自己的序列化器/反序列化器,然後實現你自己的序列化/反序列化代碼 –

+0

我使用Jackson ObjectMapper序列化/反序列化。你能用傑克遜編組給你一個例子(或者鏈接)嗎?感謝Angelo Immediata。 –

+0

你可能需要你自己的'JsonDeserializer'。或者,查看mixin。 –

回答

1

您應該使用aa JsonSerializer和JsonDeserializer這是鏈接到文檔:http://fasterxml.github.io/jackson-databind/javadoc/2.3.0/ 如果你想使用它,一個非常基本的樣本是這樣的(it'sjust樣本....嘗試在自己的代碼contestualize):

public class MyJsonDeserializer extends JsonDeserializer<MyObject> 
{ 
//Deserializer implementation 
} 

@JsonDeserialize(using=MyJsonDeserializer.class) 
public class MyObject 
{ 
    //MyObj properties and methos 
} 

我希望這可以幫助 安傑洛

+0

謝謝安傑洛。我在上面粘貼了我的完整代碼。我的課程需要使用JsonSerializer和JsonDeserializer? –

+0

@ VQ-ANGUYEN通過看到你的代碼我猜你可以將JsonSerializer和JsonDeserializer添加到Animal抽象類(如果我沒有錯,你在Animal類中使用的Option類有問題;所以所有的子類都可以使用自定義解串器/ serilizer –

+0

Thanks @Angelo。我嘗試了一些方法,但它不起作用 如果不是,我發現相同的問題如下 http://stackoverflow.com/questions/10723826/json- serialize-guava-optional/22962690#22962690 –