Struts2与OGNL的联系

1、Struts与OGNL的结合原理

(1)值栈:

Struts2与OGNL的联系_第1张图片

 

 

 OGNL表达式要想运行就要准备一个OGNLContext对象,Struts2内部含有一个OGNLContext对象,名字叫做值栈。

 值栈也由两部分组成,一部分叫做root,里面放置的是栈,另一部分是context放入的是数据中心。

(2)栈:

Struts2与OGNL的联系_第2张图片

 

 

 利用了栈先进先出的特点,每次放入元素的时候是放入到索引为零的位置,取出的时候也是取出索引为零的元素,即:从下图的最上方元素取,符合栈的先进先出的特性。

Struts2与OGNL的联系_第3张图片

 

 

 

2、标签(查看值栈中的内容)

(1)root(栈)

Struts2与OGNL的联系_第4张图片

 

 

 默认情况下栈中存放当前访问的Action。

(2)context:

存放以下这些东西:

Struts2与OGNL的联系_第5张图片

 即:

Struts2与OGNL的联系_第6张图片

 

 3、Struts2与OGNL结合的体现

(1)Action以属性名的方式获取数据解析:

直接输出属性名,保持和表单的name属性的值相同。

 Struts2与OGNL的联系_第7张图片

 表单将数据提交给拦截器,拦截器获取到“name=zhai”后,交给OGNL处理,OGNL从root中拿到name属性并赋值为“zhai”,由此,Action获取到了表单提交的数据。

(2)对象方式:

表单:

 获取:

Struts2与OGNL的联系_第8张图片

  OGNL从栈顶获得user对象后,获得其name属性并将其值设置为“zhai”,由此,Action获取到了表单提交的数据。

(3)模型驱动

Struts2与OGNL的联系_第9张图片

 OGNL获取到name=zhai后,在值栈的root中,将user压入栈顶,并给user中的name赋值,也就是说从栈顶取元素并赋值。

 原理演示:

创建一个Action:

public class ActionStack extends ActionSupport implements Preparable {
    User user=new User();
    public String execute(){
        System.out.println(user);
        return "success";
    }

    @Override
    public void prepare() throws Exception {
        ValueStack valueStack=ActionContext.getContext().getValueStack();
        valueStack.push(user);
    }
}

实现Preparable接口的原因:

要在赋值前将user压入栈顶 ,而将获取栈的代码和将user对象压入栈顶的代码写入到prepare()函数中的目的正是获取栈并在赋值前将user对象压入栈顶。

源码分析:

 
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                    input,back,cancel,browse
                
                
                    input,back,cancel,browse
                
                
                
            

在众多的拦截器中,params拦截器位置相对靠后,因此需要将params拦截器放到prepare拦截器的位置,以实现赋值前将user压入栈顶。

那么如何操作呢?打开prepare拦截器的源码可知要调用prepare拦截器需要实现Preparable接口并调用 prepare()方法。

配置Struts的配置文件、创建表单、User类后将表单数据提交给Action:


            
用户名:
public class ActionStack extends ActionSupport implements Preparable {
    User user=new User();
    public String execute(){
        System.out.println(user);
        return "success";
    }

    @Override
    public void prepare() throws Exception {
        ValueStack valueStack=ActionContext.getContext().getValueStack();
        valueStack.push(user);
    }
}

 

 4、在struts.xml配置文件中的使用

(1)创建两个Action:

Action1:

public class Action1 extends ActionSupport {
    private String name;

    public String execute(){
        name="zhang";
        return "success";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Action2:

public class Action2 extends ActionSupport {
    public String execute(){
        return "success";
    }
}

(2)配置Struts.xml配置文件,使得访问Action1的时候能够重定向到Action2,:


    <package name="action" namespace="/a" extends="struts-default">
        class="pers.zhb.hello.Action2" method="execute">
            hello.jsp
        
        class="pers.zhb.hello.Action1" method="execute">
            
                Action2
                /a
                ${name}
            
        
    package>

(3)访问Action1:

 

 

 

 也就是说在配置struts.xml配置文件的时候,在标签内部将name属性的值设置为属性不能识别的值,就可以在重定向的时候将参数加到另外一个Action。

你可能感兴趣的:(Struts2与OGNL的联系)