Jackson反序列化@JsonFormat 不生效的解决方案

下面是详细讲解“Jackson反序列化@JsonFormat 不生效的解决方案”的完整攻略。

问题背景

在Java开发中,我们常常需要将JSON字符串或者文件反序列化成Java的对象。使用Jackson库是常见的做法,而@JsonFormat注解可以给Java对象的某个属性设置序列化/反序列化的格式。但是有时候我们会发现@JsonFormat注解不生效,即使已经正确地在Java类中设置了该注解,反序列化时仍然不能按照我们期望的格式进行。

解决方案

经过调查,发现在使用Jackson反序列化@JsonFormat时,需要使用ObjectMapper对象来进行反序列化操作,并设置一个JavaTimeModule模块来支持Java 8中的新日期时间类,否则@JsonFormat注解可能不会生效。

下面是具体的代码解析。

首先,我们需要在Java类的日期类型属性上添加@JsonFormat注解。例如:

import com.fasterxml.jackson.annotation.JsonFormat;

public class User {
    private Integer id;
    private String name;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    // Getters and Setters
}

然后,在反序列化时需要调用ObjectMapper的configure()方法,传入一个JavaTimeModule模块。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class Main {
    public static void main(String[] args) throws Exception {
        String json = "{\"id\": 1, \"name\": \"Bob\", \"createTime\": \"2022-12-02 12:34:56\"}";

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());

        User user = objectMapper.readValue(json, User.class);
        System.out.println(user.getCreateTime());
    }
}

在这个例子中,我们使用了一个JSON字符串,通过ObjectMapper的readValue()方法将其反序列化成User对象。需要注意的是,在ObjectMapper的构造函数中,我们调用了registerModule()方法,并将一个JavaTimeModule实例传递进去。这个模块将会支持Java 8新的日期时间处理类。

于是,我们就能够成功反序列化User对象并得到正确的日期时间属性了。

示例

下面提供两个具体的示例,以便更好地理解问题和解决方案。

示例1

在这个示例中,我们定义了一个Student类,其中包含了一个LocalDateTime类型的属性updateTime。我们在属性上添加了@JsonFormat注解,并指定了日期时间的格式为"yyyy-MM-dd HH:mm:ss"。

import com.fasterxml.jackson.annotation.JsonFormat;

import java.time.LocalDateTime;

public class Student {
    private Integer id;
    private String name;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalDateTime getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
    }
}

接着,我们使用ObjectMapper进行反序列化,在main()方法中定义了一个JSON字符串,并使用ObjectMapper的readValue()方法将其反序列化成Student对象。需要注意的是,在ObjectMapper的构造函数中,我们调用了registerModule()方法,并将一个JavaTimeModule实例传递进去。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        String json = "{\"id\": 1, \"name\": \"Alice\", \"updateTime\": \"2022-12-02 12:34:56\"}";

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());

        Student student = objectMapper.readValue(json, Student.class);

        System.out.println(student.getUpdateTime());
    }
}

输出结果为:

2022-12-02T12:34:56

这说明我们成功地反序列化了Student对象,并且日期时间格式符合我们的期望。

示例2

在这个示例中,我们定义了一个Person类,其中包含了一个Date类型的属性birthday。我们在属性上添加了@JsonFormat注解,并指定了日期时间的格式为"yyyy-MM-dd"。

import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.Date;

public class Person {
    private Integer id;
    private String name;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private Date birthday;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

接着,我们使用ObjectMapper进行反序列化,在main()方法中定义了一个JSON字符串,并使用ObjectMapper的readValue()方法将其反序列化成Person对象。同样地,在ObjectMapper的构造函数中,我们调用了registerModule()方法,并将一个JavaTimeModule实例传递进去。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        String json = "{\"id\": 1, \"name\": \"Jack\", \"birthday\": \"1990-05-12\"}";

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());

        Person person = objectMapper.readValue(json, Person.class);

        System.out.println(person.getBirthday());
    }
}

输出结果为:

Fri May 11 20:00:00 PDT 1990

从结果可以看出,我们成功地反序列化了Person对象,但是出现了一个问题:从JSON字符串中反序列化得到的Date对象的时间不正确。这是因为Java 8中的日期时间类和旧版本的日期时间类在序列化/反序列化时,存在不兼容的问题。

解决方案是使用Java 8中的日期时间类。我们只需要更改Person类中的Birthday属性为LocalDate类型,在ObjectMapper的readValue()方法中指定LocalDate类型即可。代码如下:

import com.fasterxml.jackson.annotation.JsonFormat;

import java.time.LocalDate;

public class Person {
    private Integer id;
    private String name;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private LocalDate birthday;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalDate getBirthday() {
        return birthday;
    }

    public void setBirthday(LocalDate birthday) {
        this.birthday = birthday;
    }
}

