How to Use FastJSON, Gson and Jackson to Customize Time Serialization

Posted by adammo on Wed, 05 Jun 2019 20:20:51 +0200

Java processing JSON data has three popular class libraries FastJSON, Gson and Jackson.

  • Jackson

Jackson is maintained by its community, simple to use and relatively high performance. But for complex bean s to transform Json, the format of the transformation despises the standard Json format. PS:Jackson built-in Json parsing tool for Spring MVC

  • Gson

Gson is a product developed by Google and is currently the most complete Json parsing tool. Complex types of Json can be parsed into beans or beans to Json transformations

  • FastJson

Fastjson is a high performance JSON processor written in Java language, developed by Alibaba. FastJson uses original algorithms to speed up parse to its maximum, exceeding all JSON libraries. However, there are some problems on some complex types of Bean transformation Json, which need special treatment.

1. Problems encountered

When the Java platform invokes the services provided by. Net through the interface, it often encounters the incorrect conversion of time format when Json serializes.

The Json serialization built into the. Net platform uses System.Runtime.Serialization, and the serialized time is in the following format

\/Date(1296576000000+0800)\/

2. Thoughts

In order to invoke the services provided by the. Net platform, the above format can be serialized when the time format (Date) is serialized. Then spell the time string.

  • Java code
Date now = new Date();
String nowStr = String.format("\\/Date(%s+0800)\\/", now.getTime());

3. Code

  • Dependent on Jar packages
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.1'
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.36'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.0'
  • Custom Time Conversion String Code
public class StringSmallUtils {

    /**
     * Converts the time type format to the specified String type
     *
     * @param date
     * @return
     */
    protected static String DateToSpecialString(Date date) {
        if (date == null)
            return null;
        return String.format("\\/Date(%s+0800)\\/", date.getTime());
    }

    /**
     * Converts the specified String type to a time type format
     *
     * @param str
     * @return
     */
    protected static Date SpecialStringToDate(String str) {
        if (isEmpty(str))
            return null;
        if (!contains(str,"Date"))
            return null;
        str = str.replace("\\/Date(", "").replace("+0800)\\/", "").trim();
        return new Date(Long.parseLong(str));
    }


    /**
     * Determine whether a string contains an input string
     *
     * @param str
     * @param searchStr
     * @return
     */
    public static boolean contains(String str, String searchStr) {
        if (str == null || searchStr == null) {
            return false;
        }
        return str.contains(searchStr);
    }

    /**
     * Determine whether a string is empty
     *
     * @param str
     * @return
     */
    public static boolean isEmpty(String str) {
        return ((str == null) || (str.trim().isEmpty()));
    }
}

3.1 Gson custom implementation of Date Json string serialization

Gson custom Json sequence class only needs to implement JsonSerializer < T > interface and deserialized interface JsonDeserializer < T >

public class GsonCustomerDateJsonSerializer implements JsonSerializer<Date>, JsonDeserializer<Date> {
    @Override
    public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(StringSmallUtils.DateToSpecialString(src));
    }

    @Override
    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return StringSmallUtils.SpecialStringToDate(json.getAsString());
    }
}
  • test

Gson's custom serialized classes are registered on Gson through the adapter pattern.

public class Program {
    public static void main(String[] args) throws JsonProcessingException {
        Date start = new Date();
        Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new GsonCustomerDateJsonSerializer()).create();
        String gsonStr = gson.toJson(createUser());
        Date end = new Date();
        long interval = (end.getTime() - start.getTime());
        System.out.println(String.format("Gson Serialized string:%s,Spending time%d Millisecond", gsonStr, interval));
    }

    private static User createUser() {
        User user = new User();
        user.setName("Zhang San");
        user.setAge(21);
        user.setLastlogintime(new Date());
        return user;
    }
}

3.2 FasJSON Custom Implementation of Date Json String Serialization

FastJSON custom serialization only needs to implement the ObjectSerializer interface and the Deserializer interface.

public class FastJsonCustomerDateJsonSerializer implements ObjectSerializer, ObjectDeserializer {
    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
        SerializeWriter out = serializer.getWriter();
        out.write(StringSmallUtils.DateToSpecialString((Date) object));
    }

    @Override
    public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
        return (T) StringSmallUtils.SpecialStringToDate(parser.getInput());
    }

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

FastJSON custom serializer classes are serializersMap objects maintained internally through SerializeConfig

public class Program {
    public static void main(String[] args) throws JsonProcessingException {
        Date start1 = new Date();
        SerializeConfig mapping = new SerializeConfig();
        mapping.put(Date.class, new FastJsonCustomerDateJsonSerializer());
        String fastjsonStr = JSON.toJSONString(createUser(), mapping);
        Date end1 = new Date();
        long interval1 = (end1.getTime() - start1.getTime());
        System.out.println(String.format("FastJSON Serialized string:%s,Spending time%d Millisecond", fastjsonStr, interval1));
    }

    private static User createUser() {
        User user = new User();
        user.setName("Zhang San");
        user.setAge(21);
        user.setLastlogintime(new Date());
        return user;
    }
}

3.3 Jackson Customizes Date Json String Serialization

Jackson's custom serialized classes need to inherit Json Deserializer < T>. Since Java can only inherit in one way, Jackson's custom deserialized class needs to create a new deserialized class inheriting JsonDeserializer < T > class.

public class JacksonCustomerDateJsonSerializer extends JsonSerializer<Date> {
    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(StringSmallUtils.DateToSpecialString(value));
    }
}
public class JacksonCustomerDateJsonDeserializer extends JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        return StringSmallUtils.SpecialStringToDate(p.getText());
    }
}
  • test

Jackson's custom serialization class needs to be registerModule. That is, you need to register the new serialized class to SimpleModule

public class Program {
    public static void main(String[] args) throws JsonProcessingException {
        Date start2 = new Date();
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Date.class, new JacksonCustomerDateJsonSerializer());
        module.addDeserializer(Date.class, new JacksonCustomerDateJsonDeserializer());
        mapper.registerModule(module);
        String jacksonStr = mapper.writeValueAsString(createUser());
        Date end2 = new Date();
        long interval2 = (end2.getTime() - start2.getTime());
        System.out.println(String.format("Jackson Serialized string:%s,Spending time%d Millisecond", jacksonStr, interval2));
    }

    private static User createUser() {
        User user = new User();
        user.setName("Zhang San");
        user.setAge(21);
        user.setLastlogintime(new Date());
        return user;
    }
}

4. Summary

The time and results of the three final runs are as follows:

The string after Gson serialization: {"Name", "Zhang San", "Age": 21, "Lastlogintime": " Date (1502366214027+0800)\ /", takes 77 milliseconds.
FastJSON serialized string: {"age": 21, "lastlogintime"; Date (15023214100 + 0800); /, "name", "Zhangsan"} takes 99 milliseconds
 The string after Jackson's serialization: {"name": "Zhang San", "age": 21, "lastlogintime": " Date (15023214307+0800)\/", takes 200 milliseconds.
  • 1. In terms of code implementation, Gson and FastJSON are better than Jackson. Interface-oriented programming.
  • 2. In terms of registration methods, Gson is better than FastJSON and Jackson. Using the adapter model
  • 3. In terms of operation efficiency, Gson and FastJSON are better than Jackson. Gson is three times Jackson's and FastJSON is twice Jackson's.

In practical projects, priority should be given to using Gson and FastJSON

Topics: JSON Java Google Spring