zoukankan      html  css  js  c++  java
  • FastJson配置全局LocalDateTime序列化

    最近工作中使用到了JDK1.8 time包,逐步取代以前的Date类,相比以前,time包的API的确好用多了,相关内容在网上有很多,就不累赘了。

    但是有点蛋疼的地方在于LocalDateTime支持ISO8601标准,即[2018-10-10T05:51:31.924Z]。在MVC中,习惯性用[yyyy-MM-dd HH:mm:ss]。
    好在Spring带有注解。如:

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss)
    private LocalDateTime ldt;
    

    @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date

    参数在Param上,可以使用@DateTimeFormat在参数或者参数实体的属性上。对于参数在body上,则可以通过自定义拓展Formatter或者Converter<String, LocalDateTime>,网上也有很多,这里就提供一下代码

    @Configuration
    public class LocalDateTimeFormatConfig {
    
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> Formatter<span class="token generics function"><span class="token punctuation">&lt;</span>LocalDate<span class="token punctuation">&gt;</span></span> <span class="token function">localDateFormatter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Formatter</span><span class="token generics function"><span class="token punctuation">&lt;</span>LocalDate<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token annotation punctuation">@Nullable</span> String <span class="token function">print</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Nullable</span> LocalDate object<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> Locale locale<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>Objects<span class="token punctuation">.</span><span class="token function">isNull</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
                    <span class="token keyword">return</span> null<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> object<span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span>DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span><span class="token string">"yyyy-MM-dd"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token annotation punctuation">@Nullable</span> LocalDate <span class="token function">parse</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Nullable</span> String text<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> Locale locale<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>StringUtils<span class="token punctuation">.</span><span class="token function">hasText</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    <span class="token keyword">return</span> null<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> LocalDate<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>text<span class="token punctuation">,</span> DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span><span class="token string">"yyyy-MM-dd"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> Formatter<span class="token generics function"><span class="token punctuation">&lt;</span>LocalDateTime<span class="token punctuation">&gt;</span></span> <span class="token function">localDateTimeFormatter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Formatter</span><span class="token generics function"><span class="token punctuation">&lt;</span>LocalDateTime<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token annotation punctuation">@Nullable</span> String <span class="token function">print</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Nullable</span> LocalDateTime object<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> Locale locale<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>Objects<span class="token punctuation">.</span><span class="token function">isNull</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
                    <span class="token keyword">return</span> null<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> object<span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span>DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span><span class="token string">"yyyy-MM-dd HH:mm:ss"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token annotation punctuation">@Nullable</span> LocalDateTime <span class="token function">parse</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Nullable</span> String text<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> Locale locale<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>StringUtils<span class="token punctuation">.</span><span class="token function">hasText</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    <span class="token keyword">return</span> null<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> LocalDateTime<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>text<span class="token punctuation">,</span> DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span><span class="token string">"yyyy-MM-dd HH:mm:ss"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> Formatter<span class="token generics function"><span class="token punctuation">&lt;</span>LocalTime<span class="token punctuation">&gt;</span></span> <span class="token function">localTimeFormatter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Formatter</span><span class="token generics function"><span class="token punctuation">&lt;</span>LocalTime<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token annotation punctuation">@Nullable</span> String <span class="token function">print</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Nullable</span> LocalTime object<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> Locale locale<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>Objects<span class="token punctuation">.</span><span class="token function">isNull</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
                    <span class="token keyword">return</span> null<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> object<span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span>DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span><span class="token string">"HH:mm:ss"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token annotation punctuation">@Nullable</span> LocalTime <span class="token function">parse</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Nullable</span> String text<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> Locale locale<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>StringUtils<span class="token punctuation">.</span><span class="token function">hasText</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    <span class="token keyword">return</span> null<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> LocalTime<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>text<span class="token punctuation">,</span> DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span><span class="token string">"HH:mm:ss"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    

    }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    public class LocalDateTimeConvertConfig {
    
    <span class="token keyword">private</span> String dateTimePattern <span class="token operator">=</span> <span class="token string">"yyyy-MM-dd HH:mm:ss"</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> String datePattern <span class="token operator">=</span> <span class="token string">"yyyy-MM-dd"</span><span class="token punctuation">;</span>
    
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> Converter<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> LocalDateTime<span class="token punctuation">&gt;</span></span> <span class="token function">LocalDateTimeConvert</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> source <span class="token operator">-</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
            DateTimeFormatter df <span class="token operator">=</span> DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span>dateTimePattern<span class="token punctuation">)</span><span class="token punctuation">;</span>
            LocalDateTime date <span class="token operator">=</span> null<span class="token punctuation">;</span>
            <span class="token keyword">try</span> <span class="token punctuation">{</span>
                date <span class="token operator">=</span> LocalDateTime<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>source<span class="token punctuation">,</span> df<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">return</span> date<span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> Converter<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> LocalDate<span class="token punctuation">&gt;</span></span> <span class="token function">localDateConverter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> source <span class="token operator">-</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
            DateTimeFormatter df <span class="token operator">=</span> DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span>datePattern<span class="token punctuation">)</span><span class="token punctuation">;</span>
            LocalDate date <span class="token operator">=</span> null<span class="token punctuation">;</span>
            <span class="token keyword">try</span> <span class="token punctuation">{</span>
                date <span class="token operator">=</span> LocalDate<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>source<span class="token punctuation">,</span>df<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><span class="token punctuation">{</span>
                e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">return</span> date<span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token comment">// 这里是使用JackSon全局序列化LocalDateTime,而我使用是FastJso,蛋疼</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> LocalDateTimeSerializer <span class="token function">localDateTimeDeserializer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">LocalDateTimeSerializer</span><span class="token punctuation">(</span>DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span>dateTimePattern<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> Jackson2ObjectMapperBuilderCustomizer <span class="token function">jackson2ObjectMapperBuilderCustomizer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> builder <span class="token operator">-</span><span class="token operator">&gt;</span> builder<span class="token punctuation">.</span><span class="token function">serializerByType</span><span class="token punctuation">(</span>LocalDateTime<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token function">localDateTimeDeserializer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    

    }

    这里要说的问题就是现在工作项目中遇到的问题,使用的FastJson,而不是MVC默认的JackSon,在序列化LocalDateTime输出到前端时候,是[2018-10-10T05:51:31.924Z],而想要输出的是yyyy-MM-dd HH:mm:ss格式,至此我们需要定制LocalDateTime类的序列化。我们一样可以使用注解解决,使用FastJson的@JSONField(format = “yyyy-MM-dd HH:mm:ss”),在需要特殊序列化的成员属性上。

    为了减少注解的使用,尝试是否可以让FastJson默认根据我们的规则去序列化LocalDateTime类。
    首先祭出常规的FastJsonConfig:

      FastJsonConfig fastJsonConfig = new FastJsonConfig();
      fastJsonConfig.setSerializerFeatures(
      SerializerFeature.PrettyFormat,
      SerializerFeature.WriteMapNullValue,
      ...
      SerializerFeature.WriteNullStringAsEmpty);
    fastJsonConfig.setCharset(Charset.forName("utf-8"));
    ...
    

    使用ValueFilter:

    ValueFilter valueFilter = (o, s, o1) -> {
        if (null == o1) {
            o1 = "";
        }
        if (o1 instanceof LocalDateTime){
            o1 = ((LocalDateTime) o1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        }
        return o1;
    };
    fastJsonConfig.setSerializeFilters(valueFilter);
    // 缺点,这是过滤级别的序列化,序列化的结果取决于o1的值,如将LocalDateTime类型的o1转换为String类型的o1,后续将不会调用LocalDateTime的序列化器,因为已经不是LocalDateTime类型了
    

    指定fastJsonConfig的DateFormat:

    fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
    ...
    // 缺点,指定后,将不会使用@JSONField注解上的format属性,包括并不限于Date类,LocalDateTime类,LocalDate类。(慎用)
    

    自定义LocalDateTimeSerializer实现ObjectSerializer接口,重写write方法:

    public class LocalDateTimeSerializer implements ObjectSerializer {
    
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> LocalDateTimeSerializer instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LocalDateTimeSerializer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String defaultPattern <span class="token operator">=</span> <span class="token string">"yyyy-MM-dd HH:mm:ss"</span><span class="token punctuation">;</span>
    
    <span class="token keyword">public</span> <span class="token function">LocalDateTimeSerializer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token punctuation">}</span>
    
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">write</span><span class="token punctuation">(</span>JSONSerializer serializer<span class="token punctuation">,</span> Object object<span class="token punctuation">,</span> Object fieldName<span class="token punctuation">,</span> Type fieldType<span class="token punctuation">,</span> <span class="token keyword">int</span> features<span class="token punctuation">)</span> <span class="token keyword">throws</span> IOException <span class="token punctuation">{</span>
        SerializeWriter out <span class="token operator">=</span> serializer<span class="token punctuation">.</span>out<span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>object <span class="token operator">==</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            out<span class="token punctuation">.</span><span class="token function">writeNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
            LocalDateTime result <span class="token operator">=</span> <span class="token punctuation">(</span>LocalDateTime<span class="token punctuation">)</span> object<span class="token punctuation">;</span>
            out<span class="token punctuation">.</span><span class="token function">writeString</span><span class="token punctuation">(</span>result<span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span>DateTimeFormatter<span class="token punctuation">.</span><span class="token function">ofPattern</span><span class="token punctuation">(</span>defaultPattern<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    

    }

    SerializeConfig serializeConfig = SerializeConfig.globalInstance;
    serializeConfig.put(LocalDateTime.class, LocalDateTimeSerializer.instance);
    fastJsonConfig.setSerializeConfig(serializeConfig);

    // 缺点,@JSONField注解一样会失效,仅限于LocalDateTime类
    ...

    如果使用的是JackSon,只需要在实例化LocalDateTimeSerializer的时候,指定一个DateTimeFormatter即可,方便很多,FastJson完败,有可能是我学艺不精,毕竟我是菜鸡。

    原文地址:https://blog.csdn.net/luomin369433047/article/details/88972543
  • 相关阅读:
    很好用的DBHelper类
    .net连接SAP的几种方式
    使用API管理平台的优势
    ASP.NET 2.0中的登陆控件简介
    asp.net 1.1/ 2.0 中快速实现单点登陆
    ASP.NET 2.0 成员资格和角色管理授权
    SqlDataSource 调用带参数的存储过程
    Asp.net中基于Forms验证的角色验证授权
    解释:ASP.NET 2.0 中的窗体身份验证
    SQL JOIN 的用法
  • 原文地址:https://www.cnblogs.com/jpfss/p/12156094.html
Copyright © 2011-2022 走看看