직렬화 및 역 직렬화 중에 다른 JSON 속성 이름
가능합니까 : Jackson 라이브러리에서 직렬화 / 직렬화 해제 중에 클래스에 하나의 필드를 갖지만 다른 이름을 갖는 것이 가능합니까?
예를 들어 클래스 "Coordiantes"가 있습니다.
class Coordinates{
int red;
}
JSON에서 직렬화 해제하려면 다음과 같은 형식을 원합니다.
{
"red":12
}
그러나 객체를 직렬화 할 때 결과는 다음과 같아야합니다.
{
"r":12
}
@JsonProperty
getter와 setter (다른 값으로)에 주석 을 적용하여 이것을 구현하려고했습니다 .
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 : 인식 할 수없는 필드 "빨간색"
방금 테스트했으며 작동합니다.
public class Coordinates {
byte red;
@JsonProperty("r")
public byte getR() {
return red;
}
@JsonProperty("red")
public void setRed(byte red) {
this.red = red;
}
}
아이디어는 메소드 이름이 달라야하므로 Jackson은이를 하나의 필드가 아닌 다른 필드로 구문 분석합니다.
테스트 코드는 다음과 같습니다.
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
jackson 2.9.0에 도입 된 @jsonAlias를 사용할 수 있습니다
예:
public class Info {
@JsonAlias({ "r", "red" })
public String r;
}
I would bind two different getters/setters pair to one variable:
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;
}
}
You can use a combination of @JsonSetter, and @JsonGetter to control the deserialization, and serialization of your property, respectively. This will also allow you to keep standardized getter and setter method names that correspond to your actual field name.
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;
}
}
This was not what I was expecting as a solution (though it is a legitimate use case). My requirement was to allow an existing buggy client (a mobile app which already released) to use alternate names.
The solution lies in providing a separate setter method like this:
@JsonSetter( "r" )
public void alternateSetRed( byte red ) {
this.red = red;
}
It's possible to have normal getter/setter pair. You just need to specify access mode in @JsonProperty
Here is unit test for that:
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);
}
}
I got the output as follows:
Serialized colotObject: {"device_color":"red"}
They must have included this as a feature, because now setting a different @JsonProperty
for a getter and setter results in exactly what you would expect (different property name during serialization and deserialization for the same field). Jackson version 2.6.7
You can write a serialize class to do that:
public class Symbol
{
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;
}
}
public class SymbolJsonSerializer extends JsonSerializer<Symbol> {
@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);
I know its an old question but for me I got it working when I figured out that its conflicting with Gson library so if you are using Gson then use @SerializedName("name")
instead of @JsonProperty("name")
hope this helps
'IT' 카테고리의 다른 글
angularJS에서 여러 값을 필터링하는 방법 (또는 연산) (0) | 2020.06.29 |
---|---|
특정 값을 가진 stl 벡터에서 항목을 어떻게 제거합니까? (0) | 2020.06.29 |
세그먼테이션 오류를 일으키는 코드 줄을 결정 하시겠습니까? (0) | 2020.06.29 |
"사용"블록에서 SqlConnection이 반환 또는 예외로 닫혔습니까? (0) | 2020.06.29 |
JSONArray를 반복 할 수 있습니까? (0) | 2020.06.29 |