从play framework表单调用JPA实体中的getter方法会调用setter函数
我正在编写一个带有身份验证的简单play框架应用程序,其中密码使用BCrypt散列 简单地说,我的问题是:我观察到,在JPA实体中,当调用属性的get方法时,它的set方法也会被调用。如果我在set方法中执行非幂等运算,这就是一个问题 我将在这里描述我的问题的一个简化示例 这是我的登录视图从play framework表单调用JPA实体中的getter方法会调用setter函数,jpa,playframework-2.0,Jpa,Playframework 2.0,我正在编写一个带有身份验证的简单play框架应用程序,其中密码使用BCrypt散列 简单地说,我的问题是:我观察到,在JPA实体中,当调用属性的get方法时,它的set方法也会被调用。如果我在set方法中执行非幂等运算,这就是一个问题 我将在这里描述我的问题的一个简化示例 这是我的登录视图 @helper.form(routes.Application.authenticate) { <h3>Login</h3> <ul id
@helper.form(routes.Application.authenticate) {
<h3>Login</h3>
<ul id="login_box">
<li>
<span class="loginbox_label">Username : </span>
<input type="text" class="login_input" id="usernm-input" name="email" value='@form("email").value' placeholder="Enter Username..." />
</li>
<li>
<span class="loginbox_label">Password : </span>
<input type="password" class="login_input" id="passwd-input" name="password" placeholder="Enter Password..." />
</li>
<li>
@if(form.hasGlobalErrors) {
<p class="error">
@form.globalError.message
</p>
}
</li>
</ul>
<hr />
<a href="#" onclick="javascript:window.location.href = '@routes.Application.forgotpwd()?usr='+$('#usernm-input').val()" class="forgotpwdlink">Retrieve Forgotten Password</a>
<input type="submit" class="alt_btn login_btn" value="Login" />
<hr />
}
如您所见,我没有调用usr.setPassword方法。另外,我在else部分返回usr.getPassword(),以返回它并在页面上显示它,而不是错误消息
最后,这是我的用户类,一个JPA实体
@Transient
@Constraints.Required
@Formats.NonEmpty
private String password;
@Access(AccessType.PROPERTY)
@Column(name = "password")
public String getPassword(){
return this.password;
}
public void setPassword(String password){
this.password = password + "1";//BCrypt.hashpw(password, BCrypt.gensalt());
}
链接到完整的JPA实体:
我只是在这里添加了代码的相关部分。现在看看代码,您会发现每次提交表单时,它都必须返回存储的密码(因为我在else部分返回usr.getPassword()。注意this.password=password+1
现在,如果我继续提交错误的密码..这就是我得到的
很明显,每当我提交登录表单时,都会反复调用setPassword
为什么会这样
这是一篇很长的帖子,我知道您明确地为您的实体选择了属性访问。这意味着将调用setter来填充实体。但你的二传手并不是真正的二传手。因此,请将此方法重命名为其他方法,并添加一个真正的setter,或者使用字段访问而不是属性访问
@helper.form(routes.Application.authenticate) {
<h3>Login</h3>
<ul id="login_box">
<li>
<span class="loginbox_label">Username : </span>
<input type="text" class="login_input" id="usernm-input" name="email" value='@form("email").value' placeholder="Enter Username..." />
</li>
<li>
<span class="loginbox_label">Password : </span>
<input type="password" class="login_input" id="passwd-input" name="password" placeholder="Enter Password..." />
</li>
<li>
@if(form.hasGlobalErrors) {
<p class="error">
@form.globalError.message
</p>
}
</li>
</ul>
<hr />
<a href="#" onclick="javascript:window.location.href = '@routes.Application.forgotpwd()?usr='+$('#usernm-input').val()" class="forgotpwdlink">Retrieve Forgotten Password</a>
<input type="submit" class="alt_btn login_btn" value="Login" />
<hr />
}
IMHO,散列密码不应该由实体完成,更不应该由setter完成。预期的行为是getter应该返回setter设置的值。屏幕截图中的“qwe123”是实际密码,但在每次调用身份验证时,都会通过缓慢更改数据库本身中的密码来调用该集..:(谢谢。我想我必须在业务逻辑层面上对此进行分析。
@Transient
@Constraints.Required
@Formats.NonEmpty
private String password;
@Access(AccessType.PROPERTY)
@Column(name = "password")
public String getPassword(){
return this.password;
}
public void setPassword(String password){
this.password = password + "1";//BCrypt.hashpw(password, BCrypt.gensalt());
}