序列化和反序列化过程中JSON属性的不同名称
是否有可能:在类中有一个字段,但在Jackson库中的序列化/反序列化过程中有不同的名称?序列化和反序列化过程中JSON属性的不同名称
例如,我有班级“Coordiantes”。
class Coordinates{
int red;
}
对于从JSON反序列化希望有这样的格式:
{
"red":12
}
但是,当我将序列化对象,结果应该是像这样的:
{
"r":12
}
我试图执行这通过在获取器和设置器上使用@JsonProperty
注释(具有不同的值):
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:我想结合两个不同干将无法识别领域的 “红色”
只是测试,这个工程:
public class Coordinates {
byte red;
@JsonProperty("r")
public byte getR() {
return red;
}
@JsonProperty("red")
public void setRed(byte red) {
this.red = red;
}
}
这个想法是,方法名称应该是不同的,所以杰克逊解析为不同的领域,而不是一个领域。
下面是测试代码:
Coordinates c = new Coordinates();
c.setRed((byte) 5);
ObjectMapper mapper = new ObjectMapper();
System.out.println("Serialization: " + mapper.writeValueAsString(c));
Coordinates r = mapper.readValue("{\"red\":25}",Coordinates.class);
System.out.println("Deserialization: " + r.getR());
结果:
Serialization: {"r":5}
Deserialization: 25
/setter方法对一个变量:
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;
}
}
这不是我所期待的解决方案(虽然它是一个合法的用例)。我的要求是允许现有的buggy客户端(已发布的移动应用程序)使用替代名称。
解决之道在于提供一个单独的setter方法是这样的:
@JsonSetter("r")
public void alternateSetRed(byte red) {
this.red = red;
}
你可以写一个序列化类来做到这一点:
公共类符号
{ 私人字符串符号;
private String name;
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
公共类SymbolJsonSerializer扩展JsonSerializer {
@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();
}
}
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);
他们一定包括这是一个特点,因为现在设置不同@JsonProperty
了getter和setter的结果完全符合你的期望(在同一字段的序列化和反序列化期间,不同的属性名称)。杰克逊版本2.6.7
有可能有正常的getter/setter对。你只需要在@JsonProperty
指定访问模式以下是一个单元测试:
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);
}
}
我得到的输出如下:
Serialized colotObject: {"device_color":"red"}
您可以使用它得到了在引入@jsonAlias杰克逊2.9.0
例如:
public class Info {
@JsonAlias({ "r", "red" })
public String r;
}
[@JsonAlias的文档](http://fasterxml.github.io/jackson-annotations/javadoc/2.9.pr1/com/fasterxml/jackson/annotation/JsonAlias.html)明确声明它在'期间没有效果序列化主要名称始终使用'。这不是OP想要的。 – 2018-02-27 17:35:10
您可以使用@JsonSetter和@JsonGetter的组合来分别控制您的属性的反序列化和序列化。
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;
}
}
是与jaxb可能相同吗? – CuiPengFei 2014-03-22 07:16:18