序列化和反序列化过程中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 
+0

是与jaxb可能相同吗? – CuiPengFei 2014-03-22 07:16:18

/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; 
    } 
} 
+6

但是在这种情况下,在序列化过程中,我们将得到两个属性:“r”和“red”,具有相同的值。 – kiRach 2011-12-19 11:24:27

+0

为我工作,上面的答案没有那么+1 – Tim 2013-08-23 17:48:47

这不是我所期待的解决方案(虽然它是一个合法的用例)。我的要求是允许现有的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; 
} 
+0

[@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; 
    } 
}