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

我还try 添加了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

推荐答案

解决方案是

@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])

我试过了,它起作用了,你能试一下让我知道它是否起作用吗?

Java相关问答推荐

将偶数元素移动到数组的前面,同时保持相对顺序

日食IDE 2024-03在Ubuntu下崩溃,导致hr_err_pid.log

为什么接口中的主函数而不是类中的主函数在Java 17中编译和运行没有问题?

同时运行JUnit测试和Selenium/Cucumber测试时出现问题

将成为一个比较者.比较…在现代Java中,编译器会对`CompareTo`方法进行优化吗?

为什么一个java函数会返回一个作为参数传递给它的对象?

暂停计时器

对于亚洲/香港,使用ResolverStyle.STRICT的LocalDate.parse返回意外结果

Java ArrayList的整数和数组的泛型

Java连接池无法正常工作

WebSockets和Spring Boot安全性出现错误401

在JDK Flight Recorder中只记录单个线程

如何在ImageIO或十二只猴子中旋转TIFF CMYK图像?

在缺少字段时使用Jackson With Options生成Optional.Empty()

在WHILE()循环初始化部分中声明和初始化变量的Java语法?

如何在Spring Security中设置一个任何人都可以打开的主页?

spring 更新多项管理关系

在不带instanceof或switch的java中记录模式

UuidGenerator Bean 类型不匹配?

类型安全:从 JSONArray 到 ArrayList> 的未经判断的转换