【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之Spring定义Jackson转换Null的方法和实现案例

Spring自动定义Jackson转换Null得方法

  • 背景
    • MessageConverter
  • 使用Jackson原生方式处理空字段(次重点方案)
      • ObjectMapper的配置选项
        • 通过使用注解的方式
  • MappingJackson2HttpMessageConverter(重点方案)
    • 创建MappingJackson2HttpMessageConverter
    • XML配置
    • Java配置
    • MappingJackson2HttpMessageConverter整合ObjectMapper的配置
      • XML配置
      • JavaConfig配置
    • 自定义的null处理类注解
      • 方案1:使用注解
      • 方案1:序列化器
  • 总结一下

背景

在Spring MVC中配置JSON转换器时,当需要全局控制将某些JSON返回值的key转换为一些默认值时,可以通过实现一个自定义的序列化器(Serializer)来实现这个功能。现在,我们来深入了解Spring MVC的整体处理流程,以确定在哪个步骤进行实现和调整。
在这里插入图片描述
我们先来总结数量一下整个流程:

  1. 用户发送请求,由Spring的前端控制Servlet DispatcherServlet捕获。
  2. DispatcherServlet解析请求URL,并根据URI获取与之相关的Handler和拦截器配置。
  3. DispatcherServlet选择合适的HandlerAdapter来执行Handler(Controller)。在此过程中,也会执行拦截器的preHandler方法。
  4. 提取请求中的模型数据(通过MessageConverter对于入参进行转换)并填充Handler的参数,开始执行Handler。
  5. 执行完成后,返回一个包含Model和View信息的ModelAndView对象。
  6. 根据ModelAndView选择合适的ViewResolver,将其返回给DispatcherServlet。
  7. ViewResolver将Model和View结合起来,进行视图渲染。
  8. 最终将渲染结果返回给客户端(响应的数据转换则通过MessageConverter完成)

MessageConverter

对于JSON转换,涉及到MessageConverter的工作,通过在Spring MVC处理流程中的适当步骤实现自定义序列化器,我们能够全局控制JSON返回值的key,确保它们在需要时转换为指定的默认值。这种方式提供了灵活性和可定制性,使开发者能够更好地适应不同的业务需求。
在这里插入图片描述
MappingJackson2HttpMessageConverter是Spring框架中提供的一个HTTP消息转换器,用于在Spring MVC中进行JSON与Java对象之间的转换。它基于Jackson库,利用Jackson提供的功能进行JSON的序列化和反序列化,接下来我们就针对于它进行实现。

使用Jackson原生方式处理空字段(次重点方案)

当返回字段为null时需要进行处理,可以通过配置ObjectMapper来选择合适的处理方式。以下是几种常见的处理方式及其配置方式:
在这里插入图片描述

ObjectMapper的配置选项

使得ObjectMapper在将Java对象转换为JSON字符串时,仅包含字段值不为null的属性。对于为null的属性,它们将被忽略并不会显示在生成的JSON中。

// 创建ObjectMapper实例
ObjectMapper objectMapper = new ObjectMapper();
// 配置ObjectMapper处理返回字段为null的方式
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);  // 字段均包含在结果JSON中,无论是否为null
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);  // 字段的值不为null时,才会包含在结果JSON中
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);  // 字段的值与其默认值不相等时,才会包含在结果JSON中
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);  // 字段的值不为null且不为空时,才会包含结果JSON中
// 使用配置好的ObjectMapper进行对象转换
YourObject yourObject = ...;  // 要转换的对象
String json = objectMapper.writeValueAsString(yourObject);  // 将对象转换为JSON字符串
通过使用注解的方式

使用注解可以更精确地控制每个类或属性的处理方式。

@JsonInclude(JsonInclude.Include.ALWAYS)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@JsonInclude(JsonInclude.Include.NON_EMPTY)

通过调用setSerializationInclusion方法并传入相应的JsonInclude.Include枚举值,可以配置ObjectMapper处理返回字段为null时的方式。可以根据具体需求选择适合的处理方式。

MappingJackson2HttpMessageConverter(重点方案)

对于SpringMVC,我们会采用MappingJackson2HttpMessageConverter可以将Java对象转换为JSON格式的响应体,并将JSON格式的请求体转换为对应的Java对象。它支持多种媒体类型,如application/json、text/json等。

创建MappingJackson2HttpMessageConverter

在Spring MVC中配置MappingJackson2HttpMessageConverter可以通过以下两种方式:Xml配置和Javaconfig配置

XML配置

