@Transient 注解、@org.springframework.data.annotation.Transient 注解、transient 关键字和密码存储

Posted

技术标签:

【中文标题】@Transient 注解、@org.springframework.data.annotation.Transient 注解、transient 关键字和密码存储【英文标题】:@Transient annotation, @org.springframework.data.annotation.Transient annotation, transient keyword and password storing 【发布时间】:2017-08-02 17:19:51 【问题描述】:

目前我正在学习 Spring 框架,主要关注它的安全模块。我看过一些与注册和登录有关的指南。我在 User 类的密码字段中看到了 transient 关键字或 @Transient 注释的常见用法。

我的虚拟应用正在使用 Spring Boot + Spring MVC + Spring Security + mysql

我知道

Java 的 transient 关键字用于表示字段不被序列化。

JPA 的 @Transient 注解...

...指定属性或字段不是持久的。它用于注释实体类、映射超类或可嵌入类的属性或字段。

还有 org.springframework.data.annotation 的 @Transient 注释...

将字段标记为映射框架的瞬态。因此,属性不会被持久化,也不会被映射框架进一步检查。

在我的 MySQL 数据库中,我的 spring_demo 模式有 3 个表:

+-----------------------+
| Tables_in_spring_demo |
+-----------------------+
| role                  |
| user                  |
| user_role             |
+-----------------------+

当我在 User 类的密码字段上使用 transient 关键字时,它不会存储在 MySQL 数据库中。 (例如:test01)

mysql> select * from user;
+----+--------+------------------+----------+
| id | active | email            | username |
+----+--------+------------------+----------+
|  1 |      1 | test01@gmail.com | test01   |
+----+--------+------------------+----------+
1 row in set (0,00 sec)

当我在 User 类的密码字段上使用 javax.persistence @Transient 注释时,它也不会存储在 MySQL 数据库中。 (例如:test02)

但是...当我在 User 类的密码字段上使用 org.springframework.data.annotation @Transient 注释时,它确实存储在 MySQL 数据库中。 (例如:test03)这是为什么?

mysql> select * from user;
+----+--------+------------------+----------+--------------------------------------------------------------+
| id | active | email            | username | password                                                     |
+----+--------+------------------+----------+--------------------------------------------------------------+
|  1 |      1 | test02@gmail.com | test02   |                                                              |
|  2 |      1 | test03@gmail.com | test03   | $2a$10$UbvmdhfcKxSNr/I4CjOLtOkKGX/j4/xQfFrv3FizxwEVk6D9sAoO  |
+----+--------+------------------+----------+--------------------------------------------------------------+
2 rows in set (0,00 sec)

我的主要问题是,当我使用基于 spring.data 的 @Transient 注释时,密码字段一直存在。为什么?我为什么要在密码字段上使用任何 @Transient 注释?

提前感谢您的指导和帮助!

【问题讨论】:

【参考方案1】:

在 Spring Framework 中,您可以使用 Mapping Framework 从一种形式转换为另一种形式。例如,您的 Spring Java 服务器端应用程序需要以 JSON 格式将用户信息发送给客户端(网页、移动应用程序)。

@Entity
public class User 

@Id
private long id;

@Column(name = "username")
private String username;

@Column(name = "email")
private String email;

@Column(name = "password")
private String password;


现在要将这个 java 实体对象映射到 JSON 格式,您可以使用映射框架(例如 jackson:com.fasterxml.jackson.databind.ObjectMapper)或手动进行。

将用户 2 对象转换为 JSON 时会得到的 JSON 格式输出是:


   "id": 2,
   "email": "test03@gmail.com",
   "username": "test03",
   "password": "$2a$10$UbvmdhfcKxSNr/I4CjOLtOkKGX/j4/xQfFrv3FizxwEVk6D9sAoO"

现在如果你添加了:

@org.springframework.data.annotation.Transient
@Column(name = "password")
private String password;

然后使用 Mapping Framwwork 再次为您将获得的用户 2 实体生成 JSON:


   "id": 2,
   "email": "test03@gmail.com",
   "username": "test03",

请注意,您的 JSON 输出中缺少密码字段。那是因为@org.springframework.data.annotation.Transient 明确向 spring 框架声明,您使用的 Object Mapper 在从 Java Object 转换为 JSON 时不应包含此值。

另请注意,如果您尝试将上述实体持久保存到数据库中,它仍会将其保存到数据库中,因为@org.springframework.data.annotation.Transient 仅适用于对象映射框架而不适用于 JPA。

回顾一下:

transient 用于所有序列化(通过网络、保存到磁盘、保存到 db)javax.persistence.Transient 专门用于 JPA DB 序列化 @org.springframework.data.annotation.Transient 用于 Spring 中使用的 ObjectMapping Framework 序列化

【讨论】:

如果目的不是保存时忽略该字段,可以使用@Transient private transient String password; 我现在正在学习 Spring 和 Spring Security,这是一个在细节和清晰度方面非常有用的答案。试图弄清楚为什么我的密码字段没有保留到数据库中的原因有点疯狂。谢谢!

以上是关于@Transient 注解、@org.springframework.data.annotation.Transient 注解、transient 关键字和密码存储的主要内容,如果未能解决你的问题,请参考以下文章

@Transient 注解对方法意味着啥?

@Transient 注解和瞬态修饰符有啥区别

Hibernate JPA中@Transient@JsonIgnoreProperties@JsonIgnore@JsonFormat@JsonSerialize等注解解释

spring_02注解 和插件配置以及与juint整合

Spring Data JPA 常用注解 @Query@NamedQuery

@Transient