为什么在 JSON 序列化中不使用 transient
有些小伙伴发现了,明明在返回的实体类中指定了属性为transient。为什么前端得到的返回json中还是有这个属性的值?
类:
private String name;
private transient String password;
返回结果:
{
name:"刘大大",
password:"baofu"
}
1. 序列化是什么?
1.1 是什么?
序列化是将对象的状态(即其属性值)转换为一种可以存储或传输的形式的过程。这个过程通常用于以下几种场景:
- 持久化:将对象的状态保存到磁盘文件中,以便以后恢复。
- 网络传输:将对象的状态转换为字节流,以便在网络上传输。
- 进程间通信:将对象的状态转换为字节流,以便在不同的进程或线程之间传递。
1.2 主要目的
序列化的主要目的是确保对象的状态可以在不同的环境中准确地恢复。具体来说,序列化有以下几种常见形式:
- 二进制序列化:将对象转换为字节流。
- JSON 序列化:将对象转换为 JSON 格式。
- XML 序列化:将对象转换为 XML 格式。
1.3 Java 中的序列化
在 Java 中Java 中的序列化,序列化主要通过实现 Serializable 接口来完成。当一个类实现了 Serializable 接口后,它的对象就可以被序列化。
2. transient 是什么?
transient 关键字主要用于 Java 的二进制序列化过程中。当一个字段被标记为 transient 时,Java 的序列化机制不会将这个字段写入到序列化的字节流中。
这是因为 transient 字段的值不应该被持久化,或者是由于安全性、性能等原因而不应该在网络上传输。
- 不希望将某些敏感数据(如密码)持久化。
- 某些字段在序列化时是不必要的,例如缓存数据。
3. transient 关键字在JSON序列化的问题
尽管 transient 关键字在 Java 的二进制序列化中很有用,但在 JSON 序列化中却不起作用。常见的 JSON 序列化库(如 Jackson 和 Gson)并不会识别 transient 关键字。这意味着即使你将一个字段标记为 transient,它仍然会被序列化到 JSON 中。
4. 替代方案
为了在 JSON 序列化中排除某些字段,可以使用 JSON 序列化库提供的注解和方法。以下是常见的替代方案:既然是JSON不会识别transient 。那就用JSON能否识别的方式进行处理
4.1 使用 Jackson 的 @JsonIgnore
Jackson 提供了 @JsonIgnore 注解来控制哪些字段应该被序列化到 JSON 中。这是一个非常直观且易于理解的方法。
4.2 示例代码
假设你有一个 User 类,并且你不希望将 password 字段包含在 JSON 输出中。
import com.fasterxml.jackson.annotation.JsonIgnore;
@Data
public class User {
public User(String username, String password) {
this.username = username;
this.password = password;
}
private String username;
@JsonIgnore
private String password;
}
4.3 控制器类 UserController
假设你有一个控制器类 UserController,用于返回 User 对象。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
public class UserController {
@GetMapping("/user")
public R getUser() {
User user = new User("Alice", "secret");
return R.data(user);
}
}
4.4 输出结果
当你通过浏览器或工具访问 /user 接口时,返回的 JSON 将不再包含 password 字段。
{
"username": "Alice"
}
5. 总结
虽然 transient 可以帮助你控制 Java 的二进制序列化行为,但它并不是为 JSON 序列化设计的。如果你的目标是在 JSON 序列化过程中排除某些字段,建议使用 JSON 序列化库提供的机制,比如 Jackson 的 @JsonIgnore 或者类似的注解。这样做不仅更符合预期,而且代码的意图也更加清晰。