下面展示了如何在applicationContext.xml文件中进行XML配置来实现对MappingJackson2HttpMessageConverter 的定义,并通过元素设置了supportedMediaTypes属性:

<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="supportedMediaTypes">
        <list>
            <value>application/json</value>
            <!-- 可以添加其他支持的媒体类型 -->
        </list>
    </property>
    <!-- 其他配置属性 -->
</bean>

在上述配置中,我们使用元素定义了MappingJackson2HttpMessageConverter的bean,并指定了其类名org.springframework.http.converter.json.MappingJackson2HttpMessageConverter,通过元素来设置supportedMediaTypes属性。通过元素来指定一个媒体类型列表,其中每个类型由元素表示。在示例中,我们设置了一个值为application/json的媒体类型。这样就可以将Java对象转换为JSON,并以指定的媒体类型返回给客户端。

Java配置

在Java配置中,我们可以使用@Bean注解创建MappingJackson2HttpMessageConverter的bean,并在方法中进行相同的配置。此外,我们还可以使用Charset.forName(“UTF-8”)来替代java.nio.charset.StandardCharsets.UTF_8来创建MediaType。具体示例如下:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        // 配置媒体类型
        converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON));
        // 其他配置...
        converters.add(converter);
    }
}

MappingJackson2HttpMessageConverter整合ObjectMapper的配置

在上面我们定义了一个 MappingJackson2HttpMessageConverter bean,并设置了 supportedMediaTypes 属性为"application/json",以支持在 Spring MVC 中将 Java 对象转换为 JSON 并返回给客户端。

在这个基础知识,我们加入了最早介绍的 ObjectMapper bean,并设置其 serializationInclusion 属性为 NON_NULL,这将使得序列化时排除掉值为null的字段。

XML配置

<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="supportedMediaTypes">
        <list>
            <value>application/json;charset=UTF-8</value>
        </list>
    </property>
    <property name="objectMapper">
        <bean class="com.fasterxml.jackson.databind.ObjectMapper">
            <property name="serializationInclusion">
                <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
            </property>
        </bean>
    </property>
</bean>

JavaConfig配置

通过mappingJacksonHttpMessageConverter方法创建了一个MappingJackson2HttpMessageConverter的实例,并设置了支持的媒体类型为application/json;charset=UTF-8。

@Configuration
public class WebConfig {

    @Bean
    public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        // 配置支持的媒体类型为application/json;charset=UTF-8
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
        // 配置ObjectMapper,设置serializationInclusion为NON_NULL
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        converter.setObjectMapper(objectMapper);
        return converter;
    }
}

创建了一个ObjectMapper实例,并配置了其serializationInclusion为NON_NULL,然后将该ObjectMapper设置到MappingJackson2HttpMessageConverter中。

自定义的null处理类注解

自定义的 DetfaultNullJsonSerializer,它是一个继承自 JsonSerializer<Object> 的序列化器,用于处理值为null的情况。在 serialize 方法中,我们将使用自定义的 JsonNullDef 对象来替代值为null的字段进行序列化。


public class DetfaultNullJsonSerializer extends JsonSerializer<Object> {
    @Override
    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException {
        jgen.writeObject(new JsonNullDef());
    }
}

class JsonNullDef {
    private List<String> def = new ArrayList<>();
    public List<String> getDef() {
        return def;
    }
    public void setDef(List<String> def) {
        this.def = def;
    }
}

因此,我们可以通过自定义ObjectMapper和注册自定义的序列化器来在转换过程中添加我们需要的控制逻辑。上述的示例代码展示了如何在WebConfig配置类中实现这一点,通过注册自定义的序列化器实现对特定字段null值的转换为默认值。

JsonNullDef 类中,我们定义了一个包含一个名为 def 的列表字段,用于存储默认值。通过这个自定义的null处理类,我们可以在值为null的字段处提供一个默认值,从而避免在序列化时出现null值。

方案1:使用注解

在需要使用自定义序列化器的类或对象上,通过注解或方法来指定使用 DetfaultNullJsonSerializer,例如在 MyData 类中使用注解:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
public class MyData {
    @JsonSerialize(nullsUsing = DetfaultNullJsonSerializer.class)
    private String name;
    @JsonSerialize(nullsUsing = DetfaultNullJsonSerializer.class)
    private String description;
    // 其他字段和方法...
   // 构造函数、getter和setter方法...
}

除了直接用到了注解上,还可以定义到序列化器上面,方便控制和整合到MappingJackson2HttpMessageConverter中。

方案1:序列化器

