OGNL表达式与Struts框架结合参数接收(配置文件中配置传递参数)

一、属性驱动接收参数

1.1 ParamsDemoAction 接收类

import com.opensymphony.xwork2.ActionSupport;
public class ParamsDemoAction extends ActionSupport {
    //与页面中提交的名称对应
    private String name;
    @Override
    public String execute() throws Exception {
        System.out.println(name);
        return SUCCESS;
    }

    public String getName() {
        return name;
    }

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

1.2 struts.xml 配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <package name="params" namespace="/" extends="struts-default">
        <action name="paramsAction" class="com.qwm.struts2_3.c_params.ParamsDemoAction">
            <result name="success">/form1.jsp</result>
        </action>
    </package>
</struts>

1.3 form1.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>参数接收测试</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/paramsAction" method="post">
    用户名:<input type="text" name="name"/><br>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

1.4 图示

image

1.5 原理分析

image

  1. 我们表单中提交的数据通过 “name=tom” 的方式提交到后台

  2. 后台接收到一个请求以后,首先会到达struts2的核心过滤器

  3. 在核心过滤器执行的过程中,会调用到多个拦截器,其中就会调用到一个叫做 params 的拦截器。

  4. struts2就会把它交给OGNL来处理

  5. 我们的值栈中,Root中默认存放的就是请求的Action。所以交给OGNL处理,从Root中取到name属性并且赋值为tom,其实就是给我们的请求的action的name属性赋值,这样我们请求的action的name就有值了。


二、对象驱动接收参数

2.1 创建User类

我们现在把我们的参数封装到我们的User类的实例中。所以我们现在先创建一个User类

public class User {
    private String user;

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "User{" +
                "user='" + user + '\'' +
                '}';
    }
}

2.2 ParamsDemoAction 接收类修改

public class ParamsDemoAction extends ActionSupport {
    private User user;
    @Override
    public String execute() throws Exception {
        System.out.println(user.getName());
        return SUCCESS;
    }

    public User getUser() {
        System.out.println("---getUser---"+user);
        return user;
    }

    public void setUser(User user) {
        System.out.println("---setUser------"+user);
        this.user = user;
    }
}

2.3 form1.jsp 修改

修改我们传值的name为“user.name”。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>参数接收测试</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/paramsAction" method="post">
    用户名:<input type="text" name="user.name"/><br>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

2.4 图示

image

2.5 原理分析

image

这里面的原理和上面是一样。只是在赋值的时候多了一点而已。赋值时从栈顶对象中获取user属性,再获取user的name属性,赋值为tom。

需要说明的是我们的 user 属性。struts会调用我们在 Action提供的 getUser() 方法,如果为空那么创建一个,然后调用 setUser() 传递到的 Action 中;如果不为空,那么就不会再调用setUser()了。


三、自己操作值栈,把对象押入栈来获取参数

3.1 如何获取值栈(ValueStack)

想要获取值栈我可以通过如下的代码获取

ValueStack valueStack = ActionContext.getContext().getValueStack();

通过上面的分析我们可以知道,struts2是通过OGNL取出栈中的属性来赋值的。那么如果我们想要自己来把我们需要被赋值的属性押入栈要如何操作呢??

3.2 自己把变量押入栈分析

我们都知道,我们的Struts2会调用多个拦截器,比如赋值使用的 params。想要我们传递的变量能够被赋值,那么就比如在 params拦截器调用之前把变量押入栈中。查看调用的拦截器栈如下 
struts2-core-2.5.13.jar!\struts-default.xml

<interceptor-stack name="defaultStack">
    <interceptor-ref name="exception"/>
    <interceptor-ref name="alias"/>
    <interceptor-ref name="servletConfig"/>
    <interceptor-ref name="i18n"/>
    <interceptor-ref name="prepare"/>
    <interceptor-ref name="chain"/>
    <interceptor-ref name="scopedModelDriven"/>
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="fileUpload"/>
    <interceptor-ref name="checkbox"/>
    <interceptor-ref name="datetime"/>
    <interceptor-ref name="multiselect"/>
    <interceptor-ref name="staticParams"/>
    <interceptor-ref name="actionMappingParams"/>
    <interceptor-ref name="params"/>
    <interceptor-ref name="conversionError"/>
    <interceptor-ref name="validation">
        <param name="excludeMethods">input,back,cancel,browse</param>
    </interceptor-ref>
    <interceptor-ref name="workflow">
        <param name="excludeMethods">input,back,cancel,browse</param>
    </interceptor-ref>
    <interceptor-ref name="debugging"/>
</interceptor-stack>

这里面有一个 prepare 的拦截器,它就是可以满足我们的需求的,它也是在params之前调用的。查找 prepare 对应的类

<interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>

通过上面,我们找到了我们需要查看的类 PrepareInterceptor,进入看一下

public class PrepareInterceptor extends MethodFilterInterceptor {
    ......
    @Override
    public String doIntercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();

        if (action instanceof Preparable) {

            .........

            if (alwaysInvokePrepare) {
                ((Preparable) action).prepare();
            }
        }

        return invocation.invoke();
    }
    ......
}

它里面干的事情就是,获取到请求的Action,判断Action是否实现了 Preparable接口,如果是,那么调用 prepare() 方法。到此我们的解决方法就有了,我们只需要让我们的 Action 实现 Preparable接口,在prepare()中把变量押入栈就行了。这样我们可以明白了,为什么我们的变量必须实例化(不实例化我们传入栈的变量就是null,这样赋值绝对会空指针异常的)。

