如何自定义Jackson序列化 @JsonSerialize

目录
  • 自定义Jackson序列化 @JsonSerialize
  • jackson自定义全局序列化、反序列化
    • 创建序列化类
    • 创建反序列化类
    • 将两个类注册进入jackson核心对象objectMapper
    • 小结一下

自定义Jackson序列化 @JsonSerialize

自定义json序列化需要实现StdSerializer<T>或者JsonSerializer<T>。

我要序列化House这个类,加上注解,指定用于序列化的类

package com.xhx.json.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.xhx.json.serializers.HourseSerializer;
import java.util.Date;

@JsonSerialize(using = HourseSerializer.class)
public class Hourse {
    private String location;
    private Date buildDate;
    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public Date getBuildDate() {
        return buildDate;
    }

    public void setBuildDate(Date buildDate) {
        this.buildDate = buildDate;
    }
}
package com.xhx.json.serializers;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.xhx.json.entity.Hourse;
import java.io.IOException;

public class HourseSerializer extends StdSerializer<Hourse> {
    public HourseSerializer(){
        super(Hourse.class);
    }

    protected HourseSerializer(Class<Hourse> t) {
        super(t);
    }

    @Override
    public void serialize(Hourse hourse, JsonGenerator generator, SerializerProvider provider) throws IOException {
        generator.writeStartObject();
        generator.writeFieldName("id");
        generator.writeString("自定义");
        generator.writeFieldName("location");
        generator.writeString(hourse.getLocation());
        generator.writeObjectField("buildDate",hourse.getBuildDate());
        generator.writeEndObject();
    }
}

测试:

jackson自定义全局序列化、反序列化

需要自定义Jackson序列化和反序列化有两种方式,一种是全局定义,一种是非全局定义。先来看看全局定义。全局定义的步骤如下,以定义一个localDateTime的序列化和反序列化为例:

创建序列化类

创建一个序列化类然后继承JsonSerializer,重写serialize序列化方法。其中第一个参数localDateTime为JsonSerializer的泛型,表示的是被序列化的类型的值,第二个参数jsonGenerator表示的是用于输出生成的Json内容,第三个参数暂时没明白什么应用场景。重写方法一般是将想要序列化的字符串传入 jsonGenerator.writeString。

public final class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    public static final LocalDateTimeSerializer INSTANCE = new LocalDateTimeSerializer();
    public LocalDateTimeSerializer() {
    }
    @Override
    public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        jsonGenerator.writeString(DateUtil.format(localDateTime, DateUtil.DateTimeFormatEnum.DATE_TIME_FORMAT_4));
    }
}

创建反序列化类

创建两个类,一个类继承JsonDeserializer,一个类继承KeyDeserializer,重写deserialize反序列化方法。参数jsonParser用于读取json内容的解析,deserializationContext可用于访问此有关反序列化的上下文(暂时也不知道怎么用),返回值则是JsonDeserializer的泛型对象,表示要反序列化的对象。一般用法是通过jsonParser.getText().trim()获取该字段json字符串,然后将该字符串转换为对象返回。

public final class LocalTimeDeserializer extends JsonDeserializer<LocalTime> {
    public static final LocalTimeDeserializer INSTANCE = new LocalTimeDeserializer();
    public LocalTimeDeserializer() {
    }
    @Override
    public LocalTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        String text = jsonParser.getText().trim();
        return LocalTime.parse(text, DateUtil.DATE_TIME_FORMATTER_6);
    }
}
public final class LocalDateTimeKeyDeserializer extends KeyDeserializer {
    public static final LocalDateTimeKeyDeserializer INSTANCE = new LocalDateTimeKeyDeserializer();
    public LocalDateTimeKeyDeserializer() {
    }
    @Override
    public Object deserializeKey(String s, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        return StringUtils.isBlank(s) ? null : LocalDateTime.parse(s, DateUtil.DATE_TIME_FORMATTER_4);
    }
}

将两个类注册进入jackson核心对象objectMapper

