java - parser - spring boot jackson




序列化和反序列化過程中JSON屬性的不同名稱 (6)

是否有可能:在類庫中有一個字段,但在Jackson庫中的序列化/反序列化過程中有不同的名稱?

例如,我有班級“Coordiantes”。

class Coordinates{
  int red;
}

從JSON反序列化想要有這樣的格式:

{
  "red":12
}

但是當我要序列化對象時,結果應該是這樣的:

{
  "r":12
}

我試圖通過在getter和setter(具有不同的值)上應用@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:無法識別的字段“紅色”


你可以使用@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;
    }
}

你可以使用在jackson 2.9.0中引入的@jsonAlias

例:

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

剛剛測試過,這個工程:

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

它們必須包含此功能,因為現在為getter和setter設置不同的@JsonProperty導致您期望的結果(在同一字段的序列化和反序列化期間不同的屬性名稱)。 傑克遜版本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"}

這不是我期望的解決方案(儘管這是一個合法的用例)。 我的要求是允許現有的buggy客戶端(已發布的移動應用程序)使用替代名稱。

解決方案在於提供像這樣的單獨的setter方法:

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




jackson