首页 > 其他分享 >自定义全局反序列化器

自定义全局反序列化器

时间:2023-09-19 11:24:43浏览次数:40  
标签:JsonToken return 自定义 parser CustomerLocalDateTimeDeserializer LocalDateTime impo

以处理LocalDateTime格式的全局反序列化器为例,全局序列化器类似

1、全局反序列化器代码

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.datatype.jsr310.deser.JSR310DateTimeDeserializerBase;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;

import java.io.IOException;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class CustomerLocalDateTimeDeserializer extends JSR310DateTimeDeserializerBase<LocalDateTime> {

    public CustomerLocalDateTimeDeserializer() {
        this(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    }

    public CustomerLocalDateTimeDeserializer(DateTimeFormatter formatter) {
        super(LocalDateTime.class, formatter);
    }

    protected CustomerLocalDateTimeDeserializer(CustomerLocalDateTimeDeserializer base, Boolean leniency) {
        super(base, leniency);
    }

    protected CustomerLocalDateTimeDeserializer withDateFormat(DateTimeFormatter formatter) {
        return new CustomerLocalDateTimeDeserializer(formatter);
    }

    protected CustomerLocalDateTimeDeserializer withLeniency(Boolean leniency) {
        return new CustomerLocalDateTimeDeserializer(this, leniency);
    }

    protected CustomerLocalDateTimeDeserializer withShape(JsonFormat.Shape shape) {
        return this;
    }

    @Override
    public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
        if (parser.hasTokenId(6)) {
            String string = parser.getText().trim();
            if (string.length() == 0) {
                return !this.isLenient() ? (LocalDateTime)this._failForNotLenient(parser, context, JsonToken.VALUE_STRING) : null;
            } else {
                try {
                    // 这里有点改造
                    if (string.length() > 10 && string.charAt(10) == 'T') {
                        return string.endsWith("Z") ?
                                LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.UTC) :
                                LocalDateTime.parse(string);
                    } else {
                        LocalDateTime.parse(string);
                        return LocalDateTime.parse(string, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    }
                } catch (DateTimeException var12) {
                    return (LocalDateTime)this._handleDateTimeException(context, var12, string);
                }
            }
        } else {
            // 直接从com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize() 拷贝的
            if (parser.isExpectedStartArrayToken()) {
                JsonToken t = parser.nextToken();
                if (t == JsonToken.END_ARRAY) {
                    return null;
                }

                LocalDateTime result;
                if ((t == JsonToken.VALUE_STRING || t == JsonToken.VALUE_EMBEDDED_OBJECT) && context.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
                    result = this.deserialize(parser, context);
                    if (parser.nextToken() != JsonToken.END_ARRAY) {
                        this.handleMissingEndArrayForSingle(parser, context);
                    }

                    return result;
                }

                if (t == JsonToken.VALUE_NUMBER_INT) {
                    int year = parser.getIntValue();
                    int month = parser.nextIntValue(-1);
                    int day = parser.nextIntValue(-1);
                    int hour = parser.nextIntValue(-1);
                    int minute = parser.nextIntValue(-1);
                    t = parser.nextToken();
                    if (t == JsonToken.END_ARRAY) {
                        result = LocalDateTime.of(year, month, day, hour, minute);
                    } else {
                        int second = parser.getIntValue();
                        t = parser.nextToken();
                        if (t == JsonToken.END_ARRAY) {
                            result = LocalDateTime.of(year, month, day, hour, minute, second);
                        } else {
                            int partialSecond = parser.getIntValue();
                            if (partialSecond < 1000 && !context.isEnabled(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
                                partialSecond *= 1000000;
                            }

                            if (parser.nextToken() != JsonToken.END_ARRAY) {
                                throw context.wrongTokenException(parser, this.handledType(), JsonToken.END_ARRAY, "Expected array to end");
                            }

                            result = LocalDateTime.of(year, month, day, hour, minute, second, partialSecond);
                        }
                    }

                    return result;
                }

                context.reportInputMismatch(this.handledType(), "Unexpected token (%s) within Array, expected VALUE_NUMBER_INT", new Object[]{t});
            }

            if (parser.hasToken(JsonToken.VALUE_EMBEDDED_OBJECT)) {
                return (LocalDateTime)parser.getEmbeddedObject();
            } else {
                if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
                    this._throwNoNumericTimestampNeedTimeZone(parser, context);
                }

                return (LocalDateTime)this._handleUnexpectedToken(context, parser, "Expected array or string.", new Object[0]);
            }
        }
    }
}

