Fastjson1 @JSONField 注解

在Java开发中,我们经常遇到这样的场景:Java 对象的属性名和 JSON 中的字段名不一致,或者只想序列化某些字段,又或者想要自定义日期格式。这时候可以使用@JSONField 注解来解决这些问题。

@JSONField 是什么?

@JSONField 是 Fastjson 提供的一个注解,主要用于控制 类属性与 JSON 字段之间的映射关系。它可以作用在 字段(field)方法的 getter/setter 上。

使用前请确保你的项目已经引入了 Fastjson:

自定义字段名称(name 属性)

最常用的场景:Java 属性叫 userName,但 JSON 中包含的是 user_name

public class User {
    @JSONField(name = "user_name")
    private String userName;

    // 省略 getter/setter
    public String getUserName() { return userName; }
    public void setUserName(String userName) { this.userName = userName; }
}

测试一下:

User user = new User();
user.setUserName("Tom");

String json = JSON.toJSONString(user);
System.out.println(json); // 输出:{"user_name":"Tom"}

User parsed = JSON.parseObject("{\"user_name\":\"Jerry\"}", User.class);
System.out.println(parsed.getUserName()); // 输出:Jerry

可以看到,序列化时 userName 变成了 user_name,反序列化时也自动匹配到了 user_name 字段。

控制字段是否序列化

有时候,我们不想把某些敏感字段(比如密码)序列化到 JSON 输出中,或者不想从 JSON 中读取某个字段。其属性是serializedeserialize

public class Account {
    private String username;

    @JSONField(serialize = false)   // 序列化时忽略
    private String password;

    @JSONField(deserialize = false) // 反序列化时忽略
    private String internalCode;

    // getter/setter 略
}

测试代码:

Account acc = new Account();
acc.setUsername("admin");
acc.setPassword("123456");
acc.setInternalCode("secret");

String json = JSON.toJSONString(acc);
System.out.println(json);
// 输出:{"username":"admin"}    没有 password

String input = "{\"username\":\"admin\",\"password\":\"111\",\"internalCode\":\"xxx\"}";
Account parsed = JSON.parseObject(input, Account.class);
System.out.println(parsed.getPassword());   // null,因为 deserialize=false
System.out.println(parsed.getInternalCode()); // null

💡 注意:serialize=false 只影响序列化(Java → JSON),deserialize=false 只影响反序列化(JSON → Java)。

自定义日期格式(format 属性)

日期格式化是另一个高频需求。默认 Fastjson 会把 Date 转成时间戳,但通常我们希望输出“yyyy-MM-dd”这样的字符串。

public class Order {
    private String orderId;

    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    // getter/setter 略
}

测试:

Order order = new Order();
order.setOrderId("1001");
order.setCreateTime(new Date());

String json = JSON.toJSONString(order);
System.out.println(json);
// 输出:{"createTime":"2026-05-12 20:30:28","orderId":"1001"}

反序列化时也同样支持该格式:

String jsonStr = "{\"createTime\":\"2026-05-12 20:31:00\",\"orderId\":\"1002\"}";
Order order2 = JSON.parseObject(jsonStr, Order.class);
System.out.println(order2.getCreateTime()); // 输出 Tue May 12 20:31:00 CST 2026

格式字符串与 SimpleDateFormat 完全兼容。

指定序列化顺序(ordinal 属性)

如果你对 JSON 中字段的顺序有要求,可以用 ordinal 设置优先级,数字越小越靠前

public class Product {
    @JSONField(ordinal = 1)
    private String name;

    @JSONField(ordinal = 2)
    private double price;

    @JSONField(ordinal = 3)
    private int stock;
}

序列化结果:

{"name":"手机","price":2999.0,"stock":100}

即使添加新字段,也能保持这个顺序。

注意事项

  1. 优先作用在 getter/setter 上:如果字段和 getter 上都加了 @JSONField,Fastjson 会优先使用 getter 上的配置。
  2. 与 @JSONAlias 的区别@JSONAlias 主要用于反序列化时接受多个字段名,而 @JSONField 更偏向单一定义。初学者先用 @JSONField 就够了。
  3. 配合 Lombok 使用:如果你用了 Lombok,记得 @JSONField 直接加在字段上,Lombok 生成的 getter/setter 会自动继承注解。

总结

通过一个简单的 @JSONField 注解,我们就实现了:

  • 字段名映射(name
  • 字段忽略(serialize/deserialize
  • 日期格式化(format
  • 字段排序(ordinal

它是 Fastjson 中最基础也最灵活的配置方式,几乎每个实际项目中都会用到。