SpringBoot使用Jackson序列化返回方式

 更新时间:2026年05月28日 09:41:54   作者:黑风风  
在SpringBoot应用中,本文详细介绍了如何使用Jackson库处理JSON的序列化和反序列化,包括自定义序列化器、使用@JsonView控制输出和处理日期及枚举类型,Jackson作为高效的JSON处理器,广泛应用于Java环境,特别是与Spring框架集成时

在Spring Boot应用中,使用Jackson库来处理JSON的序列化和反序列化是一种常见的做法。

Jackson是一个高效的JSON处理器,广泛用于Java环境中,尤其是在与Spring框架集成时。

本文将详细介绍如何在Spring Boot中配置和使用Jackson,以实现复杂对象的序列化。

基本配置

在Spring Boot项目中,默认已经集成了Jackson,因此你不需要手动引入Jackson库。

Spring Boot会自动配置Jackson,并将其用作默认的JSON转换库。

以下是一个简单的示例,展示了如何在Spring Boot应用中使用Jackson来序列化一个对象。

实体类定义

假设我们有一个名为User的实体类,包含几个属性:姓名、年龄和邮箱。

import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    private String name;
    private int age;
    private String email;

    // 标准的getter和setter
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

控制器层

在Spring Boot控制器中,你可以直接返回一个对象,Spring MVC会自动使用Jackson将对象序列化为JSON格式。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @GetMapping("/user")
    public User getUser() {
        User user = new User();
        user.setName("张三");
        user.setAge(30);
        user.setEmail("zhangsan@example.com");
        return user;
    }
}

自定义序列化,JsonSerializer

尽管Spring Boot的默认配置通常足够使用,但在某些情况下,你可能需要对Jackson的行为进行定制。以下是一些常见的自定义配置方法。

简单使用

如果你想要自定义某个类的序列化方式,可以通过实现JsonSerializer来实现。

例如,如果你想在序列化User类时隐藏邮箱信息,可以创建一个自定义的序列化器。

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;

public class UserSerializer extends StdSerializer<User> {

    public UserSerializer() {
        this(null);
    }

    public UserSerializer(Class<User> t) {
        super(t);
    }

    @Override
    public void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("name", user.getName());
        jsonGenerator.writeNumberField("age", user.getAge());
        // 不序列化email字段
        jsonGenerator.writeEndObject();
    }
}

整数格式化为千分位

在使用 Jackson 进行序列化时,如果需要将整数(例如 Integer 类型)格式化为带有千分位的字符串(如 “100,000”),可以通过自定义序列化器来实现。

这里我将演示如何创建一个自定义的序列化器,并应用在一个实体类的字段上。

步骤 1: 创建自定义序列化器

首先,我们需要创建一个扩展自 JsonSerializer<T> 的类,专门用于序列化 Integer 字段。

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.text.DecimalFormat;

public class ThousandsFormatterSerializer extends JsonSerializer<Integer> {
    private static final DecimalFormat formatter = new DecimalFormat("#,###");

    @Override
    public void serialize(Integer value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value == null) {
            gen.writeNull();
        } else {
            gen.writeString(formatter.format(value));
        }
    }
}

这个自定义的序列化器使用 DecimalFormat 将整数格式化为千分位字符串。

步骤 2: 应用注解到实体类

现在,你可以使用 @JsonSerialize 注解来指定使用这个自定义序列化器。

将此注解添加到实体类的相应字段上:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public class DataModel {
    private String name;

    @JsonSerialize(using = ThousandsFormatterSerializer.class)
    private Integer amount;

    // 构造函数、getter 和 setter 省略
}

在这个例子中,amount 字段将被格式化为千分位字符串,当 Jackson 序列化这个 DataModel 类的实例时。

步骤 3: 使用和测试

最后,在你的应用程序中创建 DataModel 的实例,并通过 Spring Boot 的 REST 控制器返回它,Jackson 会自动应用这个自定义的序列化器来格式化 amount 字段。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DataController {

    @GetMapping("/formatted-data")
    public DataModel getFormattedData() {
        DataModel data = new DataModel();
        data.setName("Example");
        data.setAmount(100000);
        return data;
    }
}

