struts2重点——ModelDriven

一、属性驱动

在目标 Action 类中,通过 setXxx() 方法来接收请求参数。

二、模型驱动

1.ParametersInterceptor 拦截器工作原理

ParametersInterceptor 会将请求参数赋值给值栈中栈顶的对象。默认情况下,栈顶对象是目标 Action 类。

2.modelDriven 拦截器工作原理

获取目标 Action 对象,判断是否实现了 ModelDriven 接口,若实现,则调用目标 Action 的 getModel(),将该方法返回的对象压入栈顶。

3.PrepareInterceptor 拦截器工作原理

首先获取目标Action方法的名字,首字母大写后加上prepare或prepareDo前缀,看有没有这个前缀方法,如果有则执行。

4.Struts2 通过 ParametersInterceptor.doIntercept(ActionInvocation) 方法调用 Action 类的 setXxx() 方法向目标 Action 类注入对应的属性。

5.拦截器栈

说明:

拦截器:Struts 定义了很多拦截器,每个拦截器有各自的作用。可以在 struts-default.xml 文件中看到定义的这些拦截器。

拦截器栈:Struts2 将若干拦截器进行了不同的组合排序,使这些拦截器进行协同工作,这就是拦截器栈(interceptor-stack)。

Struts2在 struts-default.xml 文件中定义了很多拦截器栈。

如:basicStack,validationWorkflowStack,fileUploadStack,modelDrivenStack,chainStack,i18nStack,paramsPrepareParamsStackdefaultStack,completeStack,executeAndWaitStack

默认拦截器栈为:<default-interceptor-ref name="defaultStack"/>

6.拦截器栈的调用者

defaultStack 拦截器栈中引用了 18 个拦截器。由 StrutsActionProxy 进行了调用,实际是由 DefaultActionInvocation 进行的调用。

说明:

DefaultActionInvocation 对象在初始化的时候就加载了当前拦截器栈中的所有拦截器 List ,然后在调用 invoke() 方法时,遍历了这个 List,然后依次调用每个拦截器的 interceptor() 方法,

调用完所有拦截器方法,然后再去调用目标方法。这就是 Struts 工作的流程。

7.使用 defaultStack 拦截器栈的缺点

在 defaultStack 拦截器栈中定义了 拦截器的执行顺序。modelDriven 拦截器先于  params 拦截器执行。

进行修改操作时,需要先传一个 id 过来,然后根据 id 去数据库中查找,将该对象作为 ModelDriven 的 getModel() 返回,进行表单回显。但显然 defaultStack 不能完成。

8.paramsPrepareParamsStack 拦截器栈

在 paramsPrepareParamsStack 栈中,params prepare modelDriven params 这样的执行顺序,能满足需求。

这样在修改是时候就能先注入 id 了。然后根据 id 去数据库中查找,并将该对象作为 ModelDriven 的 getModel() 返回。

但是还有问题是,在删除的时候,不需要去调用 getModel() 方法。

这时候就需要用到 prepare 拦截器,

为每一个有需要的Action方法量身打造自己专属的 prepareXxx() 方法,在这个方法中为 getModel() 方法准备模型。

还有一个问题,每一次请求都会调用 prepare() 这个空方法。我们可以通过配置让他不执行这个方法。

<interceptors>
    <interceptor-stack name="myStack">
        <interceptor-ref name="paramsPrepareParamsStack">
            <param name="prepare.alwaysInvokePrepare">false</param>
        </interceptor-ref>
     </interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"/>

9.最终的一个例子:

public class BookAction extends ActionSupport implements RequestAware,ModelDriven<Book>,Preparable {
    private static final long serialVersionUID = 1L;

    private Dao dao = new Dao();
    private Map<String, Object> requestMap;

    private Book book;

    private Integer bookId;

    public void setBookId(Integer bookId) {
        this.bookId = bookId;
    }

    @Override
    public Book getModel() {
        return this.book;
    }

    @Override
    public void prepare() throws Exception {
    }

    public void prepareUpdate() {
        this.book = dao.getBook(bookId);
    }

    public String update() {
        dao.updateBook(book);
        return "update-success";
    }

    public void prepareEditUI() {
        this.book = dao.getBook(bookId);
    }
    
    public String editUI() {
        return "editUI";
    }
    
    public String remove() throws Exception {
        dao.removeBook(bookId);
        return "remove-success";
    }

    public void prepareSave() {
        this.book = new Book();
    }

    public String save() {
        dao.saveBook(book);
        return "save-success";
    }

    public String showList() throws Exception {
        requestMap.put("bookList", dao.getBookList());
        return "showList";
    }

    @Override
    public void setRequest(Map<String, Object> request) {
        this.requestMap = request;
    }

}
BookAction
原文地址:https://www.cnblogs.com/solverpeng/p/5653721.html