Java:SpringBoot返回json数据时间格式、命名风格、忽略字段返回

简介: Java:SpringBoot返回json数据时间格式、命名风格、忽略字段返回

SpringBoot返回json数据是很常见的需求,我们可以通过配置来控制实体对象的输出形式

目录

版本依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.7</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

通过一个简单的SpringBoot项目测试json数据返回格式

对象实体

package com.example.demo.dto;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
@Data
public class User {
    private String name;
    private Integer age;
    private String password;
    private Date birthday;
    private LocalDateTime localDateTime;
    private LocalDate localDate;
    private LocalTime localTime;
    private LocalDateTime localDateTimeFormat;
}

控制器

package com.example.demo.controller;
import com.example.demo.dto.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
@RestController
public class UserController {
    @GetMapping("/user")
    @ResponseBody
    public User getUser(){
        User user = new User();
        user.setAge(20);
        user.setName("tom");
        user.setPassword("123456");
        user.setBirthday(new Date());
        user.setLocalDateTime(LocalDateTime.now());
        user.setLocalDate(LocalDate.now());
        user.setLocalTime(LocalTime.now());
        user.setLocalDateTimeFormat(LocalDateTime.now());
        return user;
    }
}

默认返回

没有任何配置,直接输出对象,可以得到一个如下的json数据(前端看了想打人)

{
    "name":"tom",
    "age":20,
    "password":"123456",
    "birthday":1677250587064,
    "localDateTime":[ 2023, 2, 24, 22, 56, 27, 64000000],
    "localDate":[ 2023, 2, 24],
    "localTime":[ 22, 56, 27, 64000000],
    "localDateTimeFormat":[ 2023, 2, 24, 22, 56, 27, 64000000]
}

或者(测试几次发现日期格式输出竟然不固定)

{
    "name": "tom",
    "age": 20,
    "password": "123456",
    "birthday": "2023-02-24T23:24:08.956+00:00",
    "localDateTime": "2023-02-25T07:24:08.956",
    "localDate": "2023-02-25",
    "localTime": "07:24:08.956",
    "localDateTimeFormat": "2023-02-25T07:24:08.956"
}

默认返回数据有几个问题:

  1. 密码字段password不需要返回
  2. 时间格式Date 返回的是13位时间戳
  3. 时间格式LocalDateTimeLocalDateLocalTime返回的是数组格式
  4. 字段名是小驼峰个格式,大部分情况需要返回蛇形的下划线小写格式

通过配置格式化

添加配置 application.yml

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

返回数据

{
    "name": "tom",
    "age": 20,
    "password": "123456",
    "birthday": "2023-02-25 07:25:56",
    "localDateTime": "2023-02-25T07:25:56.509",
    "localDate": "2023-02-25",
    "localTime": "07:25:56.51",
    "localDateTimeFormat": "2023-02-25T07:25:56.51"
}

可以看到,只有Date类型的birthday参数生效了

通过注解实现属性设置

通过几个注解,实现实体对象转为json的属性设置

注解 作用
@JsonIgnoreProperties 批量设置转 JSON 时忽略的属性
@JsonIgnore 转 JSON 时忽略当前属性
@JsonProperty 修改转换后的 JSON 的属性名
@JsonFormat 转 JSON 时格式化属性的值

返回对象实体

package com.example.demo.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
@Data
public class User {
    private String name;
    private Integer age;
    // 忽略属性
    @JsonIgnore
    private String password;
    // 修改属性名
    @JsonProperty("birthDay")
    private Date birthday;
    private LocalDateTime localDateTime;
    private LocalDate localDate;
    private LocalTime localTime;
    // 格式化
    @JsonFormat(pattern = "yyyy年MM月dd日")
    private LocalDateTime localDateTimeFormat;
}

返回结果

{
    "name": "tom",
    "age": 20,
    "localDateTime": "2023-02-25T07:32:57.637",
    "localDate": "2023-02-25",
    "localTime": "07:32:57.637",
    "localDateTimeFormat": "2023年02月25日",
    "birthDay": "2023-02-25 07:32:57"
}

通过以上配置,我们实现了

  1. 不返回密码字段password
  2. 自定义了字段localDateTimeFormat的时间格式
  3. 自定义了字段birthday的命名风格改为了小驼峰形式birthDay

目前为止,localDateTimelocalTime还没有处理到

全局配置

