跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何使用 transient 关键字防止密码等敏感属性被持久化到磁盘或网络传输流中

transient仅对Java原生序列化有效,使字段不被ObjectOutputStream写入;反序列化后字符串为null、基本类型为默认值;需实现Serializable接口并建议显式定义serialVersionUID;对JSON等序列化无效,须配合@JsonIgnore等注解或DTO隔离敏感数据。 transient 关键字能跳过 Java 原生序列化过程,让密码等字段不写入磁盘文件或网络字节流,但仅限于
ObjectOutputStream
/
ObjectInputStream
场景。 它怎么起作用 只要字段被
transient
修饰,JVM 在调用
writeObject()
时就会自动忽略该字段——既不保存值,也不在反序列化时恢复。例如: 字符串类型(如
private transient String password;
)反序列化后为
null
基本类型(如
private transient int attempts;
)反序列化后为
0
或
false
它不加密、不删数据,只是“不拷贝”,内存里依然存在,日志、调试器、堆转储照常可见 必须配合 Serializable 接口使用 transient 单独声明无效,类必须实现
Serializable
,且通常建议显式定义
serialVersionUID
: 没写
serialVersionUID
时,JVM 会基于非-static、非-transient 字段自动生成;加了
transient
后,UID 值一般不变 但若后续增删了非-transient 字段,务必重新生成并更新
serialVersionUID
,否则跨版本反序列化可能失败 它防不住 JSON、HTTP 响应这些常见场景 Spring Boot 的
@ResponseBody
、Feign 调用、前端 AJAX 请求,底层多用 Jackson 序列化 JSON——而
transient
默认对 Jackson 完全无效: Jackson 需额外开启:
mapper.configure(MapperFeature.USE_TRANSIENT_ANNOTATION, true)
更推荐直接用注解:
@JsonIgnore
(Jackson)、
@JSONField(serialize = false)
(Fastjson)、
@Expose(serialize = false)
(Gson) 别指望一个
transient
同时管住二进制流和 JSON,这是两个独立机制 真正安全的做法不是只靠 transient 把敏感字段标为
transient
是基础动作,但生产环境还需叠加其他控制: 用 DTO 对象返回响应,比如
UserDTO
里根本不声明
password
字段 数据库查出的实体(含密码)绝不直接返回给前端,必须转换 密码字段在入库前应哈希加盐,内存中也不宜长期保留明文 若需自定义序列化逻辑(如只存密码摘要),可结合
transient
+
private void writeObject()
手动控制

相关文章