Struts2中的paramsPrepareParamsStack拦截器中,第一个params拦截器自动将request的parameter值注入到Action的instance变量以及其关联对象中,然后我们可以在Action中的prepare方法中根据id从数据库将PO实体装载进来,后一个params拦截器中再将新值赋给这些PO对象,这样就保证了数据库原有的一些属性值不会丢失。
这一功能很好很强大,但在与OpenSessionInView结合时,会有一个小陷阱需要防范。
举一个典型的应用场景:
一个Group对象,有id,name等属性
一个User对象,与Group是多对一的关系,User有id,name和group等属性
在修改后保存User时,form表单的input如下:
<input type="text" name="user.id" .../>
<input type="text" name="user.name" .../>
<select name="user.group.id">
<option value=1>group1</option>
<option value=2>group2</option>
</select>
Action的prepare方法如下:
public void prepare() throws Exception {
if (user != null && user.getId() != null) {
user = userManager.get(user.getId());
}
}
某一User的group原来为group1,修改为group2后,点保存,Action执行了updateUser()方法,Hibernate会报错:
org.springframework.orm.hibernate3.HibernateSystemException: identifier of an instance of com.xxx.model.Group was altered from 1 to 2; nested exception is org.hibernate.HibernateException: identifier of an instance of com.xxx.model.Group was altered from 1 to 2
原来,prepare方法调用后,user对象被重置为hibernate生成的po,user.getGroup()的group对象处于persistent状态,它的id来自于数据库,为1。第二个param拦截器执行了user.getGroup.setId(2)操作,所以抛出了上述异常。
解决办法是,在prepareUpdateUser()方法中执行:
public void prepareUpdateUser() throws Exception {
if (user != null && user.getId() != null) {
long newGroupId = user.getGroup().getId();
user = userManager.get(user.getId());
if (newGroupId != user.getGroup().getId()) {
Group newGroup = new Group();
newGroup.setId(newGroupId);
user.setGroup(newGroup);
}
}
}
这样在group修改后手动将与user关联的处于persistent状态的group断开联系。
更简单的方式是直接
public void prepareUpdateUser() throws Exception {
if (client != null && client.getId() != null) {
client = clientManager.get(client.getId());
client.setGroup(null);
}
}
因为第二个param拦截器还会正确地把不管是新的还是老的group id注入进来。
注:该方式只适用于user不对group进行级联更新的情况
分享到:
相关推荐
在SSH2框架中,模型驱动与拦截器注入是两个重要的概念和技术。 ##### 1. 模型驱动 模型驱动是指在开发过程中,通过创建模型类来组织业务逻辑的一种方式。这种方式可以让代码更加清晰、易于维护。在Struts2中,如果...
这里`myStack`是一个拦截器栈,包含`paramsPrepareParamsStack`(Struts2默认的参数处理拦截器栈)和`myCustomInterceptor`(自定义拦截器)。 - **Action配置**:在Action的配置中,通过`<action>`标签的`...
`interceptor-stack`定义了一个拦截器栈,它包含了`login`拦截器和其他默认的拦截器`paramsPrepareParamsStack`。最后,`default-interceptor-ref`指定了应用中的默认拦截器栈,所有Action都会经过这个拦截器栈处理...
视频10、20和21深入讲解了Preparable拦截器、paramsPrepareParamsStack拦截器栈以及自定义拦截器的实现和应用,例如防止表单重复提交。 5. **类型转换**:Struts 2自动处理请求参数到Action属性的类型转换。视频11...
这是通过`paramsPrepareParamsStack`拦截器栈中的`ParamsInterceptor`实现的。 此外,Struts2还支持动态方法调用和类型转换。动态方法调用允许我们不指定具体的execute方法,而是根据请求参数自动调用Action中的...
对于安全性,应使用预定义的拦截器如`paramsPrepareParamsStack`来自动进行基本的数据类型转换和参数过滤,防止SQL注入等安全问题。同时,对于密码,应该在保存前进行加密处理。 通过这个项目,初学者可以了解...
`paramsPrepareParamsStack`是Struts2默认的拦截器栈,包含了参数处理和准备动作等步骤。通过`<param>`标签,我们可以自定义拦截器的行为,比如`prepare.alwaysInvokePrepare`被设置为`false`,意味着只有当Action类...
在Struts2配置文件(struts.xml)中,你需要启用文件上传拦截器(`paramsPrepareParamsStack`)。这个拦截器栈会处理上传请求,并将文件内容转换为Action类中的属性,以便后续处理。 单个文件上传通常涉及到一个...
在struts.xml或struts-default.xml配置文件中,需要添加拦截器链,其中包括`paramsPrepareParamsStack`,它包含了`i18n`拦截器,该拦截器负责从session中获取用户的locale并加载相应的资源文件。 6. **使用资源...
4. **Struts2拦截器**:Struts2的DefaultActionInvocation拦截器链中的`ParamsPrepareParamsStack`包含了一个`ParamsInterceptor`,它可以处理multipart请求并填充Action的属性。 5. **文件存储**:上传的文件需要...
默认情况下,Struts2的`default-stack`已经包含了`paramsPrepareParamsStack`,但是为了处理文件上传,需要添加`fileUpload`拦截器。在struts.xml中,你可以这样配置: ```xml ...
同时,为了实现Struts2与Hibernate的结合,可能需要配置拦截器,如`paramsPrepareParamsStack`,它可以帮助处理请求参数。 5. **编写DAO层**:Data Access Object层负责与数据库交互。这里可以创建接口和实现类,...
在Struts2中,可以使用拦截器(Interceptors)来增强安全性,例如使用`paramsPrepareParamsStack`预处理用户输入。 以上就是基于Struts2的登录系统的基本实现原理和关键点。通过这个项目,开发者可以学习到如何在...
Struts2提供了`params`拦截器,用于从请求中获取参数,`prepare`拦截器则负责在Action执行之前初始化Action的属性。在`struts.xml`配置文件中,可以这样配置: ```xml <interceptor-ref name="...
Struts2的核心配置文件,用于定义Action、拦截器、结果类型等。以下是`struts.xml`的部分内容: ```xml <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ...
同时,需要在Action配置中添加`<interceptor-ref name="paramsPrepareParamsStack"/>`拦截器。 #### 六、总结 通过以上介绍,我们可以看到Struts2提供的验证机制非常强大且灵活。通过合理的配置和使用,开发者可以...
Struts2是一个流行的Java web开发框架,用于构建MVC(模型-视图-控制器)架构的应用程序。在处理用户输入时,确保数据的有效性和正确性是至关重要的,这就是输入校验的作用。Struts2提供了内置的验证框架Struts2 ...
- 若使用`Preparable`接口,则必须在`action`配置中添加`<interceptor-ref name="paramsPrepareParamsStack"/>`,以确保`prepare()`方法能够获取到表单提交的参数。 **2. 创建XML内容** 验证文件的结构如下: ```...