首页 > 其他分享 >【springMVC】全局json序列化配置

【springMVC】全局json序列化配置

时间:2023-08-18 13:33:45浏览次数:40  
标签:jackson java springMVC json new import 序列化 com

1.概述

现在我们进行web开发,一般都要设计成RESTful风格的API,通过json格式的数据进行交互。但是前端传入的 json 数据如何被解析成 Java 对象作为 API入参,后端返回结果又如何将 Java 对象解析成 json 格式数据返回给前端,在整个数据流转过程中,这是由谁来完成的呢?

2.HttpMessageConverter简介

org.springframework.http.converter.HttpMessageConverter 是SpringMVC中提供的一个策略接口,它是一个转换器类,负责转换HTTP请求和响应,可以把对象自动转换为JSON(使用Jackson库或Gson库)或XML(使用Jackson XML或者JAXB2),对字符串默认使用UTF-8编码处理,一般情况下采用默认配置就可以。

 

自定义 HttpMessageConverter(一般不添加自定义,使用默认配置):

package com.ryxx.config;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.ryxx.util.JacksonUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.function.Predicate;

/**
 * ClassName:JacksonObjectMapperConfig <br/>
 * Function: 一般不添加该配置,使用默认配置. <br/>
 * Reason:   一般不添加该配置,使用默认配置. <br/>
 * Date:     2023/08/17/11:31 <br/>
 *
 * @author guocheng
 * @version 1.0
 * @since JDK 1.8
 */
@Configuration
public class JacksonObjectMapperConfig extends WebMvcConfigurationSupport {


    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss.SSS}")
    private String pattern;

    @Value("${spring.jackson.time-zone:GMT+8}")
    private String timeZoneString;


    /**
     * 重定制 objectMapper
     * 想完全控制序列化过程并且不想允许外部配置时打开 @Primary 注解
     */
    @Bean(name = "objectMapper")
//    @Primary
    public ObjectMapper objectMapper() {

        ObjectMapper objectMapper = new ObjectMapper();

        // POJO对象的属性值不论是什么,序列化时都显示
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        // 设置在反序列化时忽略在JSON字符串中存在,而在Java中不存在的属性
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 设置序列化时间类型不使用时间戳形式(jackson时间类型默认都是序列化为时间戳形式的)
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

        // 为了处理JSON中的日期字符串并正确转换为 LocalDate,我们需要注册在 ObjectMapper 实例中注册 JavaTimeModule 模块。
        // 还需要禁止把日期转换为时间戳字符串的动作
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        // Date类型序列化、反序列化全局配置-方式1
//        objectMapper.setDateFormat(new SimpleDateFormat(pattern));

        // Date类型序列化、反序列化全局配置-方式2
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone(timeZoneString));
        javaTimeModule.addSerializer(Date.class, new DateSerializer(false, simpleDateFormat));
        javaTimeModule.addDeserializer(Date.class, new JacksonUtils.DateDeserializer());

        // LocalDateTime类型序列化、反序列化全局配置
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern)));

        objectMapper.registerModule(javaTimeModule);

        return objectMapper;


    }

    /**
     * org.springframework.http.converter.HttpMessageConverter
     * 是SpringMVC中提供的一个策略接口,它是一个转换器类,负责转换HTTP请求和响应,
     * 可以把对象自动转换为JSON(使用Jackson库或Gson库)或XML(使用Jackson XML或者JAXB2),
     * 对字符串默认使用UTF-8编码处理,一般情况下采用默认配置就可以。
     * <p>
     * 自定义 HttpMessageConverter
     * 所以如果想要覆盖 Spring MVC 中默认的 HttpMessageConverter,可以重写 #configureMessageConverters 方法,
     * 如果只是想在默认列表中添加自定义的 HttpMessageConverter 则可以重写 #extendMessageConverters 方法。
     * <p>
     * HttpMessageConverter 同时支持请求体转换为类对象,以及将类对象转换为响应体,
     * 因此 RequestResponseBodyMethodProcessor 不管处理参数还是返回值都用到了它。
     * RequestResponseBodyMethodProcessor 将请求体转换为 Controller 方法参数,
     * 将 Controller 方法返回值转换为响应体。
     */
    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 已有的MappingJackson2HttpMessageConverter bean有可能时区不是gmt+8,直接干掉,然后添加一个新的
        converters.removeIf(MappingJackson2HttpMessageConverter.class::isInstance);
        // 将重定制 objectMapper 添加自定义的 HttpMessageConverter中,
        // 使 @requestBody 和 @ResponseBody 注解的序列化与反序列化生效
        converters.add(new MappingJackson2HttpMessageConverter(objectMapper()));
    }


    /**
     * 假定我们的项目中引入了 fastjson,如果我们想要配置 fastjson
     * 自带的 HttpMessageConverter 处理 application/json 内容类型,只需如下的配置。
     */
//    @Override
//    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
//        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
//        converters.add(0, converter);
//    }


}

 

 重置 jackson 默认的 ObjectMapper(一般添加该配置即可):

package com.ryxx.config;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.std.NumberDeserializers;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.TimeZone;

/**
 * jackson全局时间格式化配置<br/>
 * springboot扫描到即生效<br/>
 * 优先级低于{@link JsonFormat}注解
 *
 * @JsonComponent 注解的类会被 SpringBoot 自动注入到默认的 ObjectMapper 中,
 * 重新定制 ObjectMapper 会覆盖该配置。
 */
@JsonComponent
public class JsonDateFormatConfig {


    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;

