Fastjson1 自定义序列化器 ObjectSerializer

在 Java 开发中,JSON 序列化是一个常见需求。Fastjson 作为一款高性能的 JSON 框架,默认提供了丰富的序列化支持,但有时我们需要自定义序列化逻辑。本文将详细介绍如何使用 Fastjson1 的 ObjectSerializer 接口实现自定义序列化。

为什么需要自定义序列化器?

假设你有这样一个场景:一个 User 对象包含敏感字段(如密码),默认序列化会将所有字段暴露出去。或者,你需要将某个对象按照特定格式输出,比如日期格式化、字段重命名等。这时,自定义序列化器就派上用场了。

实现自定义序列化器

Fastjson1 提供了 ObjectSerializer 接口,我们可以通过实现它来自定义序列化逻辑。

步骤1:创建实体类

public class User {
    private String name;
    private String password;
    private int age;

    // 构造方法和 getter/setter 省略
    public User(String name, String password, int age) {
        this.name = name;
        this.password = password;
        this.age = age;
    }

    // 必须提供 getter 方法
    public String getName() { return name; }
    public String getPassword() { return password; }
    public int getAge() { return age; }
}

步骤2:实现 ObjectSerializer 接口

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;

import java.io.IOException;
import java.lang.reflect.Type;

public class UserSerializer implements ObjectSerializer {

    @Override
    public void write(JSONSerializer serializer, Object object, 
                      Object fieldName, Type fieldType, int features) 
                      throws IOException {

        User user = (User) object;
        // 自定义序列化逻辑:只输出 name 和 age,隐藏 password
        serializer.write("{\"name\":\"" + user.getName() + 
                         "\",\"age\":" + user.getAge() + "}");
    }
}

步骤3:注册自定义序列化器

有两种方式注册:

方式一:全局注册

import com.alibaba.fastjson.serializer.SerializeConfig;

public class SerializerDemo {
    public static void main(String[] args) {
        // 创建全局配置
        SerializeConfig config = new SerializeConfig();
        // 注册自定义序列化器
        config.put(User.class, new UserSerializer());

        User user = new User("张三", "123456", 25);

        // 使用自定义配置进行序列化
        String json = com.alibaba.fastjson.JSON.toJSONString(user, config);
        System.out.println(json); // 输出: {"name":"张三","age":25}
    }
}

方式二:使用注解

import com.alibaba.fastjson.annotation.JSONField;

public class User {
    // 其他字段省略

    @JSONField(serializeUsing = UserSerializer.class)
    private String name;

    // 注意:这种方式只能应用于单个字段
}

高级用法:带条件序列化

有时我们需要根据运行时条件决定序列化行为:

public class ConditionalUserSerializer implements ObjectSerializer {

    @Override
    public void write(JSONSerializer serializer, Object object, 
                      Object fieldName, Type fieldType, int features) 
                      throws IOException {

        User user = (User) object;
        serializer.write("{");

        // 始终输出 name
        serializer.write("\"name\":\"" + user.getName() + "\"");

        // 根据年龄决定是否输出年龄字段
        if (user.getAge() > 18) {
            serializer.write(",\"age\":" + user.getAge());
        }

        // 密码始终不输出
        serializer.write("}");
    }
}

性能优化建议

  1. 使用 StringBuffer 或 StringBuilder:在自定义序列化器中,避免使用字符串拼接,建议使用 StringBuilder 提高性能。
  2. 预编译正则表达式:如果序列化需要正则处理,请预先编译。
  3. 线程安全ObjectSerializer 实现应该是线程安全的,最好是无状态的。

常见问题

Q:自定义序列化器会影响反序列化吗?
A:不会,ObjectSerializer 只影响序列化过程。如果需要自定义反序列化,应实现 ObjectDeserializer 接口。

Q:能否同时使用多个自定义序列化器?
A:可以,你可以为不同类注册不同的序列化器,Fastjson 会根据实际类型选择对应的序列化器。

总结

通过自定义 ObjectSerializer,我们可以精确控制对象的 JSON 输出格式。无论是隐藏敏感信息、格式化数据,还是实现复杂的序列化逻辑,这个接口都能提供强大的灵活性。建议在实际项目中根据业务需求合理使用,平衡灵活性和性能。