springboot项目中jackson-序列化-处理 NULL教程

在项目中有事需要对值为NULL的对象中Field不做序列化输入配置方式如下:

[配置类型]:

源码包中的枚举类:

public static enum Include {
 ALWAYS,
 NON_NULL,
 NON_ABSENT,
 NON_EMPTY,
 NON_DEFAULT,
 USE_DEFAULTS;

 private Include() {
 }
}

Include.Include.ALWAYS 默认

Include.NON_DEFAULT 属性为默认值不序列化

Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化

Include.NON_NULL 属性为NULL 不序列化

方式一:全局配置,处理所有整个应用的实体对象

#对日期类型的转换配置
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss 

# 配置 参数如下 always non_absent non_default non_empty non_null use_defaults

spring.jackson.default-property-inclusion=non_null

方式二:在需要序列的话的实体类上加注解 ->[配置类型]所列

@JsonInclude(Include.NON_NULL)

方式三:配置类型

3.1自定义序列化实现类,可以作用在类上 自定义json序列化需要实现StdSerializer<T>或者JsonSerializer<T>

@JsonSerialize(using = ClientObjectSerialize.class)
public class CreditBorrowerRepaymentRequestDto{
}

实现类:对字段类型转换,以及对值为null字段的过滤

public class ClientObjectSerialize extends JsonSerializer<CreditBorrowerRepaymentRequestDto>{

 @Override
 public void serialize(CreditBorrowerRepaymentRequestDto dto, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {

  jsonGenerator.writeStartObject();
  try {
   Field[] fields = dto.getClass().getDeclaredFields();
   for (Field field : fields) {
    field.setAccessible(true);
    if(null == field.get(dto)){
     continue;
    }
    jsonGenerator.writeFieldName(field.getName());
    jsonGenerator.writeObject(field.get(dto));
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  jsonGenerator.writeEndObject();
 }
}

3.2自定义序列化实现类,可以作用在实体对象字段上,对NULL值的处理,或者转换

@JsonSerialize(using = ClientStringSerialize.class)
private String name;

@JsonSerialize(using = ClientDtaeSerialize.class)
private Date date;
public class ClientStringSerialize extends JsonSerializer<String> {

 @Override
 public void serialize(String string, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

  if(string == null){
   jsonGenerator.writeString(string + "[NULL]");
  }else{
   jsonGenerator.writeString(string);
  }
 }
}
public class ClientDtaeSerialize extends JsonSerializer<Date> {
 @Override
 public void serialize(Date createDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
  jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createDate));
 }
}

实践总结:

一当全局配置了NULL字段过滤的配置,但有的实体对象需要序列化出NULL的字段值,如何处理?

答:

1. 直接在对象上增加 @JsonInclude(JsonInclude.Include.ALWAYS) 类上的注解优先级比较高,会覆盖全局的配置

2.用自定义的类序列化注解(同上)

二直接在字段上加自定义序列化类会覆盖全局配置吗?

答:不会,有默认的 public class NullSerializer extends StdSerializer<Object> 来处理,当值不为Null的时候才会执行自定义字段上的序列化注解实现类

补充知识:SpringBoot中Jackson返回null处理,字符串类型转空串,数组集合转[],对象转{}

SpringBoot返回Json数据中null值处理,将字符串类型null值转换为"",将集合数组类型null值转换为[],将原始数据类型null值转换为0,将布尔类型null值转换为false,将实体对象null值转换为{}。

1.自定义null值序列化处理器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;

/**
 * 自定义null值序列化处理器
 */
public class CustomizeNullJsonSerializer {

 /**
  * 处理数组集合类型的null值
  */
 public static class NullArrayJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator,
    SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeStartArray();
   jsonGenerator.writeEndArray();
  }
 }

 /**
  * 处理字符串类型的null值
  */
 public static class NullStringJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator,
    SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeString("");
  }
 }

 /**
  * 处理数值类型的null值
  */
 public static class NullNumberJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator,
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeNumber(0);
  }
 }

 /**
  * 处理boolean类型的null值
  */
 public static class NullBooleanJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator,
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeBoolean(false);
  }
 }

 /**
  * 处理实体对象类型的null值
  */
 public static class NullObjectJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator,
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeStartObject();
   jsonGenerator.writeEndObject();
  }
 }
}

