前言
在 Java 开发中,进行对象与 JSON 的相互转换是一项常见操作,尤其在前后端分离的架构中显得尤为重要。Fastjson 作为阿里巴巴开源的 JSON 处理框架,因其高性能和强大功能而被广泛使用。@JSONField
是 Fastjson 提供的一个注解,用于精细控制 Java Bean 字段在序列化(Java 对象转 JSON)与反序列化(JSON 转 Java 对象)时的行为。
为什么需要 @JSONField
?它解决了哪些痛点?
在日常开发中,我们经常会遇到以下几个痛点:
Java 字段名与前端字段不一致:前端使用的是
user_name
,而 Java 中是username
,映射困难。时间格式不统一:JSON 默认的时间格式与系统或业务需求不同,需要手动格式化。
字段冗余或安全隐患:某些字段如
password
、token
不能被序列化,但默认会输出。后端字段更新但兼容老版本前端字段名:需要兼容多个字段名进行反序列化。
@JSONField
注解可以精准控制每一个字段的序列化和反序列化行为,从而有效解决上述问题,提高开发效率并降低出错概率。
一、@JSONField 注解简介
@JSONField
注解是 Fastjson 提供的元注解,位于 com.alibaba.fastjson.annotation.JSONField
包中。它允许开发者在字段或方法上配置特定的序列化/反序列化规则,从而达到灵活控制 JSON 输出和输入的目的。
二、常用属性说明
属性名 | 类型 | 说明 |
---|---|---|
name |
String |
指定字段在 JSON 中的名称 |
format |
String |
指定日期格式,例如 "yyyy-MM-dd HH:mm:ss" |
serialize |
boolean |
是否参与序列化,默认 true |
deserialize |
boolean |
是否参与反序列化,默认 true |
ordinal |
int |
字段排序优先级,值越小越靠前 |
defaultValue |
String |
反序列化时的默认值 |
alternateNames |
String[] |
支持反序列化时的多个字段名 |
三、基本使用示例
1. 重命名字段
public class User {
@JSONField(name = "user_name")
private String username;
// Getter & Setter
}
输出的 JSON:
{
"user_name": "jack"
}
2. 格式化日期字段
public class Event {
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
}
3. 控制字段参与序列化/反序列化
public class Login {
@JSONField(serialize = false)
private String password;
@JSONField(deserialize = false)
private String token;
}
4. 使用别名反序列化
public class Product {
@JSONField(alternateNames = {"productId", "id"})
private Long pid;
}
无论 JSON 中是 productId
还是 id
,都能正确反序列化为 pid
字段。
四、进阶技巧:搭配方法使用
除了作用在字段上,@JSONField
还可以作用在方法(尤其是 getter/setter)上,控制方法参与序列化与反序列化的行为:
public class Order {
private String status;
@JSONField(name = "order_status")
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
五、完整代码示例
我们通过一个综合示例类来演示多个 @JSONField
功能的组合使用:
// JSONFieldDemo.java
package com.example.fastjsondemo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import java.util.Date;
public class JSONFieldDemo {
static class User {
@JSONField(name = "user_name")
private String username;
@JSONField(serialize = false)
private String password;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createdAt;
public User(String username, String password, Date createdAt) {
this.username = username;
this.password = password;
this.createdAt = createdAt;
}
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public Date getCreatedAt() { return createdAt; }
public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; }
}
public static void main(String[] args) {
User user = new User("jack", "secret123", new Date());
String json = JSON.toJSONString(user);
System.out.println(json);
}
}
运行输出示例:
{
"user_name":"jack",
"createdAt":"2025-05-06 14:12:33"
}
六、实战注意事项
优先级问题:Fastjson 默认使用字段进行序列化,如果字段和 getter 都使用了
@JSONField
,字段上的注解优先。与
transient
冲突:transient
修饰的字段不会被序列化,即使加上了@JSONField
,也需要设置SerializerFeature.WriteMapNullValue
才可能生效。性能优化:通过设置
ordinal
属性可以控制序列化顺序,从而在某些场景下优化网络传输结构。避免与 Jackson 混用:项目中如果同时使用了 Fastjson 和 Jackson,要避免注解混淆导致序列化失效。
七、总结
@JSONField
是 Fastjson 提供的一个功能强大的注解,它允许开发者更灵活地控制对象的 JSON 映射行为。通过合理配置其属性,可以实现字段重命名、日期格式转换、序列化控制等多种功能,在企业级开发中非常实用。
如果你在项目中使用 Fastjson,掌握 @JSONField
的用法将大大提升你对 JSON 数据处理的掌控能力。