一、时间格式序列化
1、时间格式化
JSONObject.toJSONStringWithDateFormat(time, "yyyy-MM-dd HH:mm:ss")
Fastjson可以直接对Date类型进行格式化输出,格式化方法调用了Java标准库DateFormat的格式化方法,自行传入自定义的解析规则即可。
2、JSONField
public class Person { @JSONField(format="yyyy-MM-dd") private Date birthday; //... }
使用JSONField注解的format属性可以直接对Date类型进行格式化输出。
3、JSONType
@JSONType (dateFormat = "yyyy-MM-dd HH:mm:ss") public class Person { private Date createTime; //... }
通过JSONType注解实现类级别的日期格式化。
二、优化输出性能
1、缓存反射信息
public class User { private int id; private String name; //... private static final SerializeConfig config = new SerializeConfig(); static { config.put(User.class, new UserSerializer()); } }
Fastjson为每个类的序列化都会创建一个序列化器,序列化器的创建会涉及到反射机制,创建序列化器的过程是比较耗时的。如果需要对同一类型的数据进行反复序列化,则可以使用静态的变量来缓存序列化的配置信息,避免反射机制的开销。
2、指定序列化顺序
public class User { private int id; private String name; //... static class IdNameSerializer implements JavaBeanSerializer { public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.out; User user = (User) object; Integer id = user.getId(); String name = user.getName(); if ((features & SerializerFeature.SortField.mask) != 0) { out.write('{'); serializer.out.writeFieldName("id"); serializer.out.writeInt(id); serializer.out.write(','); serializer.out.writeFieldName("name"); serializer.out.writeString(name); serializer.out.write('}'); } else { out.write('{'); out.writeFieldName("name"); serializer.write(name); out.write(','); out.writeFieldName("id"); out.writeInt(id); out.write('}'); } } } }
Fastjson对于JavaBean的序列化顺序默认采用ASCII码顺序,可以使用SortFeild序列话属性控制输出顺序。此外,也可以编写自定义序列化器来制定输出顺序。
三、自定义输出
1、ValueFilter
ValueFilter valueFilter = new ValueFilter() { public Object process(Object obj, String s, Object v) { if(v == null) { return ""; } return v; } }; String jsonString = JSONObject.toJSONString(map, valueFilter);
通过实现ValueFilter接口,可以在序列化过程中动态改变某些Bean属性的值。
2、PropertyFilter
PropertyFilter propertyFilter = new PropertyFilter() { public boolean apply(Object object, String name, Object value) { if(name.equalsIgnoreCase("password")){ return false; } return true; } }; String jsonString = JSONObject.toJSONString(user, propertyFilter);
通过实现PropertyFilter接口,可以过滤不想序列化的Bean属性。
3、SerializeFilter
public class ValueLabelFilter implements NameFilter { private Object value; private String label; public ValueLabelFilter(Object value, String label) { this.value = value; this.label = label; } public String process(Object source, String name, Object value) { if (this.value.equals(value)) { return this.label; } return name; } } ValueLabelFilter filter = new ValueLabelFilter(0, "男"); SerializeFilter[] filters = {filter}; String jsonString = JSONObject.toJSONString(user, filters);
通过实现SerializeFilter接口,可以控制序列化过程中修改每个属性序列化时的过滤要求,一般同时实现NameFilter、ValueFilter、PropertyFilter三个接口。
四、异常处理
1、关闭循环引用检测
JSON.toJSONString(xxx, SerializerFeature.DisableCircularReferenceDetect)
默认情况下,Fastjson会检测到循环引用并抛出异常,如果不需要对循环引用进行处理,则可以禁用此项检测。
2、定制异常处理器
public class MyException extends RuntimeException { public MyException(Throwable cause) { super(cause); } } public class MyExceptionHandler implements ExceptionHandler { @Override public void handle(Exception ex) { throw new MyException(ex); } @Override public void handle(Exception ex, Object obj, Object fieldName) { throw new MyException(ex); } } SerializeWriter out = new SerializeWriter(); JSONSerializer serializer = new JSONSerializer(out); serializer.setExceptionHandler(new MyExceptionHandler()); serializer.write(jsonObject);
如果Fastjson序列化过程中出现异常,则会自动调用默认的异常处理器,将异常信息打印出来。但是,你也可以定制自己的异常处理器,来处理Fastjson发生的异常。