【SpringBoot 实战专题】「开发实战系列」全方位攻克你的技术盲区之 Spring 定义 Jackson 转换 Null 的方法和实现案例
背景
在 Spring MVC 中配置 JSON 转换器时,当需要全局控制将某些 JSON 返回值的 key 转换为一些默认值时,可以通过实现一个自定义的序列化器(Serializer)来实现这个功能。现在,我们来深入了解 Spring MVC 的整体处理流程,以确定在哪个步骤进行实现和调整。
我们先来总结数量一下整个流程:
用户发送请求,由 Spring 的前端控制 Servlet DispatcherServlet 捕获。
DispatcherServlet 解析请求 URL,并根据 URI 获取与之相关的 Handler 和拦截器配置。
DispatcherServlet 选择合适的 HandlerAdapter 来执行 Handler(Controller)。在此过程中,也会执行拦截器的 preHandler 方法。
提取请求中的模型数据(通过 MessageConverter 对于入参进行转换)并填充 Handler 的参数,开始执行 Handler。
执行完成后,返回一个包含 Model 和 View 信息的 ModelAndView 对象。
根据 ModelAndView 选择合适的 ViewResolver,将其返回给 DispatcherServlet。
ViewResolver 将 Model 和 View 结合起来,进行视图渲染。
最终将渲染结果返回给客户端(响应的数据转换则通过 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 中。
通过使用注解的方式
使用注解可以更精确地控制每个类或属性的处理方式。
通过调用 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 的定义,并通过<property>元素设置了 supportedMediaTypes 属性:
在上述配置中,我们使用<bean>元素定义了 MappingJackson2HttpMessageConverter 的 bean,并指定了其类名 org.springframework.http.converter.json.MappingJackson2HttpMessageConverter,通过<property>元素来设置 supportedMediaTypes 属性。通过<list>元素来指定一个媒体类型列表,其中每个类型由<value>元素表示。在示例中,我们设置了一个值为 application/json 的媒体类型。这样就可以将 Java 对象转换为 JSON,并以指定的媒体类型返回给客户端。
Java 配置
在 Java 配置中,我们可以使用 @Bean 注解创建 MappingJackson2HttpMessageConverter 的 bean,并在方法中进行相同的配置。此外,我们还可以使用 Charset.forName("UTF-8")来替代 java.nio.charset.StandardCharsets.UTF_8 来创建 MediaType。具体示例如下:
MappingJackson2HttpMessageConverter 整合 ObjectMapper 的配置
在上面我们定义了一个 MappingJackson2HttpMessageConverter
bean,并设置了 supportedMediaTypes
属性为"application/json",以支持在 Spring MVC 中将 Java 对象转换为 JSON 并返回给客户端。
在这个基础知识,我们加入了最早介绍的 ObjectMapper
bean,并设置其 serializationInclusion
属性为 NON_NULL
,这将使得序列化时排除掉值为 null 的字段。
XML 配置
JavaConfig 配置
通过 mappingJacksonHttpMessageConverter 方法创建了一个 MappingJackson2HttpMessageConverter 的实例,并设置了支持的媒体类型为 application/json;charset=UTF-8。
创建了一个 ObjectMapper 实例,并配置了其 serializationInclusion 为 NON_NULL,然后将该 ObjectMapper 设置到 MappingJackson2HttpMessageConverter 中。
自定义的 null 处理类注解
自定义的 DetfaultNullJsonSerializer
,它是一个继承自 JsonSerializer<Object>
的序列化器,用于处理值为 null 的情况。在 serialize
方法中,我们将使用自定义的 JsonNullDef
对象来替代值为 null 的字段进行序列化。
因此,我们可以通过自定义 ObjectMapper 和注册自定义的序列化器来在转换过程中添加我们需要的控制逻辑。上述的示例代码展示了如何在WebConfig
配置类中实现这一点,通过注册自定义的序列化器实现对特定字段 null 值的转换为默认值。
在 JsonNullDef
类中,我们定义了一个包含一个名为 def
的列表字段,用于存储默认值。通过这个自定义的 null 处理类,我们可以在值为 null 的字段处提供一个默认值,从而避免在序列化时出现 null 值。
方案 1:使用注解
在需要使用自定义序列化器的类或对象上,通过注解或方法来指定使用 DetfaultNullJsonSerializer,例如在 MyData 类中使用注解:
除了直接用到了注解上,还可以定义到序列化器上面,方便控制和整合到 MappingJackson2HttpMessageConverter 中。
方案 1:序列化器
创建一个自定义的 ObjectMapper 并注册自定义的序列化器:
总结一下
用自定义的 DetfaultNullJsonSerializer,在类或属性上使用 @JsonSerialize(nullsUsing = DetfaultNullJsonSerializer.class)注解指定使用该序列化器,以及在配置类中创建并注册自定义的 ObjectMapper,将自定义序列化器与 ObjectMapper 关联。在代码中使用该 ObjectMapper 实现对象的序列化和反序列化操作。这样,你就可以灵活地控制值为 null 的字段的处理方式。
版权声明: 本文为 InfoQ 作者【洛神灬殇】的原创文章。
原文链接:【http://xie.infoq.cn/article/b137c31bcb2bc84af44d0e84c】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论