2011-12-19 26 views
98

Có thể: có một trường trong lớp, nhưng các tên khác nhau cho nó trong quá trình tuần tự hóa/deserialization trong thư viện Jackson?Tên khác nhau của thuộc tính JSON trong quá trình tuần tự hóa và deserialization

Ví dụ: tôi có lớp "Điều phối".

class Coordinates{ 
    int red; 
} 

Đối deserialization từ JSON muốn có định dạng như thế này:

{ 
    "red":12 
} 

Nhưng khi tôi sẽ serialize đối tượng, kết quả sẽ như thế này một:

{ 
    "r":12 
} 

tôi cố gắng thực hiện điều này bằng cách áp dụng chú thích @JsonProperty cả trên getter và setter (với các giá trị khác nhau):

class Coordiantes{ 
    int red; 

    @JsonProperty("r") 
    public byte getRed() { 
     return red; 
    } 

    @JsonProperty("red") 
    public void setRed(byte red) { 
     this.red = red; 
    } 
} 

nhưng tôi có một ngoại lệ:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Không nhận ra lĩnh vực "đỏ"

Trả lời

130

Chỉ cần kiểm tra và làm việc này:

public class Coordinates { 
    byte red; 

    @JsonProperty("r") 
    public byte getR() { 
     return red; 
    } 

    @JsonProperty("red") 
    public void setRed(byte red) { 
     this.red = red; 
    } 
} 

Ý tưởng là tên của phương thức phải khác nhau, vì vậy, jackson phân tích cú pháp dưới dạng các trường khác nhau, không phải là một trường.

Đây là mã kiểm tra:

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

Kết quả:

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

là cùng có thể với jaxb? – CuiPengFei

12

tôi sẽ ràng buộc hai thu khí khác nhau/setters cặp với một biến:

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

Nhưng trong trường hợp này, trong quá trình tuần tự hóa, chúng tôi sẽ nhận cả hai thuộc tính: "r" và "đỏ", có cùng giá trị. – kiRach

+0

làm việc cho tôi, câu trả lời ở trên không như vậy +1 – Tim

4

Đây không phải là những gì tôi đã mong đợi như một giải pháp (mặc dù nó là một trường hợp sử dụng hợp pháp). Yêu cầu của tôi là cho phép ứng dụng lỗi hiện tại (một ứng dụng di động đã phát hành) sử dụng tên thay thế.

Giải pháp nằm trong việc cung cấp một phương pháp setter riêng biệt như thế này:

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

Bạn có thể viết một lớp serialize để làm điều đó:

public class Symbol

{ Chuỗi biểu tượng tư nhân;

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

}

public class SymbolJsonSerializer kéo dài 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

Họ phải đã bao gồm này như một tính năng, bởi vì bây giờ thiết lập một khác nhau @JsonProperty cho một getter và setter kết quả chính xác những gì bạn mong đợi (tên thuộc tính khác nhau trong quá trình tuần tự hóa và deserialization cho cùng một lĩnh vực). Jackson phiên bản 2.6.7

4

Có thể có cặp getter/setter bình thường. Bạn chỉ cần để xác định chế độ truy cập trong @JsonProperty

Đây là thử nghiệm đơn vị cho rằng:

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

tôi có đầu ra như sau:

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

Bạn có thể sử dụng @jsonAlias ​​mà đã được giới thiệu trong jackson 2.9.0

Ví dụ:

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

[tài liệu cho @JsonAlias] (http://fasterxml.github.io/jackson-annotations/javadoc/2.9.pr1/com/fasterxml/jackson/annotation/JsonAlias.html) tuyên bố rõ ràng rằng nó 'không có hiệu lực trong thời gian serialization nơi tên chính luôn được sử dụng'. Đây không phải là những gì OP muốn. –

0

Bạn có thể sử dụng kết hợp @JsonSetter@JsonGetter để kiểm soát quá trình tuần tự hóa và tuần tự hóa thuộc tính của bạn.

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; 
    } 
} 
Các vấn đề liên quan