【问题标题】:fasterxml serialize using toString and deserialize using String constructorfastxml 使用 toString 序列化和使用 String 构造函数反序列化
【发布时间】:2015-10-12 16:36:32
【问题描述】:

我有一个看起来像这样的 POJO:

public class Thing
{
   private final int x;
   private final int y;
   private final int z;

   public Thing(String strThing)
   {
       // parse strThing which is in some arbitrary format to set x, y and z
   }

   @Override
   public String toString()
   {
       // return a string representation of thing
       // (same format as that parsed by the constructor)
   }

   @Override
   public boolean equals(Object obj) ...

   @Override
   public int hashCode() ...

}

我想将它用作映射的键​​(例如HashMap<Thing, SomeOtherPOJO>),当序列化为 json 时,使用 Thing 的 toString() 表示作为键,而在反序列化时,使用 String 构造函数。这可以使用像杰克逊数据绑定注释这样简单的东西吗?解决这个问题的最佳方法是什么?

【问题讨论】:

    标签: java json dictionary fasterxml


    【解决方案1】:

    通过实验(我认为文档可能对此更清楚一点)我发现我可以在String 构造函数上使用JsonCreator 注释,在toString() 方法上使用JsonValue 来实现什么我要:

    public class Thing
    {
       private final int x;
       private final int y;
       private final int z;
    
       @JsonCreator
       public Thing(String strThing)
       {
           // parse strThing which is in some arbitrary format to set x, y and z
       }
    
       @Override
       @JsonValue
       public String toString()
       {
           // return a string representation of thing
           // (same format as that parsed by the constructor)
       }
    
       @Override
       public boolean equals(Object obj) ...
    
       @Override
       public int hashCode() ...
    
    }
    

    【讨论】:

    • 高效方法
    • 你会认为这样一个可爱的节省时间的人会用粗体字突然出现,但可惜编写好的文档的能力似乎正在消亡。
    【解决方案2】:

    您可以创建一个扩展 JsonSerializer 并覆盖其序列化方法的新类。将您应该在 toString() 方法中编写的实现写入 JsonGenerator 的 writeString() 方法,如图所示。您必须在项目中使用 jackson-core-asl.jar 和 jackson-mapper-asl.jar。下面是 JsonThingSerializer.java 类

    import java.io.IOException;
    import org.codehaus.jackson.JsonGenerator;
    import org.codehaus.jackson.JsonProcessingException;
    import org.codehaus.jackson.map.JsonSerializer;
    import org.codehaus.jackson.map.SerializerProvider;
    
    
    public class JsonThingSerializer extends JsonSerializer<Thing>{ //note use of generics
    
    @Override
    public void serialize(Thing myThing, JsonGenerator gen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
    
        gen.writeString("I want this way.. which I was thinking to implement inside toString() method "+" "+myThing.getX()+" "+myThing.getY()+" "+myThing.getZ());
    }
    
    }
    

    在你的 Thing.java 中使用下面的注解

    import org.codehaus.jackson.annotate.JsonAutoDetect;
    import org.codehaus.jackson.map.annotate.JsonSerialize;
    
    @JsonAutoDetect
    @JsonSerialize(using=JsonThingSerializer.class)
    public class Thing
    {
       private final int x;
       private final int y;
       private final int z;
    
       public Thing(String strThing)
       {
           // parse strThing which is in some arbitrary format to set x, y and z
           //insert your own implementation to get x, y and z
           x=y=z=10;
       }
    
       @Override
       public String toString()
       {
           //no need to override this for json serialization.. mapper will not use it
       }
    
       @Override
       public boolean equals(Object obj){
         //you can have your own implementation
       }
    
       @Override
       public int hashCode() {
         //you can have your own implementation
        }
    
    public int getX() {
        return x;
    }
    
    public int getY() {
        return y;
    }
    
    public int getZ() {
        return z;
    }
    
    }
    

    您可以使用以下代码测试您的代码。

    import java.io.IOException;
    import org.codehaus.jackson.JsonGenerationException;
    import org.codehaus.jackson.map.JsonMappingException;
    import org.codehaus.jackson.map.ObjectMapper;
    
    public class TestJsonSerialization {
    
        public static void main(String[] args) {
    
            Thing thing =new Thing("your strThing which is in some arbitrary format to set x, y and z");
            ObjectMapper mapper =new ObjectMapper();
            try {
                String thingString = mapper.writeValueAsString(thing);
                System.out.println(thingString);
            } catch (JsonGenerationException e) {
                e.printStackTrace();
            } catch (JsonMappingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    

    Blow 是输出:

    “我想要这种方式.. 我想在 toString() 方法 10 10 10 中实现”

    【讨论】:

    • 我发现有一种更简单的方法可以实现这一点。看我的回答。
    • 如果您想序列化/反序列化成员并且您不控制成员类的源,这将非常有用(但您需要使用 JsonSerializeJsonDeserialize 注释成员而是)。
    猜你喜欢
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    相关资源
    最近更新 更多