首页 > 其他分享 >奇妙的paramsPrepareParamsStack——Struts2中ModelDriven问题

奇妙的paramsPrepareParamsStack——Struts2中ModelDriven问题

时间:2023-09-07 14:05:29浏览次数:39  
标签:model 拦截器 prepare id Struts2 user ModelDriven public paramsPrepareParamsStack


每次调用全文检索都要传入所有的参数值,不然导致当某个参数没有传值的时候但取到的却是上一次搜索提供的参数值。

最后才发现原来是Action类里implements ModelDriven实现的原因:

public class DocuIndexAction extends BaseAction implements ModelDriven{
DocSearchParam docSearchParam = new DocSearchParam(); //模型对象:搜索条件参数类
@Override
 public Object getModel() {
  return docSearchParam;
 }.......
}

这样在类里new的模型对象成员变量,在下一次再调用该类里的方法时,该对象并没有重新new,所以里面的值如果没有传就会保存上一次的值。

最后看到下面一篇文章《奇妙的paramsPrepareParamsStack》才明白代码修改为:

public class DocuIndexAction extends BaseAction implements ModelDriven,Preparable{
/**
  * 模型的对象
  */
 DocSearchParam docSearchParam;  
@Override
 public void prepare() throws Exception {
   docSearchParam = new DocSearchParam(); 
 } 
@Override
 public Object getModel() {
  return docSearchParam;
 }.......
}

再测试居然ok了。

 

paramsPrepareParamsStack在Struts 2.0中是一个很奇妙的interceptor stack,以至于很多人疑问为何不将其设置为默认的interceptor stack。paramsPrepareParamsStack主要解决了ModelDriven和Preparable的配合问题,从字面上理解来说,这个stack的拦截器调用的顺序为:首先params,然后prepare,接下来modelDriven,最后再params。Struts 2.0的设计上要求modelDriven在params之前调用,而业务中prepare要负责准备model,准备model又需要参数,这就需要在prepare之前运行params拦截器设置相关参数,这个也就是创建paramsPrepareParamsStack的原因。流程如下:
   1. params拦截器首先给action中的相关参数赋值,如id
   2. prepare拦截器执行prepare方法,prepare方法中会根据参数,如id,去调用业务逻辑,设置model对象
   3. modelDriven拦截器将model对象压入value stack,这里的model对象就是在prepare中创建的
   4. params拦截器再将参数赋值给model对象
   5. action的业务逻辑执行 依据此stack,一个action的代码通常如下:

public class UserAction extends ActionSupport implements ModelDriven, Preparable{
private User user;
private int id;
private UserService service; // user business service

public void setId(int id) {
   this.id = id;
}
/**
* create a new user if none exists, otherwise load the user with the specified id
*/
public void prepare() throws Exception {
   if( id==0 ) {
      user = new User();
   } else {
      user = service.findUserById(id);
   }
}
public Object getModel() {
return user;
}
/**
* create or update the user and then view the created user
*/
public String update() {
   if( id==0 ) {
     service.create(user);
   } else {
     service.update(user);
}
return "redirect";
}
/**
* delete the user and go to a default home page
*/
public String delete() {
service.deleteById(id);
return "home";
}
/**
* show the page allowing the user to view the existing data 
*/
public String view() {
   return "view";
}
/** 
* show the page allowing the user to view the existing data and change the values 
*/
public String edit() {
   return "input";
}
}


在上述代码中,edit和view都不需要根据id再为界面准备数据,因为prepare方法已经准备好了model,这些方法很简单。对于update方法,prepare首先会从数据库中加载数据,然后params拦截器会将参数值付给model,在update直接更新就可以,不会出现数据被乱更新的情况。象Hibernate框架,会判断哪些字段更新了,然后进行更新,性能也不会损失。
通过paramsPrepareParamsStack可以让流程更明确,代码更简洁,也更利于大家的交流。

以上代码参考自《Starting Struts 2》。


