12

我有一个看起来像这样的 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 构造函数。这可以使用像杰克逊数据绑定注释这样简单的东西吗?解决这个问题的最佳方法是什么?

4

2 回答 2

32

通过实验(我认为文档可能会更清楚一点)我发现我可以在构造函数和方法上使用JsonCreator注释来实现我想要的:StringJsonValuetoString()

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() ...

}
于 2015-07-23T09:56:26.060 回答
3

您可以创建一个扩展 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 中实现”

于 2015-07-22T18:33:18.463 回答