开发者社区> 问答> 正文

fastjson 2 定制序列化 ObjectWriter的问题

我在 配置类编写了 自定义的序列化 规则,但是为什么没有使用自定义的规则,还是使用了默认的规则。

JSON.register(LocalDate.class, MyLocalDateWriter.instance);

经下断点调试: 并没有运行 MyLocalDateWriter.instance 中的 write 方法,而是运行了自带的 com.alibaba.fastjson2.writer.ObjectWriterImplLocalDate 中的 write 方法,导致了 输出结果达不到期望效果。

期望效果:2022-06-13 实际效果:2022-06-13 00:00:00

是不是我的写法有问题,请多指教,写法参考 实现ObjectWriter和ObjectReader实现定制序列化和反序列化 https://alibaba.github.io/fastjson2/register_custom_reader_writer_cn

package re.lpy.supermall.user.config;

import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONReader; import com.alibaba.fastjson2.JSONWriter; import com.alibaba.fastjson2.codec.DateTimeCodec; import com.alibaba.fastjson2.support.config.FastJsonConfig; import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter; import com.alibaba.fastjson2.writer.ObjectWriter; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Collections; import java.util.List;

@Configuration @EnableWebMvc public class FastJson2Configurer implements WebMvcConfigurer {

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
    
    //自定义配置...
    FastJsonConfig config = new FastJsonConfig();
    config.setDateFormat("yyyy-MM-dd HH:mm:ss");
    
    config.setReaderFeatures(JSONReader.Feature.FieldBased,
                             JSONReader.Feature.SupportArrayToBean,
                             JSONReader.Feature.InitStringFieldAsEmpty,
                             JSONReader.Feature.SupportAutoType,
                             JSONReader.Feature.SupportClassForName,
                             JSONReader.Feature.IgnoreSetNullValue);
    // JSONWriter.Feature.WriteNulls, 输出空值
    config.setWriterFeatures(
            JSONWriter.Feature.BrowserCompatible,
            JSONWriter.Feature.NullAsDefaultValue,
            JSONWriter.Feature.PrettyFormat,
            JSONWriter.Feature.WriteBigDecimalAsPlain);
    
    converter.setFastJsonConfig(config);
    converter.setDefaultCharset(StandardCharsets.UTF_8);
    converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
    // 移除jackson
    converters.removeIf(converters::contains);
    converters.add(0, converter);

    JSON.register(LocalDateTime.class, MyLocalDateTimeWriter.instance); // 1
    JSON.register(LocalDate.class, MyLocalDateWriter.instance); // 1
    JSON.register(LocalTime.class, MyLocalTimeWriter.instance); // 1
}

}

class MyLocalDateTimeWriter extends DateTimeCodec implements ObjectWriter { static MyLocalDateTimeWriter instance = new MyLocalDateTimeWriter(null);

public MyLocalDateTimeWriter(String format) {
    super(format);
}

@Override
public void write(JSONWriter jsonWriter, Object o, Object o1, Type type, long l) {
        if (o == null) {
            jsonWriter.writeNull();
            return;
        }
    String typeName = type.getTypeName();
    LocalDateTime dateTime = (LocalDateTime) o;
        
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = formatter.format(dateTime);
        
        jsonWriter.writeString(format);
}

}

class MyLocalDateWriter implements ObjectWriter { static MyLocalDateWriter instance = new MyLocalDateWriter();

@Override
public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
    if (object == null) {
        jsonWriter.writeNull();
        return;
    }
    LocalDate date = (LocalDate) object;
    // LocalDate date = dateTime.toLocalDate();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    String format = formatter.format(date);
    // 优先使用name
    jsonWriter.writeString(format);
}

}

class MyLocalTimeWriter implements ObjectWriter { static MyLocalTimeWriter instance = new MyLocalTimeWriter();

@Override
public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
    if (object == null) {
        jsonWriter.writeNull();
        return;
    }
    LocalTime time = (LocalTime) object;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    String format = formatter.format(time);
    // 优先使用name
    jsonWriter.writeString(format);
}

}

fastjson 2.0.7 最新版 ,2.0.5 是可以这样的,2.0.6未知 openjdk1.8.333

原提问者GitHub用户yangcanlin

展开
收起
飘飘斯嘉丽 2023-04-21 12:02:14 565 0
1 条回答
写回答
取消 提交回答
  • 请用2.0.8-SNAPSHOT验证,可以如下这样的写法:

    https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.8-SNAPSHOT/

    public class FormatTest { @Test public void test() { LocalDate date = LocalDate.of(2017, 12, 13); LocalDateTime dateTime = LocalDateTime.of(2017, 1, 2, 12, 13, 14);

        Bean bean = new Bean();
        bean.date = date;
        bean.dateTime = dateTime;
    
        JSON.mixIn(LocalDateTime.class, LocalDateTimeMixin.class);
        assertEquals("{\"date\":\"2017-12-13\",\"dateTime\":\"2017-01-02 12:13:14\"}", JSON.toJSONString(bean));
    
        // clear cache
        JSON.mixIn(LocalDateTime.class, null);
        JSON.mixIn(Bean.class, null);
    
        assertEquals("{\"date\":\"2017-12-13\",\"dateTime\":\"2017-01-02T12:13:14\"}", JSON.toJSONString(bean));
    
        JSON.mixIn(LocalDateTime.class, null);
        JSON.mixIn(Bean.class, null);
    
        JSON.mixIn(LocalDate.class, LocalDateMixin.class);
        assertEquals("\"2017-12-13 00:00:00\"", JSON.toJSONString(date));
        JSON.mixIn(LocalDate.class, null);
        assertEquals("\"2017-12-13\"", JSON.toJSONString(date));
    }
    
    @JSONType(format = "yyyy-MM-dd HH:mm:ss")
    public static class LocalDateMixin {
    }
    
    @JSONType(format = "yyyy-MM-dd HH:mm:ss")
    public static class LocalDateTimeMixin {
    }
    
    public static class Bean {
        public LocalDateTime dateTime;
        public LocalDate date;
    }
    

    }

    原回答者GitHub用户wenshao

    2023-04-21 14:41:09
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载