2、将自定义的全局反序列化器加入调用链(配置)

import com.haier.boot.deserializer.CustomerLocalDateTimeDeserializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


@Configuration
public class LocalDateTimeSerializerConfig {



    @Bean
    public CustomerLocalDateTimeDeserializer customerLocalDateTimeDeserializer() {
        return new CustomerLocalDateTimeDeserializer();
    }


    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            builder.deserializerByType(LocalDateTime.class, customerLocalDateTimeDeserializer());
        };
    }

}

标签:JsonToken,return,自定义,parser,CustomerLocalDateTimeDeserializer,LocalDateTime,impo
From: https://www.cnblogs.com/shareToAll/p/17714135.html

相关文章

  • 序列化器
    序列化器作用1、序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串,即把数据库的表数据转换成客户端的json格式并返回2、反序列化,反序列化器会把客户端发送过来的数据。经过request以后变成字典,序列化器可以把字典转成模型3、反序列化,完......
  • 自定义异常类处理
    在编程过程中,异常是不避免的,为了是我们的代码更加可靠,我们需要学会如何处理异常。一下是自定义异常以及异常处理的一个小案例:#一.自定义异常类MyException类,测试当用户输入的数字大于90,raise主动抛出并处理该异常classMyException(Exception):def__init__(self,msg):......
  • Vue学习七:自定义创建项目和vuex
    一、自定义创建项目默认的项目有很多包不全,需要的时候还要导包搭架子,因此我们可以自定义创建项目。选择的项目按照自己需要的设置,可参考如下参数设置。(eslink是一种代码规范)二、vuex1、vuex概述vuex是一个vue的状态管理工具,状态就是数据。大白话:vuex是一个插件,可以帮我们......
  • netty发送socket短连接请求,自定义报文头
    packagecom.chinaums.japi.util;importio.netty.bootstrap.Bootstrap;importio.netty.buffer.ByteBuf;importio.netty.buffer.Unpooled;importio.netty.channel.*;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.SocketChannel;......
  • 自定义对象的of生成操作
    自定义对象的of生成逻辑依赖于lombok的注解@RequiredArgsConstructor(staticName="of")写法@Accessors(chain=true)@Setter@Getter@RequiredArgsConstructor(staticName="of")publicclassStudent{@NonNullprivateStringname;priva......
  • Kingbase ES 自定义聚合函数和一次改写案例
    文章概要:KES的SQL的语法暂时不兼容oracle的自定义聚合函数的创建语法和流程,但是可以使用KES已支持的语法改写。本文整理和简单解析了自定义聚合函数的原理和解读了范例代码。并根据客户代码进行了改写。一,oracle自定义聚合函数的简析oracle的自定义聚合函数需要实现4个ODCIAg......
  • 自定义注解@ValidValueList
    1、自定义注解@ValidValueList和验证器ValidValueListValidator来确保集合中的元素必须是在指定的值列表中。2、注解@ValidValueList允许你在字段或参数上标记一个集合,并为其提供一组有效的值。验证器ValidValueListValidator则用于检查集合中的元素是否都在指定的值列表......
  • 2023-09-18 hexo博客之如何自定义页面内容宽度==》在custom.styl中添加两行代码即可
    前言:我的hexo主题为hexo-theme-next 5.1.4版本。操作如下:打开你的博客名称\themes\hexo-theme-next\source\css\_variables,找到这个文件custom.styl,然后把下面代码添加进去:$main-desktop=1200px$content-desktop=1000px刷新页面即可见效。......
  • EasyCode自定义模板
    一、前言最近做了几个傻瓜式的CRUD模块,光调整EasyCode生成的代码格式就调整了半天,毫无意义,但又必不可少。于是,网上找了关于EasyCode自定义模板的文章,尝试自定义模板,从根本上解决代码格式调整的痛点。EasyCode是IDEA开发的一个代码生成插件,主要通过自定义模板(基......
  • KingbaseESV8R6全局临时表不能进行reindex操作
    背景我们经常遇到两种情况下会重建索引,reindex1、索引崩溃,由于软件或硬件问题导致索引内数据失效而不可用。2、索引膨胀,当索引膨胀会占用过多磁盘空间,reindex可以解决此问题。对于临时表和全局临时表而言,临时表可以进行reindex操作,而全局临时表不能进行此操作,原因是全局临时表......