2011-12-19 117 views
98

是否有可能:在類中有一個字段,但在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:我想結合兩個不同干將無法識別領域的 「紅色」

回答

130

只是測試,這個工程:

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

12

/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

4

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

解決之道在於提供一個單獨的setter方法是這樣的:

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

你可以寫一個序列化類來做到這一點:

公共類符號

{ 私人字符串符號;

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

他們一定包括這是一個特點,因爲現在設置不同@JsonProperty了getter和setter的結果完全符合你的期望(在同一字段的序列化和反序列化期間,不同的屬性名稱)。傑克遜版本2.6.7

4

有可能有正常的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"} 
10

您可以使用它得到了在引入@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

0

您可以使用@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; 
    } 
} 
相關問題