当你访问这个控制器方法时,你应该会看到如下格式的 JSON 响应:

{
    "name": "Example",
    "amount": "100,000"
}

几个常用的注解

指定序列化和反序列化时JSON对象的属性名。@JsonProperty

  • 指定序列化和反序列化时JSON对象的属性名。
  • 例如,可以将Java字段名从 firstName 映射到 JSON 属性 first_name
public class User {
    @JsonProperty("first_name")
    private String firstName;
}

在序列化和反序列化过程中忽略该属性。@JsonIgnore

在序列化和反序列化过程中忽略该属性。

public class User {
    private String firstName;
    
    @JsonIgnore
    private String password;
}

用于格式化字段,如日期格式。@JsonFormat

用于格式化字段,如日期格式。

public class User {
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private Date birthDate;
}

下面有详细讲

使用@JsonView控制输出

@JsonView 是Jackson提供的一种方式,允许你在同一个类中定义多个视图,根据上下文来序列化不同的属性集合。

这个功能在你需要根据用户的不同权限展示不同级别的数据时特别有用。

定义视图

首先,你需要定义一些视图接口。

这些接口不包含任何方法,它们的目的是为不同的序列化视图提供标记。

public class Views {
    public static class Public {}
    public static class Internal extends Public {}
}

应用视图到实体类

然后,使用@JsonView注解来标注User实体类中的不同字段,这些字段将根据视图的不同而序列化。

public class User {
    @JsonView(Views.Public.class)
    private String name;
    
    @JsonView(Views.Public.class)
    private int age;
    
    @JsonView(Views.Internal.class)
    private String email;

    // getters 和 setters
}

控制器中使用视图

在Spring MVC控制器中,你可以通过@JsonView注解来指定哪个视图应该被用于序列化。

@RestController
public class UserController {

    @GetMapping("/user/public")
    @JsonView(Views.Public.class)
    public User getPublicUser() {
        return createUser();
    }

    @GetMapping("/user/internal")
    @JsonView(Views.Internal.class)
    public User getInternalUser() {
        return createUser();
    }

    private User createUser() {
        User user = new User();
        user.setName("张三");
        user.setAge(30);
        user.setEmail("zhangsan@example.com");
        return user;
    }
}

@JsonView和JsonSerializer混合使用

在Jackson中,@JsonViewJsonSerializer 是可以组合使用的,但这样做可能会导致一些复杂性和冗余。

这两种机制都用于控制JSON序列化的行为,但它们各自适用于不同的场景。

使用场景

  • @JsonView:这是一种较为简洁的方法,用于在不同的上下文中控制哪些属性被包含在JSON中。它适用于简单的情况,比如当同一个对象在不同的API端点返回不同字段时。
  • JsonSerializer:这是一个更为强大和灵活的工具,允许你完全控制一个对象的序列化过程。当你需要对序列化进行详细控制,如改变输出的结构或添加复杂的条件逻辑时,这是一个更好的选择。

组合使用

当你同时使用@JsonViewJsonSerializer时,通常是因为你需要处理非常具体的序列化需求,如下面的示例所示:

public class CustomUserSerializer extends StdSerializer<User> {
    public CustomUserSerializer() {
        super(User.class);
    }

    @Override
    public void serialize(User user, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
        if (provider.getActiveView() != null && provider.getActiveView().equals(Views.Public.class)) {
            gen.writeStringField("name", user.getName());
        }
        if (provider.getActiveView() != null && provider.getActiveView().equals(Views.Internal.class)) {
            gen.writeStringField("email", user.getEmail());
            gen.writeNumberField("age", user.getAge());
        }
        gen.writeEndObject();
    }
}

在这个例子中,CustomUserSerializer 判断当前激活的视图,并根据视图决定序列化哪些字段。这样做虽然增加了灵活性,但也增加了代码的复杂性和维护难度。

处理日期和枚举

处理日期和枚举类型时,可能需要特别注意。Jackson提供了多种方式来定制日期和枚举的序列化方式。

