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

参考


相关文章
|
17天前
|
缓存 前端开发 Java
【Java】仓库管理系统 SpringBoot+LayUI+DTree(源码)【独一无二】
【Java】仓库管理系统 SpringBoot+LayUI+DTree(源码)【独一无二】
|
1月前
|
JSON JavaScript 前端开发
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
33 0
|
1月前
|
JSON 前端开发 JavaScript
|
22天前
|
Java 应用服务中间件 Spring
SpringBoot出现 java.lang.IllegalArgumentException: Request header is too large 解决方法
SpringBoot出现 java.lang.IllegalArgumentException: Request header is too large 解决方法
39 0
|
1天前
|
人工智能 前端开发 Java
Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码
智慧导诊解决盲目就诊问题,减轻分诊工作压力。降低挂错号比例,优化就诊流程,有效提高线上线下医疗机构接诊效率。可通过人体画像选择症状部位,了解对应病症信息和推荐就医科室。
27 10
|
1天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
2天前
|
存储 数据可视化 安全
Java全套智慧校园系统源码springboot+elmentui +Quartz可视化校园管理平台系统源码 建设智慧校园的5大关键技术
智慧校园指的是以物联网为基础的智慧化的校园工作、学习和生活一体化环境,这个一体化环境以各种应用服务系统为载体,将教学、科研、管理和校园生活进行充分融合。无处不在的网络学习、融合创新的网络科研、透明高效的校务治理、丰富多彩的校园文化、方便周到的校园生活。简而言之,“要做一个安全、稳定、环保、节能的校园。
20 6
|
10天前
|
缓存 前端开发 Java
SpringBoot启动后加载初始化数据
SpringBoot启动后加载初始化数据
|
11天前
|
XML JSON JavaScript
Java中XML和JSON的比较与应用指南
本文对比了Java中XML和JSON的使用,XML以自我描述性和可扩展性著称,适合结构复杂、需验证的场景,但语法冗长。JSON结构简洁,适用于轻量级数据交换,但不支持命名空间。在Java中,处理XML可使用DOM、SAX解析器或XPath,而JSON可借助GSON、Jackson库。根据需求选择合适格式,注意安全、性能和可读性。
23 0
|
16天前
|
JavaScript Java 关系型数据库
基于 java + Springboot + vue +mysql 大学生实习管理系统(含源码)
本文档介绍了基于Springboot的实习管理系统的设计与实现。系统采用B/S架构,旨在解决实习管理中的人工管理问题,提高效率。系统特点包括对用户输入的验证和数据安全性保障。功能涵盖首页、个人中心、班级管理、学生管理、教师管理、实习单位管理、实习作业管理、教师评分管理、单位成绩管理和系统管理等。用户分为管理员、教师和学生,各自有不同的操作权限。