接着,我们使用ObjectMapper进行反序列化,在main()方法中定义了一个JSON字符串,并使用ObjectMapper的readValue()方法将其反序列化成Person对象。同样地,在ObjectMapper的构造函数中,我们调用了registerModule()方法,并将一个JavaTimeModule实例传递进去。需要注意的是,在readValue()方法中,我们使用了LocalDate.class来指定birthday属性的类型。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.io.IOException;
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) throws IOException {
        String json = "{\"id\": 1, \"name\": \"Jack\", \"birthday\": \"1990-05-12\"}";

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());

        Person person = objectMapper.readValue(json, Person.class);

        System.out.println(person.getBirthday());
    }
}

输出结果为:

1990-05-12

从结果可以看出,我们成功地反序列化了Person对象,并且日期格式也符合了我们的期望。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Jackson反序列化@JsonFormat 不生效的解决方案 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • Windows程序内部运行机制实例详解

    Windows程序内部运行机制实例详解 本篇介绍一些 Windows 程序的内部运行机制,包括程序启动的过程、线程的创建和同步、进程的管理和通信等。本文中的示例是基于 C# 编写的,但是所讲的原理对其他编程语言同样适用。 程序的启动过程 当用户双击一个程序的可执行文件时,操作系统会为该程序创建一个进程。进程是隔离和保护应用程序的一个容器,包括了代码、数据和系…

    C 2023年5月23日
    00
  • Golang异常控制处理程序错误流程

    下面是对于Golang异常控制处理程序错误流程的完整攻略: 什么是异常控制? 在编写程序时,难免会遇到一些错误或异常情况,例如输入数据格式不正确、权限不足、网络连接失败等等,这些异常情况称为异常,并可以通过异常控制来进行处理。 异常控制是指在程序运行出现异常情况时,通过捕获、处理、日志记录等方法进行控制,防止异常情况影响整个程序的运行或导致程序崩溃。 Gol…

    C 2023年5月23日
    00
  • C4D怎么建模三维立体的摩天轮?

    当我们要建模三维立体的摩天轮时,通常需要经过以下步骤: 步骤一:创建摩天轮主体的外形 这个步骤可以用多边形建模实现。我们可以先创建轮廓线,然后再为其赋予一个融合体(Extrude)属性来进行外形建模。这里我们用一个圆形作为轮廓线的基础。具体步骤如下: 打开C4D,再打开新建一个工程。 将“多边形建模”界面的开关打开。(然后,将视图模式切换至左视图模式) 将圆…

    C 2023年5月22日
    00
  • 基于Json序列化和反序列化通用的封装完整代码

    首先我们需要了解Json序列化和反序列化的概念。Json是一种轻量级的数据交换格式,可以用于不同语言之间的数据传递,使得不同语言的程序可以相互通信。而序列化指的是将一个对象转化为Json格式字符串的过程,而反序列化则是将Json格式字符串转换为对应的对象。在实现封装代码时需要使用到Json序列化和反序列化。 基于Json序列化和反序列化通用的封装完整代码的思…

    C 2023年5月23日
    00
  • C语言实现简单推箱子游戏

    C语言实现简单推箱子游戏攻略 游戏概述 推箱子游戏是一款非常经典的智力益智游戏,玩家需要控制箱子的移动,将箱子全部移动到指定位置即可获胜。在本文中,我们将使用C语言来实现一个简单的推箱子游戏。 游戏规则 游戏地图上有若干个箱子和若干个目标点。 箱子只能水平或垂直移动,不能斜着移动。 箱子不能移动到墙上,也不能推到其他的箱子或目标点上。 箱子被推到目标点上后,…

    C 2023年5月22日
    00
  • JS动态遍历json中所有键值对的方法(不知道属性名的情况)

    下面是完整的攻略。 方法概述 在JavaScript中,我们可以使用for…in语句动态遍历一个json对象中所有的键值对(即属性名和属性值)。但是在不知道这个json对象中的属性名的情况下,如果我们希望能够遍历json对象中所有的键值对,就需要使用一个递归函数来实现。 递归函数原理很简单:对于json对象中的每一个属性值,我们可以判断它的数据类型。如果…

    C 2023年5月23日
    00
  • 利用Python绘制好看的玫瑰花图

    下面是利用Python绘制好看的玫瑰花图的完整攻略。 1. 准备工作 在开始绘制玫瑰花图之前,需要安装Python和一些相关的库。其中,绘图库matplotlib是必需的,可以使用pip在命令行中进行安装。其他可能用到的库有numpy、math等。代码示例中会使用以下库: import matplotlib.pyplot as plt import nump…

    C 2023年5月22日
    00
  • C++解决业务办理时间问题示例解析

    C++解决业务办理时间问题示例解析 简介 C++是一种高效且广泛应用于各种领域的编程语言。在处理业务办理时间问题上,C++的高效处理能力可以很好地解决问题。本文将详细讲解如何使用C++解决业务办理时间问题,包括算法分析、编写代码和实际应用。 算法分析 在处理业务办理时间问题时,最重要的是设计合适的算法。我们可以通过以下步骤来实现: 首先,需检查某一个窗口是否…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部