创建一个自定义的 ObjectMapper 并注册自定义的序列化器:


@Configuration
public class WebConfig {
	public ObjectMapper objectMapper() {
	        ObjectMapper objectMapper = new ObjectMapper();
	        SimpleModule module = new SimpleModule();
	        module.addSerializer(Object.class, new DetfaultNullJsonSerializer());
	        objectMapper.registerModule(module);
	        return objectMapper;
	}
    @Bean
    public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        // 配置支持的媒体类型为application/json;charset=UTF-8
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
        converter.setObjectMapper(objectMapper());
        return converter;
    }
}

总结一下

用自定义的DetfaultNullJsonSerializer,在类或属性上使用@JsonSerialize(nullsUsing = DetfaultNullJsonSerializer.class)注解指定使用该序列化器,以及在配置类中创建并注册自定义的ObjectMapper,将自定义序列化器与ObjectMapper关联。在代码中使用该ObjectMapper实现对象的序列化和反序列化操作。这样,你就可以灵活地控制值为null的字段的处理方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/297244.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WebStorm 创建一个Vue项目

一、下载并安装WebStorm 步骤一 步骤二 选择激活方式 激活码&#xff1a; I2A0QUY8VU-eyJsaWNlbnNlSWQiOiJJMkEwUVVZOFZVIiwibGljZW5zZWVOYW1lIjoiVU5JVkVSU0lEQURFIEVTVEFEVUFMIERFIENBTVBJTkFTIiwiYXNzaWduZWVOYW1lIjoiVGFvYmFv77yaSkVU5YWo5a625qG25rAIOa0uW3peS9nOWup…

Easycode模板,基于官方提供的Mybatis-plus模板改造

