当字段缺失时,使用 Jackson 和Optional 生成Optional.empty()

问题描述 投票:0回答:1

我正在使用 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

java jackson jackson-databind
1个回答
0
投票

解决办法是

@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
    @SneakyThrows({IOException.class})
    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])

我试过了,它有效,你可以尝试一下并让我知道它是否有效。

© www.soinside.com 2019 - 2024. All rights reserved.