How to make fastjson support JDK8 new time objects LocalDate, LocalDateTime in Spring Book

Keywords: JSON Spring JDK

When fastjson is used to process JSON format conversion in Spring Book, by default, LocalDateTime and LocalDate objects in JDK 1.8 are not supported. To support these objects, you can define the relevant ObjectDeserializer to handle them and use the ParserConfig.getGlobalInstance().putDeserializer method to configure them globally.

The realization is as follows:

@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 Deserializing classes from JSON strings
     *
     * @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) {
            // If it is in string format
            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;
        }
    }
}

Note that parser.getLexer().nextToken(); this step must be called, otherwise an error will be reported. It means to jump to the next node that needs to be processed after getting the data of the current node. If not handled, the following errors may be reported:

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

Posted by BTalon on Tue, 26 Mar 2019 22:27:32 -0700