Spring Boot中如何使得fastjson支持JDK8新时间对象LocalDate、LocalDateTime

在Spring Boot中使用fastjson来处理JSON格式转换时,默认情况下是不支持JDK1.8中的LocalDateTime及LocalDate等时间对象的。为使其支持这些对象,可以定义相关的ObjectDeserializer来处理,并将定义的对象通过ParserConfig.getGlobalInstance().putDeserializer方法将其作为全局配置。

实现如下:

@Configuration
public class JSONConfiguration {
    @PostConstruct
    public void init() {
        ParserConfig.getGlobalInstance().putDeserializer(LocalDate.class, new LocalDateDeserializer());
        ParserConfig.getGlobalInstance().putDeserializer(LocalDateTime.class, new LocalDateDeserializer());
    }

    private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy.MM.dd");

    /**
     * LocalDate从JSON字符串反序列化类
     *
     * @author LiuQI 2019/3/8 13:45
     * @version V1.0
     **/
    public static class LocalDateDeserializer implements ObjectDeserializer {
        @Override
        public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
            // 如果是字符串格式
            String value = parser.getLexer().stringVal();
            parser.getLexer().nextToken();

            if (value.contains("-")) {
                if (type.equals(LocalDateTime.class)) {
                    return (T) LocalDateTime.parse(value, dateTimeFormatter);
                } else {
                    return (T) LocalDate.parse(value, dateTimeFormatter);
                }
            } else if (value.contains(".")) {
                if (type.equals(LocalDateTime.class)) {
                    return (T) LocalDateTime.parse(value, dateTimeFormatter1);
                } else {
                    return (T) LocalDate.parse(value, dateTimeFormatter1);
                }
            }

            long longValue = Long.parseLong(value) / 1000;
            if (type.equals(LocalDateTime.class)) {
                return (T) LocalDateTime.ofEpochSecond(longValue, 0, ZoneOffset.ofHours(8));
            } else if (type.equals(LocalDate.class)) {
                return (T) LocalDateTime.ofEpochSecond(longValue, 0, ZoneOffset.ofHours(8)).toLocalDate();
            }

            return null;
        }

        @Override
        public int getFastMatchToken() {
            return 0;
        }
    }
}

注意,parser.getLexer().nextToken();这一步骤是必须要调用的,否则将会报错。它的意思是获取到当前节点的数据后,跳转到下一需要处理的节点。如果不处理,有可能会报如下的错误:

com.alibaba.fastjson.JSONException: not close json text, token : string

你可能感兴趣的:(Spring)