继承WebMvcConfigurationSupport类,覆写方法

protected void extendMessageConverters(List<HttpMessageConverter<?>> converters){}

WebMvcConfig

package com.example.demo.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
@Configuration
@Slf4j
public class WebMvcConfig extends WebMvcConfigurationSupport {
    /**
     * 扩展消息转换器
     *
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        // 设置对象转换器
        messageConverter.setObjectMapper(new JacksonObjectMapper());
        // 添加到mvc框架消息转换器中,优先使用自定义转换器
        converters.add(0, messageConverter);
    }
}

JacksonObjectMapper

package com.example.demo.config;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {
    private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    private static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
    public JacksonObjectMapper() {
        super();
        // 收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 统一返回数据的输出风格 转为蛇形命名法
        this.setPropertyNamingStrategy(new PropertyNamingStrategies.SnakeCaseStrategy());
        // 反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig()
                .withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 格式化时间
        JavaTimeModule module = new JavaTimeModule();
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addDeserializer(Date.class, new DateDeserializers.DateDeserializer())
                // .addSerializer(BigInteger.class, ToStringSerializer.instance)
                // .addSerializer(Long.class, ToStringSerializer.instance)
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT)))
                ;
        // 注册功能模块 添加自定义序列化器和反序列化器
        this.registerModule(module);
    }
}

最终效果

{
    "name": "tom",
    "age": 20,
    "local_date_time": "2023-02-25 07:56:22",
    "local_date": "2023-02-25",
    "local_time": "07:56:22",
    "local_date_time_format": "2023年02月25日",
    "birthDay": "2023-02-25 07:56:22"
}

至此,我们解决了一开始的几个格式问题

完整代码: https://mouday.github.io/spring-boot-demo/#/SpringBoot-JSON/README

参考


相关文章
|
5月前
|
自然语言处理 Java 关系型数据库
Java|小数据量场景的模糊搜索体验优化
在小数据量场景下,如何优化模糊搜索体验?本文分享一个简单实用的方案,虽然有点“土”,但效果还不错。
81 0
|
6月前
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
7月前
|
数据采集 JSON Java
Java爬虫获取微店快递费用item_fee API接口数据实现
本文介绍如何使用Java开发爬虫程序,通过微店API接口获取商品快递费用(item_fee)数据。主要内容包括:微店API接口的使用方法、Java爬虫技术背景、需求分析和技术选型。具体实现步骤为:发送HTTP请求获取数据、解析JSON格式的响应并提取快递费用信息,最后将结果存储到本地文件中。文中还提供了完整的代码示例,并提醒开发者注意授权令牌、接口频率限制及数据合法性等问题。
|
8月前
|
存储 NoSQL Java
使用Java和Spring Data构建数据访问层
本文介绍了如何使用 Java 和 Spring Data 构建数据访问层的完整过程。通过创建实体类、存储库接口、服务类和控制器类,实现了对数据库的基本操作。这种方法不仅简化了数据访问层的开发,还提高了代码的可维护性和可读性。通过合理使用 Spring Data 提供的功能,可以大幅提升开发效率。
174 21
|
7月前
|
Java API 数据处理
深潜数据海洋:Java文件读写全面解析与实战指南
通过本文的详细解析与实战示例,您可以系统地掌握Java中各种文件读写操作,从基本的读写到高效的NIO操作,再到文件复制、移动和删除。希望这些内容能够帮助您在实际项目中处理文件数据,提高开发效率和代码质量。
164 4
|
8月前
|
存储 分布式计算 Hadoop
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
254 7
|
8月前
|
SQL Java 数据库连接
【潜意识Java】深入理解MyBatis的Mapper层,以及让数据访问更高效的详细分析
深入理解MyBatis的Mapper层,以及让数据访问更高效的详细分析
933 1
|
4月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
350 1
|
5月前
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
364 7
|
4月前
|
供应链 JavaScript BI
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发
这是一款专为小微企业打造的 SaaS ERP 管理系统,基于 SpringBoot+Vue+ElementUI+UniAPP 技术栈开发,帮助企业轻松上云。系统覆盖进销存、采购、销售、生产、财务、品质、OA 办公及 CRM 等核心功能,业务流程清晰且操作简便。支持二次开发与商用,提供自定义界面、审批流配置及灵活报表设计,助力企业高效管理与数字化转型。
376 2
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发

热门文章

最新文章