2.序列化程序修改器

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;

import java.util.Collection;
import java.util.List;

/**
 * <pre>
 * 此modifier主要做的事情为:
 * 1.当序列化类型为数组集合时,当值为null时,序列化成[]
 * 2.String类型值序列化为""
 *
 * </pre>
 */
public class MyBeanSerializerModifier extends BeanSerializerModifier {

 @Override
 public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
              BeanDescription beanDesc,
              List<BeanPropertyWriter> beanProperties) {
  // 循环所有的beanPropertyWriter
  for (int i = 0; i < beanProperties.size(); i++) {
   BeanPropertyWriter writer = beanProperties.get(i);
   // 判断字段的类型,如果是数组或集合则注册nullSerializer
   if (isArrayType(writer)) {
    // 给writer注册一个自己的nullSerializer
    writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullArrayJsonSerializer());
   }
   if (isStringType(writer)) {
    writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullStringJsonSerializer());
   }
  }
  return beanProperties;
 }

 /**
  * 是否是数组
  */
 private boolean isArrayType(BeanPropertyWriter writer) {
  Class<?> clazz = writer.getType().getRawClass();
  return clazz.isArray() || Collection.class.isAssignableFrom(clazz);
 }

 /**
  * 是否是String
  */
 private boolean isStringType(BeanPropertyWriter writer) {
  Class<?> clazz = writer.getType().getRawClass();
  return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz);
 }

 /**
  * 是否是数值类型
  */
 private boolean isNumberType(BeanPropertyWriter writer) {
  Class<?> clazz = writer.getType().getRawClass();
  return Number.class.isAssignableFrom(clazz);
 }

 /**
  * 是否是boolean
  */
 private boolean isBooleanType(BeanPropertyWriter writer) {
  Class<?> clazz = writer.getType().getRawClass();
  return clazz.equals(Boolean.class);
 }
}

3.配置Jackson实体

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

/**
 * 配置Jackson实体
 */
@Configuration
public class JacksonConfig {
 @Bean
 @Primary
 @ConditionalOnMissingBean(ObjectMapper.class)
 public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
  ObjectMapper objectMapper = builder.createXmlMapper(false).build();
  /** 为objectMapper注册一个带有SerializerModifier的Factory */
  objectMapper.setSerializerFactory(objectMapper.getSerializerFactory()
    .withSerializerModifier(new MyBeanSerializerModifier()));

  SerializerProvider serializerProvider = objectMapper.getSerializerProvider();
  serializerProvider.setNullValueSerializer(new CustomizeNullJsonSerializer
 .NullObjectJsonSerializer());
  return objectMapper;
 }
}