    @Value("${spring.jackson.time-zone:Asia/Shanghai}")
    private String timeZoneString;


    @Bean
    @Primary
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {

            builder.failOnEmptyBeans(false);
            builder.failOnUnknownProperties(false);
            // 要禁用的功能(将日期写成时间戳)
            builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

            // Date类型序列化配置
            DateFormat df = new SimpleDateFormat(pattern);
            // 设置时区
            df.setTimeZone(TimeZone.getTimeZone(timeZoneString));

            // Date类型序列化、反序列化全局配置-方式1
            builder.dateFormat(df);

/*            // Date类型序列化配置(不使用时间戳)-方式2
            builder.serializerByType(Date.class, new DateSerializer(false, df));
            // Date类型反序列化配置
            builder.deserializerByType(Date.class, new JsonDeserializer<Date>() {
                @Override
                public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
                    String dateStr = p.getText().trim();
                    if ("".equals(dateStr)) {
                        return null;
                    }
                    Date date = null;
                    try {
                        date = new SimpleDateFormat(pattern).parse(dateStr);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    return date;
                }
            });*/

            // LocalDateTime类型序列化配置
            builder.serializerByType(LocalDateTime.class,
                    new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)));

            // LocalDateTime类型反序列化配置
            builder.deserializerByType(LocalDateTime.class,
                    new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern)));

            // BigDecimal类型反序列化配置
            builder.deserializerByType(BigDecimal.class, new NumberDeserializers.BigDecimalDeserializer());

        };

    }


//    /**
//     * LocalDateTime序列化器
//     */
//    @Bean
//    public LocalDateTimeSerializer localDateTimeSerializer() {
//        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
//    }
//
//    /**
//     * LocalDateTime反序列化器
//     */
//    @Bean
//    public LocalDateTimeDeserializer localDateTimeDeserializer() {
//        return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern));
//    }


}

 

 

 

 

 

 

 

 

 

 

 

参考:SpringBoot系列教程22-整合SpringMVC之HttpMessageConverters - 知乎 (zhihu.com)

标签:jackson,java,springMVC,json,new,import,序列化,com
From: https://www.cnblogs.com/ryxxtd/p/17640247.html

相关文章

  • SpringMVC-1-解密Spring MVC:构建优雅、灵活的Web应用的秘诀
    今日目标能够编写SpringMVC入门案例了解SpringMVC原理1.SpringMVC介绍1.1SpringMVC概述思考:SpringMVC框架有什么优点?SpringMVC是一种基于Java实现MVC模型的轻量级Web框架优点使用简单,开发便捷(相比于Servlet)天然的与Spring框架集成(如IOC容器、AOP等)请求处理简化:支......
  • 解决小程序报错 getLocation:fail the api need to be declared in the requiredPriva
    一、unipp项目打开uniapp项目的配置文件manifest.json,选择“源码视图”。/*小程序特有相关*/"mp-weixin":{"appid":"你的开发者id","setting":{"urlCheck":true,"es6":true,"postcss":......
  • postman进行环境变量设置,全局变量设置 pm.response.json()
    环境变量的设置在开发和测试的过程中,经常在开发环境,测试环境,生产环境来回切换,这样每次都要修改域名很麻烦,好在postman提供了可以切换环境更改域名的方法,这样只要配置好环境变量就可以切换域名了。具体操作步骤如下:1.点击postman右上角眼镜的图标2.点击“Add”按钮3.填写域......
  • json-server安装
    一、下载安装:【json-server网址】https://www.npmjs.com/package/json-server#使用npm全局安装json-server:npminstall-gjson-server#可以通过查看版本号,来测试是否安装成功:json-server-v二、启动db.json数据及相关参数:json-server--watch.\db.json--port5000......
  • json
    js对象var obj={    name:“zs”,    age:  7} json对象var obj={    “name":“zs”,    "age":  7} ......
  • docker容器daemon.json配置文件解析
    docker版本高于1.12,配置文件的默认径为:/etc/docker/daemon.json{“api-cors-header”:"",在引擎API中设置CORS标头“authorization-plugins”:[],要加载的授权插件“bridge”:"",将容器附加到网桥“cgroup-parent”:"",为所有容器设置父cgroup“cluster-store......
  • 【剑指Offer】61、序列化二叉树
    【剑指Offer】61、序列化二叉树题目描述:请实现两个函数,分别用来序列化和反序列化二叉树。解题思路:序列化是指将结构化的对象转化为字节流以便在网络上传输或写到磁盘进行永久存储的过程。反序列化是指将字节流转回结构化的对象的过程,是序列化的逆过程。受第4题:重建二叉树的启......
  • IIS压缩API返回的JSON数据
    安装IIS压缩功能后点击 配置中选择 system.webServer/httpCompression 点击dynamicTypes 添加以下类型,Json和XML会压缩 ......
  • SpringBoot操作前端传的Geojson进行空间查询
    SpringBoot操作前端传的Geojson进行空间查询项目说明:项目技术栈:SpringBoot+MybatisPlus+postgresql先上查询SQLSELECT*FROMdemoWHEREST_Intersects(geom,ST_GeomFromGeoJSON('放geojson类型数据'));表结构Controller层packagecom.itcy.postgresql.controller;importco......
  • js前端传json,后台接收‘‘被转为quot使用replace方法替换
    前端解决方案:varjsonstr=datas.replace(newRegExp('"',"gm"),'"')正则参数说明g执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。m执行多行匹配。let data=eval('('+jsonString+')');实例1:    jsonstr.replace(newRegExp('"',......