gpt4 book ai didi

java - 基于字段值的 Jackson 属性顺序

转载 作者:太空宇宙 更新时间:2023-11-04 09:48:33 24 4
gpt4 key购买 nike

我正在尝试使用 Jackson 序列化和反序列化 Java 类,并且 JsonPropertyOrder 取决于类中 version 字段的值。如果 version = 1,我希望顺序为 {"start1", "start2"},如果 version = 2,顺序应为 {"end1", "end2"}
我有以下类(class):

 @Builder
@Value
@AllArgsConstructor(onConstructor=@__(@JsonCreator))
@JsonPropertyOrder(custom property order depending on version field)
public class ClassA {

@NonNull Integer version;

@NonNull String start1;

@NonNull String start2;

@NonNull String end1;

@NonNull String end2;
}

如何根据运行时的版本定义JsonPropertyOrder。如果我应该使用自定义的Deserializer,我无法弄清楚应该如何使用ObjectMapper 来实现和设置它。

这是反序列化的代码:

private final ObjectMapper objectMapper = new ObjectMapper();//have initialzed this as a bean
String jsonStr = "{\"version\":1, \"startLat\":\"47.6812\", \"startLng\":\"-122.3268\", \"endLat\":\"47.6074\", \"endLng\":\"-122.3377\"}";
ClassA objA = null;
try {
objA = objectMapper.readValue(jsonStr, ClassA.class);
} catch (IOException e) {
log.error("Error deserializing the string", jsonStr, e);
}
return objA;

**编辑:我错过了一个小鬼部分。这里的属性顺序很重要,因为序列化字符串可能没有字段名称。这可能吗?因此,str [1, "47.6812", "-122.3268"] 需要反序列化为字段版本 start1start2

最佳答案

如果这些属性是独占的,为什么不通过删除其中两个来创建更简洁的 POJO?您可以通过引入一些 isMethod-es 或 Enum 来了解 12 的含义不同。要将类序列化为 JSON 数组,您需要使用 @JsonFormat(shape = JsonFormat.Shape.ARRAY) 注释。要反序列化,您可以使用带有 @JsonCreator@JsonProperty 注释的 3-arg 构造函数。属性是最终。所有这些共同使得类得到很好的实现。请参阅示例:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Objects;

public class JsonApp {

public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();

ClassA classA1 = new ClassA(1, "Start_1", "Start_2");
ClassA classA2 = new ClassA(2, "End_1", "End_2");

String json1 = mapper.writeValueAsString(classA1);
String json2 = mapper.writeValueAsString(classA2);

System.out.println(json1);
System.out.println(json2);

System.out.println(mapper.readValue(json1, ClassA.class));
System.out.println(mapper.readValue(json2, ClassA.class));
}
}

@JsonFormat(shape = JsonFormat.Shape.ARRAY)
class ClassA {

private final Integer version;

private final String value1;
private final String value2;

@JsonCreator
public ClassA(@JsonProperty("version") Integer version,
@JsonProperty("start1") String value1,
@JsonProperty("start2") String value2) {
Objects.requireNonNull(version);
if (!(version == 1 || version == 2)) {
throw new IllegalArgumentException("Version is not supported!");
}
this.version = version;
this.value1 = value1;
this.value2 = value2;
}

@JsonIgnore
public boolean isStart() {
return version == 1;
}

@JsonIgnore
public boolean isEnd() {
return version == 2;
}

public Integer getVersion() {
return version;
}

public String getValue1() {
return value1;
}

public String getValue2() {
return value2;
}

@Override
public String toString() {
return "ClassA{" +
"version=" + version +
", value1='" + value1 + '\'' +
", value2='" + value2 + '\'' +
", isEnd()='" + isEnd() + '\'' +
", isStart()='" + isStart() + '\'' +
'}';
}
}

上面的代码打印:

[1,"Start_1","Start_2"]
[2,"End_1","End_2"]
ClassA{version=1, value1='Start_1', value2='Start_2', isEnd()='false', isStart()='true'}
ClassA{version=2, value1='End_1', value2='End_2', isEnd()='true', isStart()='false'}

关于java - 基于字段值的 Jackson 属性顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55113060/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com