java - Serialization और deserialization के दौरान JSON संपत्ति के विभिन्न नाम




jackson (6)

क्या यह संभव है: क्लास में एक फ़ील्ड रखना, लेकिन इसके लिए जैक्सन लाइब्रेरी में क्रमबद्धता / deserialization के दौरान इसके लिए अलग-अलग नाम हैं?

उदाहरण के लिए, मेरे पास कक्षा "Coordiantes" है।

class Coordinates{
  int red;
}

JSON से deserialization के लिए इस तरह प्रारूप होना चाहते हैं:

{
  "red":12
}

लेकिन जब मैं ऑब्जेक्ट को क्रमबद्ध कर दूंगा, तो परिणाम इस तरह होना चाहिए:

{
  "r":12
}

मैंने @JsonProperty और सेटर (विभिन्न मूल्यों के साथ) पर @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: अपरिचित फ़ील्ड "लाल"


आप @jsonAlias ​​का उपयोग कर सकते हैं जो जैक्सन 2.9.0 में पेश किया गया था

उदाहरण:

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

आप ऐसा करने के लिए एक धारावाहिक वर्ग लिख सकते हैं:

सार्वजनिक वर्ग प्रतीक

{निजी स्ट्रिंग प्रतीक;

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

}

पब्लिक क्लास सिंबलजेसनसेरियलज़र जेसनएसरियललाइज़र का विस्तार करता है {

@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 और सेटर परिणामों के लिए एक अलग @JsonProperty सेट करना है जो आप उम्मीद करेंगे (सीरियलाइजेशन के दौरान अलग-अलग संपत्ति का नाम और उसी क्षेत्र के लिए deserialization)। जैक्सन संस्करण 2.6.7


बस परीक्षण किया और यह काम करता है:

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

यह वह नहीं था जिसे मैं समाधान के रूप में उम्मीद कर रहा था (हालांकि यह एक वैध उपयोग मामला है)। मेरी आवश्यकता वैकल्पिक नामों का उपयोग करने के लिए मौजूदा बग्गी क्लाइंट (एक मोबाइल ऐप जो पहले ही रिलीज़ हुई) को अनुमति देना था।

समाधान इस तरह एक अलग सेटर विधि प्रदान करने में निहित है:

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

सामान्य गेटर / सेटर जोड़ी होना संभव है। आपको बस @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"}




jackson