fasterxml 使用 toString 序列化并使用 String 构造函数反序列化
fasterxml serialize using toString and deserialize using String constructor
我有一个看起来像这样的 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 构造函数。这可能使用像杰克逊数据绑定注释这样简单的东西吗?解决这个问题的最佳方法是什么?
您可以创建一个新的 class 来扩展 JsonSerializer 并覆盖其序列化方法。将您应该在 toString() 方法中编写的实现写入 JsonGenerator 的 writeString() 方法,如图所示。您必须在项目中使用 jackson-core-asl.jar 和 jackson-mapper-asl.jar。下面是JsonThingSerializer.javaclass
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();
}
}
}
打击是输出:
"I want this way.. which I was thinking to implement inside toString() method 10 10 10"
通过实验(我认为文档在这方面可能更清楚一些)我发现我可以在 String
构造函数上使用 JsonCreator
注释,在toString()
方法来实现我想要的:
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() ...
}
我有一个看起来像这样的 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 构造函数。这可能使用像杰克逊数据绑定注释这样简单的东西吗?解决这个问题的最佳方法是什么?
您可以创建一个新的 class 来扩展 JsonSerializer 并覆盖其序列化方法。将您应该在 toString() 方法中编写的实现写入 JsonGenerator 的 writeString() 方法,如图所示。您必须在项目中使用 jackson-core-asl.jar 和 jackson-mapper-asl.jar。下面是JsonThingSerializer.javaclass
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();
}
}
}
打击是输出:
"I want this way.. which I was thinking to implement inside toString() method 10 10 10"
通过实验(我认为文档在这方面可能更清楚一些)我发现我可以在 String
构造函数上使用 JsonCreator
注释,在toString()
方法来实现我想要的:
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() ...
}