日期格式化

如果你需要自定义日期的格式,可以使用@JsonFormat注解来指定日期字段的格式。

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

public class Event {
    private String name;

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

    // getters 和 setters
}

枚举的自定义序列化

对于枚举类型,你可能想要序列化为不同于默认的名字。使用@JsonValue注解可以指定一个枚举的方法来返回想要序列化的值。

public enum Type {
    FULL_TIME("Full time"),
    PART_TIME("Part time");

    private String value;

    Type(String value) {
        this.value = value;
    }

    @JsonValue
    public String getValue() {
        return value;
    }
}

### 返回结果示例

假设你有一个Java类`Employee`,其中包含一个`Type`枚举字段,如下所示:

```java
public class Employee {
    private String name;
    private Type employmentType;

    public Employee(String name, Type employmentType) {
        this.name = name;
        this.employmentType = employmentType;
    }

    // Getters and Setters
}

在Spring Boot应用中,当你返回一个包含枚举字段的Employee对象时,由于Type枚举使用了@JsonValue,序列化的JSON将反映getValue()方法提供的字符串,而不是枚举的名字。

例如:

@RestController
public class EmployeeController {

    @GetMapping("/employee")
    public Employee getEmployee() {
        return new Employee("张三", Type.FULL_TIME);
    }
}

该端点返回的JSON可能如下所示:

{
    "name": "张三",
    "employmentType": "Full time"
}

这里,employmentType字段显示为"Full time",这是FULL_TIME枚举值的自定义序列化输出。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Java找出两个List中的重复元素三种方法

    使用Java找出两个List中的重复元素三种方法

    在Java编程中,我们经常需要找出两个列表(List)中的重复元素,在本文中,我们将探讨三种方法来实现这一目标,需要的朋友可以参考下
    2023-10-10
  • mybatis类型处理器JSR310标准详解

    mybatis类型处理器JSR310标准详解

    这篇文章主要介绍了mybatis类型处理器JSR310标准详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Tomcat ClassLoader打破双亲委派源码解析

    Tomcat ClassLoader打破双亲委派源码解析

    这篇文章主要为大家介绍了Tomcat ClassLoader打破双亲委派源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • RocketMQ消费幂概念与使用分析

    RocketMQ消费幂概念与使用分析

    如果有⼀个操作,多次执⾏与⼀次执⾏所产⽣的影响是相同的,我们就称这个操作是幂等的。当出现消费者对某条消息重复消费的情况时,重复消费的结果与消费⼀次的结果是相同的,并且多次消费并未对业务系统产⽣任何负⾯影响,那么这整个过程就可实现消息幂等
    2023-02-02
  • SpringBoot项目统一枚举转换实践过程

    SpringBoot项目统一枚举转换实践过程

    文章介绍了在Spring Boot项目中统一枚举转换的实践,通过使用自定义的父枚举接口和AttributeConverter、ConverterFactory、JsonSerializer和JsonDeserializer等工具,实现了枚举与数据库、请求参数、响应参数和消息参数之间的自动转换
    2024-12-12
  • MyBatis中执行相关SQL语句的方法

    MyBatis中执行相关SQL语句的方法

    本文主要介绍了MyBatis中执行相关SQL语句的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-08-08
  • struts2实现多文件上传

    struts2实现多文件上传

    这篇文章主要为大家详细介绍了struts2实现多文件上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • 基于SpringBoot实现邮箱找回密码的代码示例

    基于SpringBoot实现邮箱找回密码的代码示例

    本文主要介绍了如何基于SpringBoot实现邮箱找回密码,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-02-02
  • 深入探讨Java多线程中的volatile变量

    深入探讨Java多线程中的volatile变量

    这篇文章主要为大家详细并深入的探讨Java多线程中的volatile变量,volatile用来确保将变量的更新操作通知到其他线程,保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • springboot使用校验框架validation校验的示例

    springboot使用校验框架validation校验的示例

    这篇文章主要介绍了springboot使用校验框架validation校验的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02

最新评论