Nomes diferentes da propriedade JSON durante a serialização e desserialização

É possível: ter um campo na aula, mas nomes diferentes para ele durante a serialização / desserialização na biblioteca de Jackson?

Por exemplo, eu tenho class “Coordiantes”.

class Coordinates{ int red; } 

Para desserialização do JSON, queira ter um formato como este:

 { "red":12 } 

Mas quando eu vou serializar o object, o resultado deve ser como este:

 { "r":12 } 

Eu tentei implementar isso aplicando a anotação @JsonProperty tanto no getter quanto no setter (com valores diferentes):

 class Coordiantes{ int red; @JsonProperty("r") public byte getRed() { return red; } @JsonProperty("red") public void setRed(byte red) { this.red = red; } } 

mas eu tenho uma exceção:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: campo não reconhecido “vermelho”

   

Apenas testei e isso funciona:

 public class Coordinates { byte red; @JsonProperty("r") public byte getR() { return red; } @JsonProperty("red") public void setRed(byte red) { this.red = red; } } 

A ideia é que os nomes dos methods devem ser diferentes, então jackson analisa isso como campos diferentes, não como um campo.

Aqui está o código de teste:

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

Resultado:

 Serialization: {"r":5} Deserialization: 25 

Você pode usar o @jsonAlias ​​que foi introduzido no jackson 2.9.0

Exemplo:

 public class Info { @JsonAlias({ "r", "red" }) public String r; } 

Eu ligaria dois pares getters / setters diferentes a uma variável:

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

Você pode usar uma combinação de @JsonSetter e @JsonGetter para controlar a desserialização e a serialização de sua propriedade, respectivamente.

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

Isso não era o que eu esperava como solução (embora seja um caso de uso legítimo). Meu requisito era permitir que um cliente com bugs existente (um aplicativo móvel que já foi lançado) usasse nomes alternativos.

A solução está em fornecer um método setter separado como este:

 @JsonSetter( "r" ) public void alternateSetRed( byte red ) { this.red = red; } 

É possível ter par get / setter normal. Você só precisa especificar o modo de access no @JsonProperty

Aqui está o teste unitário para isso:

 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); } } 

Eu tenho a saída da seguinte forma:

 Serialized colotObject: {"device_color":"red"} 

Eles devem ter incluído isso como um recurso, porque agora definir um @JsonProperty diferente para um getter e setter resulta exatamente no que você esperaria (nome de propriedade diferente durante a serialização e desserialização para o mesmo campo). Jackson versão 2.6.7

Você pode escrever uma class serializada para fazer isso:

class pública Símbolo

{private String symbol;

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

}

class pública SymbolJsonSerializer estende 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);