3.3 ParamsDemo2Action

public class ParamsDemo2Action extends ActionSupport implements Preparable {
    //必须实例化
    private User user = new User();
    @Override
    public String execute() throws Exception {
        System.out.println(user.getName());
        return SUCCESS;
    }

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

3.4 struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <package name="params" namespace="/" extends="struts-default">
        <action name="paramsAction" class="com.qwm.struts2_3.c_params.ParamsDemoAction">
            <result name="success">/form1.jsp</result>
        </action>
        <action name="params2Action" class="com.qwm.struts2_3.c_params.ParamsDemo2Action">
            <result name="success">/form2.jsp</result>
        </action>
    </package>
</struts>

3.5 form2.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>自己押入栈接收参数测试</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/params2Action" method="post">
    用户名:<input type="text" name="name"/><br>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

3.6 图示

image


四、模型驱动接收参数

4.1 说明

我们这里原理和方式其实和  是一样,这是这种方式,我们不用自己压栈而已。

这里我们来看的是 modelDriven 拦截器

<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>

查看 ModelDrivenInterceptor

public class ModelDrivenInterceptor extends AbstractInterceptor {
    ........
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();
        //判断Action是否是ModelDriven接口的实现类
        if (action instanceof ModelDriven) {
            //装换为ModelDriven接口
            ModelDriven modelDriven = (ModelDriven) action;
            //获取值栈
            ValueStack stack = invocation.getStack();
            //调用接口的getModel()方法,得到需要押入栈的
            Object model = modelDriven.getModel();
            if (model !=  null) {
                //如果获取到的对象不为空,就押入栈
                stack.push(model);
            }
            if (refreshModelBeforeResult) {
                invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
            }
        }
        return invocation.invoke();
    }
    ........
}

这个和我们上面说的是一个原理,这里它判断Action是不是实现了ModelDriven接口,如果是的话,调用getModel(),获取需要押入栈的对象,如果对象不为空,那么押入栈。所以说我们需要实现功能,只需要实现ModelDriven接口,然后在getModel()中放回我们需要押入栈的对象。

4.2 ParamsDemo3Action

public class ParamsDemo3Action extends ActionSupport implements ModelDriven<User> {
    //必须实例化
    private User user = new User();
    @Override
    public String execute() throws Exception {
        System.out.println(user.getName());
        return SUCCESS;
    }

    @Override
    public User getModel() {
        return user;
    }
}

4.3 struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <package name="params" namespace="/" extends="struts-default">
        <action name="paramsAction" class="com.qwm.struts2_3.c_params.ParamsDemoAction">
            <result name="success">/form1.jsp</result>
        </action>
        <action name="params2Action" class="com.qwm.struts2_3.c_params.ParamsDemo2Action">
            <result name="success">/form2.jsp</result>
        </action>
        <action name="params3Action" class="com.qwm.struts2_3.c_params.ParamsDemo3Action">
            <result name="success">/form3.jsp</result>
        </action>
    </package>
</struts>

4.4 form.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>模型接收参数测试</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/params3Action" method="post">
    用户名:<input type="text" name="name"/><br>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

4.5 图示

image

4.6 原理分析

image



五、配置文件中配置传递参数

我们除了页面中可以传递参数以外,也可以在配置文件中给action传递参数。使用 ,只要不是标签中的属性,就会被当做参数传递了。

5.1 ParamsDemo4Action

public class ParamsDemo4Action extends ActionSupport{
    @Override
    public String execute() throws Exception {
        ActionContext.getContext().put("name","qiwenming");
        return SUCCESS;
    }
}

5.2 ParamsDemo5Action

public class ParamsDemo5Action extends ActionSupport{
    private String name;
    private Integer age;
    @Override
    public String execute() throws Exception {
        System.out.println("name:"+name);
        System.out.println("age:"+age);
        return SUCCESS;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

5.3 struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <package name="params" namespace="/" extends="struts-default">
        <action name="paramsAction" class="com.qwm.struts2_3.c_params.ParamsDemoAction">
            <result name="success">/form1.jsp</result>
        </action>
        <action name="params2Action" class="com.qwm.struts2_3.c_params.ParamsDemo2Action">
            <result name="success">/form2.jsp</result>
        </action>
        <action name="params3Action" class="com.qwm.struts2_3.c_params.ParamsDemo3Action">
            <result name="success">/form3.jsp</result>
        </action>

        <action name="params4Action" class="com.qwm.struts2_3.c_params.ParamsDemo4Action">
            <result name="success" type="redirectAction">
                <param name="actionName">params5Action</param>
                <param name="namespace">/</param>
                <!-- 如果添加的参数struts"看不懂".就会作为参数附加重定向的路径之后.
                    如果参数是动态的.可以使用${}包裹ognl表达式.动态取值
                 -->
                <param name="name">${name}</param>
                <param name="age">19</param>
            </result>
        </action>

        <action name="params5Action" class="com.qwm.struts2_3.c_params.ParamsDemo5Action">
            <result name="success">/showparams.jsp</result>
        </action>
    </package>
</struts>

5.4 showparams.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>显示参数</title>
</head>
<body>
<h2>
    name:${name}<br>
    age:${age}
</h2>
</body>
</html>

5.5 图示

image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值