解决spring后端传前端数值为空的问题

问题:在开发当中,由于我的数据传输从DTO在某些场景下,其中的部分字段并不需求进行值的传递,但在其他功能当中需要;(比如开发题目模块时,查询题目采用同一接口,根据题目id不同,后台判断其为多选还是单选进行回传给dto给前端)。

导致出现了如下情况的诸多null值,而这些是没有作用但又不可删除的,因为在其他业务场景下需要这些字段。

 先上源代码便于理解。

package com.jingdianjichi.subject.application.dto;

import com.jingdianjichi.subject.commom.entity.PageInfo;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * 题目信息表(SubjectInfo)实体类
 *
 * @author makejava
 * @since 2024-07-11 22:44:31
 */
@Data
public class SubjectInfoDTO extends PageInfo implements Serializable {
    private Long id;
    /**
     * 题目名称
     */
    private String subjectName;
    /**
     * 题目难度
     */
    private Integer subjectDifficult;
    /**
     * 出题人名
     */
    private String settleName;
    /**
     * 题目类型 1单选 2多选 3判断 4简答
     */
    private Integer subjectType;
    /**
     * 题目分数
     */
    private Integer subjectScore;
    /**
     * 题目解析
     */
    private String subjectParse;

    /**
     * 题目答案
     */
    private String subjectAnswer;

    /**
     * 分类id
     */
    private List<Integer> categoryIds;

    /**
     * 标签id
     */
    private List<Integer> labelIds;

    /**
     * 答案选项
     */
    private List<SubjectAnswerDTO> optionList;

    /**
     * 标签name
     */
    private List<String> labelName;

    private Long categoryId;

    private Long labelId;

    private String keyWord;

    /**
     * 创建人昵称
     */
    private String createUser;

    /**
     * 创建人头像
     */
    private String createUserAvatar;

    /**
     * 题目数量
     */
    private Integer subjectCount;

    /**
     * 是否被当前用户点赞
     */
    private Boolean liked;

    /**
     * 当前题目点赞的数量
     */
    private Integer likedCount;

    /**
     * 下一题
     */
    private Long nextSubjectId;

    /**
     * 上一题
     */
    private Long lastSubjectId;



}

  我们可以看到DTO类封装了许多字段,但是在我查询单选题目情况下,多选,简答等字段便不再需要对其进行展示。

在这种场景下, 我们选取采用通过继承WebMvcConfigurationSupport类来自定义Spring MVC的配置,将所有JSON数据将通过自定义的如MappingJackson2HttpMessageConverter类进行序列化和反序列。

首先,我们先了解什么是WebMvcConfigurationSupport?

对WebMvcConfigurationSupport类的理解

官方介绍:

This is the main class providing the configuration behind the MVC Java config.It is typically imported by adding {@link EnableWebMvc @EnableWebMvc} to an application {@link Configuration @Configuration} class. An alternative more advanced option is to extend directly from this class and override methods as necessary, remembering to add {@link Configuration @Configuration} to the subclass and {@link Bean @Bean} to overridden {@link Bean @Bean} methods.For more details see the javadoc of {@link EnableWebMvc @EnableWebMvc}.


翻译的中文介绍如下:

这是一个在Java MVC配置之后提供配置的主类。它的导入方式是将 @EnableWebMvc注解添加到应用程序@Configuration类。另一个更高级的方式是根据需要覆盖的方法直接extends这个类,但要记住将 @Configuration添加到子类中,将@Bean添加到覆盖的@Bean方法中。有关更多细节,请参见@EnableWebMvc的javadoc。

主要特点

  1. 默认配置:

    • WebMvcConfigurationSupport类包含了Spring MVC的一些默认配置,例如自动注册视图解析器、消息转换器(如JSON转换)、数据格式化器等。
  2. 可扩展性:

    • 继承WebMvcConfigurationSupport的类可以覆盖其中的方法,从而定制Spring MVC的行为。例如,你可以覆盖configureMessageConverters方法来添加自定义的消息转换器,或者覆盖addResourceHandlers方法来配置静态资源处理。
  3. 拦截器注册:

    • 你也可以通过覆盖addInterceptors方法来注册拦截器,这些拦截器可以用于处理请求前后的逻辑,比如认证、日志记录等。
  4. 视图控制器:

    • 可以通过覆盖addViewControllers方法来添加视图控制器,它们可以快速映射URL到特定的视图,而无需显式控制器方法。

使用示例

在Spring Boot应用中,你可能会看到如下配置:


@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyCustomInterceptor());
    }

    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MyCustomMessageConverter());
        super.configureMessageConverters(converters);
    }
}

  在这个示例中,WebConfig类继承了WebMvcConfigurationSupport,并且覆盖了addInterceptorsconfigureMessageConverters方法,分别用于注册自定义的拦截器和消息转换器。

需要注意的是,如果你在Spring Boot应用中使用@EnableWebMvc注解,那么Spring Boot的自动配置会被禁用,你将完全负责MVC的配置。如果不使用@EnableWebMvc,则可以与Spring Boot的默认配置共存,只覆盖或添加你关心的部分配置。

再次回到我们本次的目的,解决json空值问题。

 
 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

  

package com.jingdianjichi.subject.application.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

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.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;

/**
 * mvc的全局处理
 *
 * @author: ChickenWing
 * @date: 2023/10/7
 */
@Configuration
public class GlobalConfig extends WebMvcConfigurationSupport {

    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(mappingJackson2HttpMessageConverter());
    }

//    @Override
//    protected void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(new LoginInterceptor())
//                .addPathPatterns("/**");
//    }

    /**
     * 自定义mappingJackson2HttpMessageConverter
     * 目前实现:空值忽略,空字段可返回
     */
    private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return new MappingJackson2HttpMessageConverter(objectMapper);
    }


}

  

  1. configureMessageConverters:

    • 这个方法用于配置HTTP消息转换器,即Spring MVC用来读取和写入HTTP请求和响应体中的数据的组件。在你的代码中,这个方法首先调用父类的同名方法来应用默认的配置,然后添加了一个自定义的MappingJackson2HttpMessageConverter实例到转换器列表中。这意味着所有的JSON数据将通过你自定义的MappingJackson2HttpMessageConverter进行序列化和反序列化。
  2. mappingJackson2HttpMessageConverter:

    • 这个方法创建并配置了一个MappingJackson2HttpMessageConverter实例。在这个方法中,你创建了一个新的ObjectMapper实例,并设置了两个重要的配置:
      • configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);: 这个配置告诉Jackson,即使遇到空的JavaBean(没有任何非默认值的字段)也不抛出异常,而是将其序列化为空的JSON对象。
      • setSerializationInclusion(JsonInclude.Include.NON_NULL);: 这个配置原本是告诉Jackson,在序列化对象时,只包含非null的字段,忽略所有null值。不过,你没有激活这个配置,因此默认情况下所有字段都会被序列化,包括null值。

这时,null值传输问题便可以得到妥善解决!

 

posted @ 2024-07-21 23:05  橘子味芬达水  阅读(87)  评论(0编辑  收藏  举报