【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 {@Overridepublic 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 {@Beanpublic MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();// 配置支持的媒体类型为application/json;charset=UTF-8converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));// 配置ObjectMapper,设置serializationInclusion为NON_NULLObjectMapper 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> {@Overridepublic 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;}@Beanpublic MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();// 配置支持的媒体类型为application/json;charset=UTF-8converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));converter.setObjectMapper(objectMapper());return converter;}
}

总结一下

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3+echart绘制中国地图并根据后端返回的坐标实现涟漪动画效果

1.效果图 2.前期准备 main.js app.use(BaiduMap, {// ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */ak: sRDDfAKpCSG5iF1rvwph4Q95M6tDCApL,// v:3.0, // 默认使用3.0// type: WebGL // ||API 默认API (使用此模式 BMapBMapGL) });i…

vue3 实现el-date-picker日期筛选过程

一、图例 二、需求&#xff1a; 有2个查询条件&#xff0c;startTime 和 endTime 选中时间1&#xff0c;禁止选中时间2&#xff0c;当前值传递给 startTime 选中时间2&#xff0c;禁止选中时间1&#xff0c;当前值传递给 startTime 和 endTime 三、完整代码 <div class…

无心剑七绝《译无止境》

七绝译无止境 人生跌宕几春秋 苦辣酸甜永不休 只待通灵成妙译 神思曼舞醉琼楼 2024年1月6日 平水韵十一尤平韵 无心剑的这首《译无止境》以七言绝句的形式&#xff0c;表达了对翻译事业的热爱和追求。 首句“人生跌宕几春秋”&#xff0c;意味着人生的曲折变化&#xff0c…

K8S部署GitLab

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Jmeter相关知识介绍

Jmeter 是Apache 组织开发的基于JAVA 的压力测试工具,用于对软件做压力测试,特别适合于WEB 应用测试(包括压力,接口测试) 今天简单介绍Jemeter的入门相关概念的理解 一、在安装目录下有一个Bin\Jmeter.bat 双击打开 打开之后是一个这样的界面 二、测试计划 1、添加和删…

【Python机器学习】线性模型——lasso

除了岭回归&#xff0c;还有一种正则化的线性回归是lasso&#xff0c;与岭回归相同&#xff0c;使用lasso也是约束系数使其接近于0&#xff0c;但方法不同&#xff0c;叫做L1正则化。L1正则化的结果是使用lasso时某些系数刚好为0。说明某些特征被模型完全忽略。 同样以波士顿房…

亚马逊自养号测评:提升商品排名与流量的必要操作

自养号测评是通过使用自主注册的海外买家账号&#xff0c;对商品进行评价&#xff0c;以提升其在平台上的排名和流量的操作。卖家选择自养号这种方式来增强商品的曝光度和吸引更多潜在买家。然而&#xff0c;养号并非易事&#xff0c;需要卖家提高养号技术、掌握相应技巧&#…

SonarQube 漏洞扫描

SonarQube 漏洞扫描 一、部署服务 1.1 docker方式部署 #安装docker curl -L download.beyourself.org.cn/shell-project/os/get-docker-latest.sh | sh yum install -y docker-compose #进去输入:set paste可以保证不穿行 [rootlocalhost sonar]# vim docker-compose.yml v…

git本地创建分支并推送到远程关联起来

git本地创建分支并推送到远程关联起来 git本地基于当前分支创建个新的分支&#xff0c;然后推送到远程&#xff0c;并把本地新创建的分支和远程分支关联 在当前分支下&#xff0c;新建分支 git checkout -b test推送到远程仓库 git push origin test将本地分支和远程分支关联…

0基础学习VR全景平台篇第134篇:720VR全景,云台调整节点

相机、云台和脚架全套设备组装完成后需要进行调校才能开始拍摄。这一节&#xff0c;我们将主要介绍云台调整的两个内容&#xff1a;对中心靶、调三点一线。&#xff08;后附调校原理&#xff09; 云台部件名称 一、调节准备 &#xff08;一&#xff09;对于安装好的云台 1.检…

音量控制软件sound control mac功能亮点

sound control mac可以帮助用户控制某个独立应用程序的音量&#xff0c;通过每应用音量&#xff0c;均衡器&#xff0c;平衡和音频路由独立控制每个应用的音频&#xff0c;还有整个系统的音量。 sound control mac功能亮点 每个应用程序的音量控制 独立控制应用的数量。 键盘音…

docker安装nodejs,并更改为淘宝源

拉取官方 Node.js 镜像 docker pull node:latest创建 Dockerfile&#xff0c;并更改 NPM 下载源为淘宝源&#xff0c;设置为全局持久化 # 使用最新版本的Node.js作为基础镜像 FROM node:latest# 设置工作目录为/app WORKDIR /app # 更改 NPM 下载源为淘宝源&#xff0c;并设置…