目录结构 模板亮点 1、接口类默认继承实体类 实体类不做任何修改保证类与表统一 2、实体类涵盖多种注解 日期格式编码、Long类型转String、字段自动填充 3、自带insertOrUpdateBatch方法 导入方式 {"author" : "Wsong","version" : "1.2.8…

SpringBoot+RocketMQ集群(dledger)部署完整学习笔记

文章目录 前言一、单台集群部署二、多台集群部署1.修改配置2.dashboard修改 三、整合springboot1.引入pom和修改yml2.编写消费者3.编写生产者4.测试效果 总结 前言 RocketMQ集群方式有好几种 官网地址 https://rocketmq.apache.org/zh/docs/4.x/deployment/01deploy 2m-2s-asy…

ATTCK视角下的信息收集:主机发现

目录 1、利用协议主动探测主机存活 利用ICMP发现主机 利用ARP发现主机 利用NetBIOS协议发现主机 利用TCP/UDP发现主机 利用DNS协议发现主机 利用PRC协议发现主机程序 2、被动主机存活检测 利用Browser主机探测存活主机 利用ip段探测主机存活 利用net命令探测主机存活…

unity C# 中通俗易懂LINQ使用案例

文章目录 1. 从数组或列表中查询元素**&#xff1a;2. **排序与分组**&#xff1a;3. **连接多个数据源**&#xff1a;4. **聚合操作**&#xff1a;5. **分页查询**&#xff1a;6. **多条件查询**&#xff1a;7. **转换和投影&#xff08;Select&#xff09;**&#xff1a;8. *…

jdbc源码研究

JDBC介绍 JDBC&#xff08;Java Data Base Connectivity,java数据库连接&#xff09;是一种用于执行SQL语句的Java API&#xff0c;可以为多种关系数据库提供统一访问&#xff0c;它由一组用Java语言编写的类和接口组成。 开发者不必为每家数据通信协议的不同而疲于奔命&#…

竞赛保研 基于深度学习的人脸专注度检测计算系统 - opencv python cnn

文章目录 1 前言2 相关技术2.1CNN简介2.2 人脸识别算法2.3专注检测原理2.4 OpenCV 3 功能介绍3.1人脸录入功能3.2 人脸识别3.3 人脸专注度检测3.4 识别记录 4 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的人脸专注度…

Flask 会员列表展示

感谢编程浪子师傅的源码信息分享 web/controllers/member/Member.py # -*- coding: utf-8 -*- from flask import Blueprint,request,redirect,jsonify from common.libs.Helper import ops_render,iPagination,getCurrentDate,getDictFilterField,selectFilterObj from comm…

【uniapp】APP打包上架应用商-注意事项

初雪云-uniapp启动图自定义生成&#xff08;支持一键生成storyboard&#xff09; 一、修改App端上传图片/视频 uni.uploadFile let thatthis; uni.chooseImage({count: 1,sourceType: [camera,album],sizeType: [compressed, original],success: rey > {uni.showLoading({ t…

Linux操作系统——进程控制(一) 进程创建和进程终止

进程创建 fork函数 在linux中fork函数时非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。 #include <unistd.h> pid_t fork(void); 返回值&#xff1a;自进程中返回0&#xff0c;父进程返回子进程id&#xff…

BetaFlight开源代码之电流校准

BetaFlight开源代码之电流校准 1. 源由2. 分析2.1 常规逻辑2.2 数据流2.3 采样电路2.3.1 采样实现2.3.2 采样原理2.3.3 Layout参考2.3.4 INA169芯片2.3.5 INA169 Near-Zero Vsense 3. 原理4. 示例4.1 实测&转换数据4.2 线性拟合-小电流4.3 线性拟合-大电流4.4 大电流/小电流…

HDMI彩条显示实验与方块移动实验

一、HDMI接口简介 一种数字音视频接口标准&#xff0c;提供高质量的数字音视频传输&#xff0c;同时支持多通道音频、高分辨率视频和其他数据传输功能。提供更高的数据传输带宽&#xff08;带宽&#xff1a;1s内传输多少比特数据&#xff09; 数字传输&#xff1a; HDMI是一种全…

【VRTK】启用多种VR设备的Passthrough功能

【背景】 透视可以让VR头盔展现AR能力,通过VRTK,可以快速实现多种设备平台可用的透视功能。包括主流的Oculus,Pico等。整个不成不需要自己写代码。 【操作】 针对WaveXR,点击场景中的CameraRigsWaveXR-》WaveRig-》Camera Offset-》Main Camera,追加一个新组件,名为Und…

QT自定义信号和槽

信号和槽 介绍实现创建文件对teacher的h和cpp文件进行处理对student的h和cpp文件进行处理对widget的h和cpp文件进行处理 介绍 Qt中的信号和槽是一种强大的机制&#xff0c;用于处理对象之间的通信。它们是Qt框架中实现事件驱动编程的核心部分。 信号&#xff08;Signal&#x…

vite4项目中,vant兼容750适配

一般非vite项目&#xff0c;使用postcss-px-to-viewport。在设计稿为750时候&#xff0c;可使用以下配置兼容vant。 在vite4项目中&#xff0c;以上配置不行。需要调整下&#xff0c;使用postcss-px-to-viewport-8-plugin&#xff0c;并修改viewportWidth&#xff0c;具体如下…

51单片机定时/计数器相关知识点

51单片机定时/计数器相关知识点 结构组成 51单片机的定时/计数器中有两个寄存器&#xff1a; T0&#xff1a;低位&#xff1a;TL0&#xff08;字节地址8AH&#xff09;高位&#xff1a;TH0&#xff08;字节地址8CH&#xff09;T1&#xff1a;低位&#xff1a;TL1&#xff08…

走向云原生 破局数字化

近年来&#xff0c;随着云计算概念和技术的普及&#xff0c;云原生一词也越来越热门&#xff0c;云原生成为云计算领域的新变量。行业内&#xff0c;华为、阿里巴巴、字节跳动等各个大厂都在“抢滩”云原生市场。行业外&#xff0c;云原生也逐渐出圈&#xff0c;出现在大众视野…

Visual Studio Code安装C#开发工具包并编写ASP.NET Core Web应用

前言 前段时间微软发布了适用于VS Code的C#开发工具包&#xff08;注意目前该包还属于预发布状态但是可以正常使用&#xff09;&#xff0c;因为之前看过网上的一些使用VS Code搭建.NET Core环境的教程看着还挺复杂的就一直没有尝试使用VS Code来编写.NET Core。不过听说C# 开发…

设计模式Java实战,彻底学会

​这是全网最强的Java设计模式实战教程。此教程用实际项目场景&#xff0c;结合SpringBoot&#xff0c;让你真正掌握设计模式。 网址是&#xff1a;Java设计模式实战专栏介绍 - 自学精灵&#xff08;也可以百度搜索“自学精灵”&#xff09;。 本设计模式专栏的威力 用Java实…

MySQL学习笔记2: MySQL的前置知识

目录 1. MySQL是什么?2. 什么是客户端&#xff0c;什么是服务器&#xff1f;3. 服务器的特点4. 安装mysql5. mysql 客户端6. mysql 服务器7. mysql的本体8. MySQL 使用什么来存储数据&#xff1f;9. 数据库的多种含义10. MySQL 存储数据的组织方式 1. MySQL是什么? MySQL 是…