Different names of JSON property during serialization and deserialization
是否可能:在Jackson库中序列化/反序列化期间,在类中有一个字段,但它有不同的名称?
例如,我有"Coordiantes"课程。
1 2 3 | class Coordinates{ int red; } |
对于来自JSON的反序列化,希望具有如下格式:
1 2 3 | { "red":12 } |
但是当我将序列化对象时,结果应该是这样的:
1 2 3 | { "r":12 } |
我尝试通过在getter和setter(具有不同的值)上应用
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Coordiantes{ int red; @JsonProperty("r") public byte getRed() { return red; } @JsonProperty("red") public void setRed(byte red) { this.red = red; } } |
但我有一个例外:
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field"red"
刚测试过,这个有效:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Coordinates { byte red; @JsonProperty("r") public byte getR() { return red; } @JsonProperty("red") public void setRed(byte red) { this.red = red; } } |
这个想法是方法名称应该是不同的,因此jackson将其解析为不同的字段,而不是一个字段。
这是测试代码:
1 2 3 4 5 6 7 8 |
结果:
1 2 | Serialization: {"r":5} Deserialization: 25 |
您可以使用在jackson 2.9.0中引入的@jsonAlias
例:
1 2 3 4 |
我会将两个不同的getter / setter绑定到一个变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Coordinates{ int red; @JsonProperty("red") public byte getRed() { return red; } public void setRed(byte red) { this.red = red; } @JsonProperty("r") public byte getR() { return red; } public void setR(byte red) { this.red = red; } } |
您可以使用@JsonSetter和@JsonGetter的组合来分别控制反序列化和属性的序列化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.JsonGetter; class Coordinates { private int red; //# Used during serialization @JsonGetter("r") public int getRed() { return red; } //# Used during deserialization @JsonSetter("red") public void setRed(int red) { this.red = red; } } |
这不是我期望的解决方案(尽管它是一个合法的用例)。我的要求是允许现有的错误客户端(已经发布的移动应用程序)使用备用名称。
解决方案在于提供一个单独的setter方法,如下所示:
1 2 3 4 | @JsonSetter("r" ) public void alternateSetRed( byte red ) { this.red = red; } |
可以使用正常的吸气剂/设定剂对。您只需在
这是单元测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class JsonPropertyTest { private static class TestJackson { private String color; @JsonProperty(value ="device_color", access = JsonProperty.Access.READ_ONLY) public String getColor() { return color; }; @JsonProperty(value ="color", access = JsonProperty.Access.WRITE_ONLY) public void setColor(String color) { this.color = color; } } @Test public void shouldParseWithAccessModeSpecified() throws Exception { String colorJson ="{"color":"red"}"; ObjectMapper mapper = new ObjectMapper(); TestJackson colotObject = mapper.readValue(colorJson, TestJackson.class); String ser = mapper.writeValueAsString(colotObject); System.out.println("Serialized colotObject:" + ser); } } |
我得到的输出如下:
1 | Serialized colotObject: {"device_color":"red"} |
它们必须将此作为一个功能包含在内,因为现在为getter和setter设置不同的
我知道这是一个古老的问题但是对我来说,当我发现它与Gson库冲突时我得到了它,所以如果你使用Gson然后使用
您可以编写一个序列化类来执行此操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
1 2 3 4 5 6 7 8 9 10 11 12 | public class SymbolJsonSerializer extends JsonSerializer<Symbol> { @Override public void serialize(Symbol symbol, JsonGenerator jgen, SerializerProvider serializers) throws IOException, JsonProcessingException { jgen.writeStartObject(); jgen.writeStringField("symbol", symbol.getSymbol()); //Changed name to full_name as the field name of Json string jgen.writeStringField("full_name", symbol.getName()); jgen.writeEndObject(); } } |
1 2 3 4 5 6 7 8 9 10 | ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(Symbol.class, new SymbolJsonSerializer()); mapper.registerModule(module); //only convert non-null field, option... mapper.setSerializationInclusion(Include.NON_NULL); String jsonString = mapper.writeValueAsString(symbolList); |