• Jackson ObjectMapper readValue过程


    1.整体调用栈

    2.看一下调用栈的两个方法

       

      

      

      resolve 方法中通过 Iterator i$ = this._beanProperties.iterator() 遍历属性的所有子属性,缓存对应的 deserializer。观察调用栈的方法,可以发现是循环调用的。

    3.比如寻找自定义的 LocalDateTime类的序列化实现类,看方法调用栈最上边的方法

      

      如果没有找到用户自定义的反序列化工具,则去找默认的标准反序列化工具

      

      

      

      deser = NumberDeserializers.find(rawType, clsName);
    deser = DateDeserializers.find(rawType, clsName); 

      可以看一下 com.fasterxml.jackson.databind.deser.std.DateDeserializers 和 com.fasterxml.jackson.databind.deser.std.NumberDeserializers,遍豁然开朗。

    4.加入对应类型序列化工具类

    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.JavaType;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    import java.lang.reflect.Type;
    import java.math.BigDecimal;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
    import xxx.utils.json.deserializers.LocalDateDeserializer;
    import xxx.utils.json.deserializers.LocalDateTimeDeserializer;
    import xxx.utils.json.deserializers.LocalTimeDeserializer;
    import xxx.utils.json.serializers.BigDecimalSerializer;
    import xxx.utils.json.serializers.LocalDateSerializer;
    import xxx.utils.json.serializers.LocalDateTimeSerializer;
    import xxx.utils.json.serializers.LocalTimeSerializer;
    
    public class JacksonHelper {
        private static final SimpleModule module = initModule();
        private static final ObjectMapper mapper;
        private static final ObjectMapper prettyMapper;
    
        public JacksonHelper() {
        }
    
        private static SimpleModule initModule() {
            return (new SimpleModule()).addSerializer(BigDecimal.class, new BigDecimalSerializer()).addSerializer(LocalTime.class, new LocalTimeSerializer()).addDeserializer(LocalTime.class, new LocalTimeDeserializer()).addSerializer(LocalDate.class, new LocalDateSerializer()).addDeserializer(LocalDate.class, new LocalDateDeserializer()).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()).addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        }
    
        public static JavaType genJavaType(Type type) {
            return getMapper().getTypeFactory().constructType(type);
        }
    
        public static ObjectMapper getMapper() {
            return mapper;
        }
    
        public static ObjectMapper getPrettyMapper() {
            return prettyMapper;
        }
    
        static {
            mapper = (new ObjectMapper()).registerModule(module).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true).configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            prettyMapper = mapper.copy().configure(SerializationFeature.INDENT_OUTPUT, true);
        }
    }
    MAPPER = JacksonHelper.getMapper().registerModule((new SimpleModule(LocalDateTimeDeserializer2.class.getName())).addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer2()));
            MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    import com.fasterxml.jackson.databind.JsonNode;
    import java.io.IOException;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        public LocalDateTimeDeserializer() {
        }
    
        public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
            String dateTimeStr = ((JsonNode)jp.getCodec().readTree(jp)).asText();
            return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        }
    }
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    import com.fasterxml.jackson.databind.JsonNode;
    import java.io.IOException;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    public class LocalDateTimeDeserializer2 extends JsonDeserializer<LocalDateTime> {
        public LocalDateTimeDeserializer2() {
        }
    
        public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
            String dateTimeStr = ((JsonNode)jp.getCodec().readTree(jp)).asText();
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return LocalDateTime.parse(dateTimeStr, df);
        }
    }

      可见,ObjectMapper registerModule 最后注册的module会优先被发现。例如上边首先 第一个 Module加入了一个LocalDateTime反序列化工具类LocalDateTimeDeserializer,接着第二个Module加入了LocalDateTime反序列化工具类LocalDateTimeDeserializer2,最后得到的反序列化工具类是LocalDateTimeDeserializer2。

    5.java.util.Date日期类型解析

      日期格式:yyyy-MM-dd HH:mm:ss

      第一种方法:MAPPER.setConfig(MAPPER.getDeserializationConfig().with(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")));

      第二种方法:自定义反序列化 MAPPER.registerModule((new SimpleModule(Date.class.getName())).addDeserializer(Date.class, DateDeserializer2.dateDeserializer));

    import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    
    public class DateDeserializer2 extends DateDeserializers.DateDeserializer{
        public static final DateDeserializer2 dateDeserializer = new DateDeserializer2(
                DateDeserializers.DateDeserializer.instance
                , new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss");
    
        public DateDeserializer2() {}
    
        public DateDeserializer2(DateDeserializers.DateDeserializer base, DateFormat df, String formatString) {
            super(base, df, formatString);
        }
    }

      默认的Date解析通过 DateDeserializers.DateDeserializer,时间的格式化处理是调用自己的StdDateFormat类来实现日期格式化

      

      而StdDateFormat定义的格式化如下

      

      DeserializationContext中为啥可以获取StdDateFormat(objectMapper readValue 时会创建DeserializationContext, 注入DeserializationConfig【包含BaseSettings(包含DateFormat)】)

      

      

      

  • 相关阅读:
    Effective JavaScript: 编写高质量JavaScript代码的68个有效方法(目录)
    第 13 条:使用立即调用的函数表达式创建局部作用域
    第11条:javascript闭包(Effective JavaScript读书笔记)
    .net各类视频教程
    IIS7视频教程
    快速排序
    冒泡排序
    python骚气的写法:b = lambda i, x: (tf.compat.v1.Print(i + 1, [i]), tf.compat.v1.Print(x + 1, [i], "x:"))
    服务器要放到水下
    keras包含各种内置层
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/8108488.html
Copyright © 2020-2023  润新知