在杰克逊中序列化/反序列化别名原语,没有太多样板



我有一个类,我想把Java解成一个类。类属性之一本身就是一个可序列化的类,它有一个原始(String(参数,并且真正表示一个别名字符串,即一个字符串,周围有一些额外的东西,以确保它以正确的格式出现。这在各种应用程序(例如标识符(中都很有用,在这种情况下,它是一个必须具有特定表示的 Cron 字符串。所以我有

class ScheduleConfigurations {
private Cron cron;
private Set<Cron> overrides;
// other attributes, getters/setters, constructor
}

class Cron {
private String cronString;
private void validate() { // validates string has correct representation }
// getters, setters, constructor
}

显然,标准的杰克逊反序列化程序需要该格式的JSON。

{
"cron": {
"cronString": "someCronString",
"overrides": [
{ "cronString": "someCronString1" },
{ "cronString": "someCronString2" }
]
}

但是,Cron类显然只是一个别名字符串。我希望上述内容被序列化/反序列化为

{
"cron": "someCronString",
"overrides": ["someCronString1", "someCronString2"]
}

我可以使用带有一堆样板的自定义序列化程序来实现这一点,但我正在寻找一种优雅的方式来对 Jackson 说"嘿,这个类有一个 String 属性,只需传递它并将其序列化表示视为其唯一属性"。

由于您希望将整个对象(反(序列化为字符串,因此非常简单:

@JsonSerialize(using = ToStringSerializer.class)
class Cron {
private String cronString;
public Cron(String cronString) { // Called by Jackson when deserializing from JSON string
this.cronString = cronString;
}
@Override
public String toString() { // Called by Jackson when serializing to JSON
return this.cronString;
}
}

由于类只是字符串的包装器,你甚至不需要getter,setter或其他构造函数,即使是其他Java代码,尽管你当然仍然可以拥有它们。

测试

ScheduleConfigurations configObj = new ScheduleConfigurations();
configObj.setCron(new Cron("someCronString"));
configObj.setOverrides(new LinkedHashSet<>(Arrays.asList(
new Cron("someCronString1"), new Cron("someCronString2"))));
ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper.writeValueAsString(configObj));
String json = "{rn" + 
"  "cron" : "someCronString",rn" + 
"  "overrides" : [ "someCronString1", "someCronString2" ]rn" + 
"}";
ScheduleConfigurations configObj = new ObjectMapper().readValue(json, ScheduleConfigurations.class);
System.out.println("cron = " + configObj.getCron());
System.out.println("overrides = " + configObj.getOverrides());

输出

{
"cron" : "someCronString",
"overrides" : [ "someCronString1", "someCronString2" ]
}
cron = someCronString
overrides = [someCronString1, someCronString2]