标签:model,拦截器,prepare,id,Struts2,user,ModelDriven,public,paramsPrepareParamsStack
From: https://blog.51cto.com/u_2544485/7396507

相关文章

  • Struts2-045 Remote Code Execution Vulnerablity(CVE-2017-5638)
    目录1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描nacs3、漏洞验证1.5、修复建议说明内容漏洞编号CVE-2017-5638漏洞名称S2-045远程代码执行漏洞漏洞评级高危影响范围Struts2.3.5-Struts2.3.31Struts2.5-Struts2.......
  • Struts2 v2.1.6 笔记
    1.启动<constantname="struts.devMode"value="true"/>或者<constantname="struts.configuration.xml.reload"value="true"/>时启动tomcat报错。org.apache.catalina.core.StandardContextfilterStart严重:Exceptionstarting......
  • [struts2]配置dispatcher INCLUDE和Forward可能问题解决
    Struts2.1.6GA不支持<dispatcher>FORWARD</dispatcher>和<dispatcher>INCLUDE</dispatcher>你要是和URLRewrite过滤器一起工作会报错。目前最新版本GeneralAvailability(GA)Releases-ReadyforPrimeTime!Struts2.1.8("bestavailable")Struts2.0.14(&qu......
  • Struts2与URL Rewrite整合注意的地方
    1.在重新定向的jsp界面中不要使用<s:include>标签,会发生空指针异常,你可以使用<jsp:include>去解决 2.web.xml中UrlRewrite过滤器要在struts2过滤器前面,在Struts2过滤器映射要这样写<filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern>......
  • 使用Struts2拦截器需要注意的地方
    今天在写拦截器的时候发现一个貌似属于bug的问题我使用的版本是2.1.8 当访问一个满足拦截器拦截条件的请求时,虽然代码已经执行进入拦截器,并且返回结果也是拦截后改变的跳转结果,但是却没有按照返回结果跳转,而是依旧进入了action。 源代码是这样的:publicStringintercept(ActionIn......
  • Struts2标签错误:using Struts tags without the associat解决
    <filter-mapping><filter-name>struts2</filter-name><url-pattern>*.jsp</url-pattern></filter-mapping> struts,在使用标签的时候,出现了这样一个问题。    原本使用标签,引用方法是默认配置:    web.xml:<filter><filter-name&......
  • struts2文件下载
    下载相对上传来说就要简单一点了,主要是使客户端获得服务器端的文件输入流,但是在配置Action时,还是有一些要注意的:1)result的type必须为stream类型 2)attachment表示不管什么类型的文件,都要弹出下载对话框,若不指定,则默认为内联形式,即inline,即浏览器能打开的就直接打开,不能打开的就提......
  • Struts2 中拦截器和Action的调用关系
    所谓的拦截器就是指实现了Interceptor接口的类,该接口中定义了三个方法:init(),destroy(),intercept()。init()用于在服务器启动的时候,初始化这个拦截器。destroy()用于清理分配给拦截器的资源,intercept()是用来起拦截作用的,这个方法还有一个ActionInvocation类型的参数invocation,并且......
  • struts2中的参数传递
    这个问题其实一直很困惑我的,在写平常的jsp程序时,传递参数很容易,通过表单,request,链接等都可以传递,但是到了struts2中,在写的各个地方,都看不到任何的request或是response,不知道该怎么传递参数了,到了今天学习了struts2中的参数传递这一节,终于解开了疑惑,但是还不是很清楚,有待以后探索。......
  • Struts2中防止表单重复提交的两种方式
    防止表单重复提交,这是个很重要的知识点,而且很有用。当用户提交了一个表单,此时,地址栏显示的是处理这个表单的Action的地址,若此时刷新,则会重新发送一次表单数据,即又进行了一次提交,若这个Action是用来处理用户注册的,那么重复提交会再一次向数据库中插入之前已经插入的数据,这显然不是我......