以上这篇springboot项目中jackson-序列化-处理 NULL教程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • springboot返回前端中文乱码的解决

    尝试了各种防止中文乱码的方式,但是还是乱码;最后还是细节问题导致; 解决方式: 以及俩种方式是百度的,我的问题不是这俩块 1.在requestMapping 中添加 produces @RequestMapping( value = "/login", produces = "application/json;charset=utf-8", method = RequestMethod.POST ) 2.在application.yml 中添加配置 spring:

  • Springboot @Value获取值为空问题解决方案

    这篇文章主要介绍了Springboot @Value获取值为空问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在spring中,常常使用 @Value("${property}") 从application.properties中取值,需要注意两点 使用 @Value 的类不能使用 new 关键字进行实例化对象,必须采用 依赖注入的方式进行实例化 不能使用显式的构造方法 否则,将取不到值.解决方法如下: 删除显式的构造方法

  • 详解Springboot之接收json字符串的两种方式

    第一种方式.通过关键字段@RequestBody,标明这个对象接收json字符串.还有第二种方式,直接通过request来获取流.在spring中,推荐使用. 代码地址 https://gitee.com/yellowcong/springboot-demo/tree/master/springboot-json 项目结构 其实项目里面没啥类容,就是一个控制器和pom.xml配置 配置fastjson 添加fastjson的依赖到pom.xml中 <dependency> <groupI

  • Springboot中@Value的使用详解

    Springboot通过@Value注解将配置文件中的属性注入到容器内组件中(可用在@Controller.@Service.@Configuration.@Component等Spring托管的类中) 1.普通字符串注入 例:yml中存在key: name: zs @Value注入 @Value("${name}") public String name; 当yml中的name没有对应值时,即yml中为: name: 此时字符串name的值为"" 可设置注入属性的

  • 最新MySql8.27主从复制及SpringBoot项目中的读写分离实战教程

    目录 最新MySql8.27主从复制以及SpringBoot项目中的读写分离实战 1.MySql主从复制 2.配置-主库Master 3.配置-从库Slave 3.主从复制测试 4.读写分离案例 4.1.Sharding-JDBC框架介绍 最新MySql8.27主从复制以及SpringBoot项目中的读写分离实战 1.MySql主从复制 MySQL主从复制是一个异步的复制过程,底层是基于MySQL1数据库自带的二进制日志功能.就是一台或多台MySQL数据库(slave,即从库)从另一台ySQL数

  • springboot项目中jackson-序列化-处理 NULL教程

    在项目中有事需要对值为NULL的对象中Field不做序列化输入配置方式如下: [配置类型]: 源码包中的枚举类: public static enum Include { ALWAYS, NON_NULL, NON_ABSENT, NON_EMPTY, NON_DEFAULT, USE_DEFAULTS; private Include() { } } Include.Include.ALWAYS 默认 Include.NON_DEFAULT 属性为默认值不序列化 Include.NON_EMP

  • SpringBoot项目中处理返回json的null值(springboot项目为例)

    在后端数据接口项目开发中,经常遇到返回的数据中有null值,导致前端需要进行判断处理,否则容易出现undefined的情况,如何便捷的将null值转换为空字符串? 以SpringBoot项目为例,SSM同理. 1.新建配置类(JsonConfig.java) import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.f

  • Springboot项目中使用redis的配置详解

    程序结构: 一.配置 1. 在pom.xml中添加依赖 pom.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=&q

  • 关于在IDEA中SpringBoot项目中activiti工作流的使用详解

    记录一下工作流的在Springboot中的使用,,顺便写个demo,概念,什么东西的我就不解释了,如有问题欢迎各位大佬指导一下. 1.创建springboot项目后导入依赖 <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>6.0.0</version&

  • SpringBoot项目中使用redis缓存的方法步骤

    本文介绍了SpringBoot项目中使用redis缓存的方法步骤,分享给大家,具体如下: Spring Data Redis为我们封装了Redis客户端的各种操作,简化使用. - 当Redis当做数据库或者消息队列来操作时,我们一般使用RedisTemplate来操作 - 当Redis作为缓存使用时,我们可以将它作为Spring Cache的实现,直接通过注解使用 1.概述 在应用中有效的利用redis缓存可以很好的提升系统性能,特别是对于查询操作,可以有效的减少数据库压力. 具体的代码参照该

  • SpringBoot项目中使用AOP的方法

    本文介绍了SpringBoot项目中使用AOP的方法,分享给大家,具体如下: 1.概述 将通用的逻辑用AOP技术实现可以极大的简化程序的编写,例如验签.鉴权等.Spring的声明式事务也是通过AOP技术实现的. 具体的代码参照 示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-aop Spring的AOP技术主要有4个核心概念: Pointcut: 切点,用于定义哪个方法会被拦截,例如 execution(* cn.sp

  • 浅谈springboot项目中定时任务如何优雅退出

    在一个springboot项目中需要跑定时任务处理批数据时,突然有个Kill命令或者一个Ctrl+C的命令,此时我们需要当批数据处理完毕后才允许定时任务关闭,也就是当定时任务结束时才允许Kill命令生效. 启动类 启动类上我们获取到相应的上下文,捕捉相应命令.在这里插入代码片 @SpringBootApplication /**指定mapper对应包的路径*/ @MapperScan("com.youlanw.kz.dao") /**开启计划任务*/ @EnableScheduling

  • SpringBoot项目中遇到的BUG问题及解决方法

    1.启动项目的时候报错 1.Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 解决方法: 在yml配置文件中加入debug: true,因为默认的话是false 2.在集成mybatis时mapper包中的类没被扫描 org.springframework.beans.factory.NoSuchBean

  • 在SpringBoot项目中的使用Swagger的方法示例

    一. 首先Swagger是什么? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步.Swagger官方API文档:https://swagger.io/ 作用:   1. 接口的文档在线自动生成.   2. 功能测试. Swagger的主见介绍:    Swagger Codegen: 通过Codegen 可

随机推荐