提问人:harsh pamnani 提问时间:11/11/2023 更新时间:11/11/2023 访问量:62
当缺少字段时,将 Jackson 与 Optional 一起使用以生成 Optional.empty()
Using Jackson with Optional to generate Optional.empty() when field is missing
问:
我正在使用 Jackson 将 json 字符串转换为 java 对象。我的类中有一个可选字段。 每当我尝试反序列化缺少可选字段的字符串时,它都会为该字段而不是 生成。null
Optional.empty()
代码如下:
public class Main {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
Person1 p1 = mapper.readValue("{\"name\": \"harsh\"}", Person1.class);
System.out.println(p1);
}
}
@EqualsAndHashCode
@ToString
@Getter
@Builder
@NoArgsConstructor(force = true)
public class Person1 {
public final String name;
public final Optional<Integer> age;
public Person1(String name, Optional<Integer> age) {
this.name = name;
this.age = age;
}
}
它生成以下输出:
Person1(name=harsh, age=null)
但是,我希望它生成:
Person1(name=harsh, age=Optional.empty)
我还尝试添加客户反序列化程序,如下所示,但它似乎不起作用:OptionalIntegerDeserializer
public class Person1 {
public final String name;
@JsonDeserialize(using = OptionalIntegerDeserializer.class)
public final Optional<Integer> age;
public Person1(String name, Optional<Integer> age) {
this.name = name;
this.age = age;
}
public static class OptionalIntegerDeserializer extends StdDeserializer<Optional<Integer>> {
public OptionalIntegerDeserializer() {
super(Optional.class);
}
@Override
public Optional<Integer> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonNode node = p.readValueAsTree();
if (node.isNull()) {
return Optional.empty();
} else {
return Optional.of(node.intValue());
}
}
}
}
有没有办法生成而不是缺失的字段?Optional.empty
null
答:
1赞
Ahmed Mera
11/11/2023
#1
解决方案是
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {
private String name;
@JsonDeserialize(using = OptinalDeserializer.class)
@Builder.Default
private Optional<Integer> age = Optional.empty();
}
自定义反序列化是
public class OptionalIntegerDeserializer extends StdDeserializer<Optional<Integer>> {
protected OptionalIntegerDeserializer() {
super(Optional.class);
}
@Override
public Optional<Integer> deserialize(JsonParser parser, DeserializationContext context) {
if (parser.getValueAsInt() > 0 ) {
return Optional.of(parser.getValueAsInt());
} else {
return Optional.empty();
}
}
}
第一次测试
public static void main(String[] args) throws JsonProcessingException {
String s = "{\"name\": \"harsh\"}";
Person p = JsonMapper.builder().build().readValue(s, Person.class);
System.out.println(p);
}
输出 1 为:Person(name=harsh, age=Optional.empty)
第二次测试
public static void main(String[] args) throws JsonProcessingException {
String s = "{\"name\": \"harsh\", \"age\": 19}";
Person p = JsonMapper.builder().build().readValue(s, Person.class);
System.out.println(p);
}
输出 2 为:Person(name=harsh, age=Optional[19])
我试过了,它有效,你能试试吗,让我知道它是否有效。
评论
1赞
harsh pamnani
11/12/2023
了不起。谢谢。它现在使用默认值工作。
1赞
harsh pamnani
11/12/2023
为可选字段添加默认值后,似乎我们甚至不需要自定义反序列化程序。没有它也能正常工作。OptionalIntegerDeserializer
1赞
Ahmed Mera
11/13/2023
我让自定义反序列化程序,因为如果你想在反序列化过程中执行另一个逻辑。
0赞
harsh pamnani
11/13/2023
棒。谢谢。
评论