@Bean
public ObjectMapper objectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //不注释,会导致swagger报错
        //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        //关闭日期序列化为时间戳的功能
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        //关闭序列化的时候没有为属性找到getter方法,报错
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        //关闭反序列化的时候,没有找到属性的setter报错
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        //序列化的时候序列对象的所有属性
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        //反序列化的时候如果多了其他属性,不抛出异常
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //如果是空对象的时候,不抛异常
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        SimpleModule simpleModule = new SimpleModule();
        //json值序列化
        simpleModule.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE);
        //json值反序列化
        simpleModule.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
        //json键序列化
        simpleModule.addKeySerializer(LocalDateTime.class,LocalDateTimeSerializer.INSTANCE);
        //json键反序列化
        simpleModule.addKeyDeserializer(LocalDateTime.class, LocalDateTimeKeyDeserializer.INSTANCE);
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }

小结一下

以上,通过objectMapper的配置,完成了全局序列化、反序列化的配置,如果不需要全局则通过@jsonserialize或 @JsonDeserialize指定使用的序列化、反序列化类。仅为个人经验,希望能给大家一个参考,也希望大家多多支持我们

(0)

相关推荐

  • springboot jackson自定义序列化和反序列化实例

    目录 jackson自定义序列化和反序列 序列化JsonSerializer 最后请求http返回对象 反序列化JsonDeserializer 小结一下 springboot 自定义序列化器 jackson自定义序列化和反序列 spingmvc使用httpmessageconverter接口来转换http请求和响应. 如果需要添加和自定义转换器,则可以使用spring boot的HttpMessageConverters类:任何存在于上下文中的HttpMessageConverter的ben都

  • SpringBoot @JsonDeserialize自定义Json序列化方式

    目录 @JsonDeserialize自定义Json序列化 1.问题 2.现象 3.解决办法 @JsonSerialize与@JsonDeserialize使用 1.以注解方式使用 2.自定义实现类 @JsonDeserialize自定义Json序列化 1.问题 在项目上使用SpringBoot为框架,调用第三方接口时,返回的参数Date类型,需要自定义进行Json序列化,需要进行处理,接受数据 2.现象 调用第三方接口,返回参数类型为Date类型,格式如下: { "created":

  • Java下利用Jackson进行JSON解析和序列化示例

    Java下常见的Json类库有Gson.JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的JSON操作方法. 一.准备工作 首先去官网下载Jackson工具包.Jackson有1.x系列和2.x系列,截止目前2.x系列的最新版本是2.2.3,2.x系列有3个jar包需要下载: jackson-core-2.2.3.jar(核心jar包,下载地址) jackson-annotations-2

  • SpringMVC Json自定义序列化和反序列化的操作方法

    需求背景 需求一:SpringMVC构建的微服务系统,数据库对日期的存储是Long类型的时间戳,前端之前是默认使用Long类型时间,现在前端框架改动,要求后端响应数据时,Long类型的时间自动变成标准时间格式(yyyy-MM-dd HH:mm:ss). 涉及到这个转换的范围挺大,所有的实体表都有创建时间createTime和修改时间updateTime,目前的主要诉求也是针对这两个字段,并且在实体详情数据和列表数据都存在,需要一个统一的方法,对这两个字段进行处理. 需求二:前端请求上传的JSON

  • Shell脚本自动更新hosts实现免翻墙访问google

    上次给大家发了一个python更新google hosts的脚本,今天看到有人发出了一句用shell来获取google hosts的脚本,我就拿来稍微简单加工了下,下面给大家shell版的更新google hosts的脚本. 脚本内容: 复制代码 代码如下: cat google_update.sh #!/bin/bash data=`date +%y%m%d%H%M` curl http://www.360kb.com/kb/2_122.html 2>/dev/null | sed -n '/

  • 如何自定义Jackson序列化 @JsonSerialize

    目录 自定义Jackson序列化 @JsonSerialize jackson自定义全局序列化.反序列化 创建序列化类 创建反序列化类 将两个类注册进入jackson核心对象objectMapper 小结一下 自定义Jackson序列化 @JsonSerialize 自定义json序列化需要实现StdSerializer<T>或者JsonSerializer<T>. 我要序列化House这个类,加上注解,指定用于序列化的类 package com.xhx.json.entity;

  • java如何利用FastJSON、Gson、Jackson三种Json格式工具自定义时间序列化

    Java处理JSON数据有三个比较流行的类库FastJSON.Gson和Jackson. Jackson Jackson是由其社区进行维护,简单易用并且性能也相对高些.但是对于复杂的bean转换Json,转换的格式鄙视标准的Json格式.PS:Jackson为Spring MVC内置Json解析工具 Gson Gson是由谷歌公司研发的产品,目前是最全的Json解析工具.完全可以将复杂的类型的Json解析成Bean或者Bean到Json的转换 FastJson Fastjson是一个Java语言

  • jackson序列化和反序列化的应用实践指南

    源码地址:https://github.com/zhouweixin/serializable 1 相关概念 序列化: 把对象转换为字节序列的过程称为对象的序列化 反序列化: 把字节序列恢复为对象的过程称为对象的反序列化 2 序列化的作用 用于把内存中的对象状态保存到一个文件中或者数据库中 用于网络传送对象 用于远程调用传输对象 3 准备序列化对象 准备了两个类, 教师类和学生类, 其中一个学生只有一个教师 这里省略了构造方法和setter, getter方法 Teacher.java publ

  • Java利用Jackson序列化实现数据脱敏

    几天前使用了Jackson对数据的自定义序列化.突发灵感,利用此方法来简单实现接口返回数据脱敏,故写此文记录. 核心思想是利用Jackson的StdSerializer,@JsonSerialize,以及自己实现的数据脱敏过程. 使用效果如下: 首先在需要进行脱敏的VO字段上面标注相关脱敏注解 调用接口即可看到脱敏效果 实现过程如下: 1. 定义脱敏的过程实现 /** * Created by EalenXie on 2021/9/24 15:52 * 顶级的脱敏器 */ public inte

  • SpringBoot 如何实现自定义Redis序列化

    目录 问题 环境 入口点 实现自定义序列化 小结 问题 在使用RedisTemplate存储对象时,如果采用JDK默认的序列化方式,数据会出现许多编码字符,辨析度不高.比如一个空的User对象,存储到redis后如下: 这些使用JDK默认序列化方式序列化后的数据简直惨不忍睹,在使用命令行查询数据时会很头疼. 如何使数据更容易辨别呢? 一种办法是使用StringRedisTemplate,在存入redis前先将数据处理成字符串格式再存入redis,但这种方式的缺点就是每次存入数据前都要手动对非字符

  • jackson使用@JsonSerialize格式化BigDecimal解决.00不显示问题

    一. 问题 最近开发中使用BigDecimal这个数据类型 返回json数据时出现了点问题: # 1.前端第一次保存的时候 穿过来的数据格式 240.00 240.77 # 2. mysql数据库存储的数据格式(数据库字段已经设置了保留小数点后两位) 240 240.77 # 3. java程序中查看从数据库中查询的回来的数据格式: 240.00 240.77 # 4. 返回前端的json字符串里的数据格式: 240 240.77 # 4. 前端想要的json字符串里的数据格式: 240.00

  • golang如何自定义json序列化应用详解

    前言 Go语言作为一个由Google开发,号称互联网的C语言的语言,自然也对JSON格式支持很好.下面这篇文章主要介绍了关于golang自定义json序列化应用的相关内容,下面话不多说了,来一起看看详细的介绍吧 问题引入 当某个struct存在某个字段为string或者[]byte类型但是实际上保存的内容是json格式的数据时,对其进行json序列化,比如 type Message struct { From string `json:"from"` To string `json:&

  • Jackson序列化和反序列化忽略字段操作

    一.设置Jackson序列化时只包含不为空的字段 new ObjectMapper().setSerializationInclusion(Include.NON_NULL); 二.设置在反序列化时忽略在JSON字符串中存在,而在Java中不存在的属性 new ObjectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 三.Jackson序列化时忽略字段的方式 1.方式一:FilterProvider a)在需

  • Jackson序列化丢失泛型的解决

    Jackson序列化丢失泛型 经过 项目中遇到一个奇怪的bug,即一个Map<Integer,List<Integer>>的泛型map,向map中get一个存在的key,事实上却返回null. 经过排查,发现是该map被Jackson序列化后,key的类型从Integer变成了String类型.再经过反序列化,即使已经声明key泛型的Integer,反序列化后内存数据中的key为String并不是Integer类型且并未抛出异常. 复现 1.声明一个key泛型为Integer的ma

随机推荐