背景:我用 ModelDriven 编写了一个 struts2 ActionSupport 类。这是一个休眠/弹簧网络应用程序,使用 OSIV 和视图中的附加实体 (JSP)。
我今天从架构师那里收到了这封电子邮件,因为我通过接口将一个引用了附加实体的对象放在了 struts2 值堆栈上
ModelDriven<E>
。他是对的还是什么?显然,这是我正在做的一件严肃的事情,但我并没有听从他的话,而且我真的不想接受他的提议并在那之后去他的办公桌前拜访他。好家伙。是时候换职业了。
---来自建筑师---
比利,正如我们之前所讨论的,你仍然在你的代码中一遍又一遍地犯同样的错误。这是您第四次犯此错误,我担心您的工作质量。做一次甚至两次是一回事,但第四次之后,我想知道你是否无法理解我在说什么。下面将为您一一解读。如果您在阅读此电子邮件后没有收到它,请到我的办公桌前,我们会仔细阅读。这必须立即停止,我希望在一天结束之前重构您的所有代码以纠正这个错误。如果任何这样的代码渗入生产环境,我们将面临严重的安全问题。另请注意,我在这方面抄袭戴夫,以便发出适当的谴责。我还将向 Dave 推荐您从 III 级开发人员转到 II 级开发人员。请阅读以下内容并学习它,并按照我的指示重构您的所有代码。
关于绑定对象:
当一个 Struts2 动作类被标记为 ModelDriven 接口时,模型将被绑定到 HTML 页面中的表单元素。例如,如果一个 HTML 表单有一个名为 userName 的字段并且一个动作类被定义为:
公共类 UserAction 扩展 ActionSupport 实现 ModelDriven
而 UserModel 是一个 POJO,如下所示:
public class UserModel {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
提交表单时,只要 Action 包含 UserModel 的实例,struts2 就会将字段 userName 绑定到 UserModel.userName,自动填充值。
然而,这种简单性对于恶意用户来说代价高昂。如果一个对象被声明为 ModelDriven,最终用户,即浏览用户,可以通过模型设置器访问模型图。以这个案例为例:
公共类 UserAction 扩展 ActionSupport 实现 ModelDriven
和...
public class UserModel {
private String userName;
private UserEntity userEntity;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
pubic UserEntity getUserEntity() {
return userEntity;
}
}
和...
@Entity
public class UserEntity {
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
假设正在使用 OSIV 模式,并且附加了实体 UserEntity。
有一点先见之明或手头有时间的狡猾用户可能会:
/myform?userName=billy&userEntity.password=newpassword
假设实体在会话结束时保存,上述结果会更改比利的密码。
关键是,对象图是可用的!
使用 ModelDriven 时,使用替代方法是一种可怕的方法,您必须定义放置在 valuestack 上的细粒度模型,然后在发送响应并允许事务提交之前从模型复制到目标对象。