Struts2框架(二)参数封装、OGNL表达式、拦截器详解

来源:互联网 发布:淘宝刷单处罚规则 编辑:程序博客网 时间:2024/06/08 08:08

struts2框架(二)

struts2参数封装

属性驱动

属性驱动:只需要在Action中准备与条件的键相同的属性即可自动接收参数.struts2在接收参数时可以帮助我们完成自动类型转换,转换范围:8大基本数据类型及包装类和特定格式(yyyy-mm-dd)的Date.

Action对象生命周期:每次请求都会创建一个新的Action对象,请求处理完销毁

public class Demo1Action extends ActionSupport{    private String name;    private int age;    private Date hiredate;    public Date getHiredate() {        return hiredate;    }    public void setHiredate(Date hiredate) {        this.hiredate = hiredate;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String execute() throws Exception {        System.out.println(name+"=>"+age+"=>"+hiredate);        return SUCCESS;    }}

对象驱动

对象驱动:与属性驱动相似,主要区别在于表单提交参数键上,使用”对象属性名.属性”来提交参数,不常使用

public class Demo2Action extends ActionSupport{    private User user;    public User getUser() {        return user;    }    public void setUser(User user) {        this.user = user;    }    @Override    public String execute() throws Exception {        System.out.println(user);        return SUCCESS;    }}

jsp页面:

<form action="${pageContext.request.contextPath}/Demo2Action" method="post">    用户名:<input type="text" name="user.name"/><br>    年龄:<input type="text" name="user.age" /><br>    入职日期:<input type="text" name="user.hiredate"/> <br>    <input type="submit" value="提交"/></form>

模型驱动

模型驱动:让Action继承ModelDriven接口,在接口方法中返回封装参数的对象.

public class Demo3Action extends ActionSupport implements ModelDriven<User>{    private User user = new User();    @Override    public String execute() throws Exception {        System.out.println(user);        return SUCCESS;    }    @Override    public User getModel() {        return user;    }}

jsp页面:

<form action="${pageContext.request.contextPath}/Demo3Action" method="post">    用户名:<input type="text" name="name"/><br>    年龄:<input type="text" name="age" /><br>    入职日期:<input type="text" name="hiredate"/> <br>    <input type="submit" value="提交"/></form>

复杂参数封装

复杂参数封装:将参数提交到list或map中
1、在action中准备复杂类型的属性
2、表单提交格式

//准备List|Map属性,提供set/get方法public class Demo4Action extends ActionSupport {    private List list;    private Map<String, String> map;    public List getList() {        return list;    }    public void setList(List list) {        this.list = list;    }    public Map<String, String> getMap() {        return map;    }    public void setMap(Map<String, String> map) {        this.map = map;    }    @Override    public String execute() throws Exception {        System.out.println(list);        System.out.println(map);        return SUCCESS;    }}

jsp页面(表单提交格式):

<form action="${pageContext.request.contextPath}/Demo4Action" method="post">    list:<input type="text" name="list"/><br>    list:<input type="text" name="list"/><br>    list:<input type="text" name="list[5]"/><br>    map:<input type="text" name="map['name']"/><br>    map:<input type="text" name="map['age']"/><br>    <input type="submit" value="提交"/></form>     

OGNL表达式

OGNL:对象视图导航语言,第三方独立的语言,并不是由Struts2项目组开发,struts2只是整合该语言.
该语言类似于EL表单式语言,用于取值,OGNL要更加强大.

开发准备

导包

只需要导入struts2的包就相当于导入了OGNL的包

代码准备

  • 准备Root(Object)
  • 准备Context(Map)

    //准备Root对象
    User root = new User();
    root.setName(“tom”);
    root.setAge(22);
    //准备Context对象
    Map context = new HashMap();

    User user1 = new User();user1.setName("jack");user1.setAge(18);User user2 = new User();user2.setName("rose");user2.setAge(16);

    context.put(“user1”, user1);
    context.put(“user2”, user2);

语法

取值

  1. 参数1:填写表达式
  2. 参数2:填写Context部分
  3. 参数3:填写Root部分

    //取出Root中name属性值
    //参数1:填写表达式,参数2:填写Context部分,参数3:填写Root部分,取出Root中的name属性值
    System.out.println(Ognl.getValue(“name”, context, root));

    //取出Context中u1对应的name属性值
    System.out.println(Ognl.getValue(“#user1.name”, context, root));

赋值

//为Root中name属性赋值//参数1:填写表达式,参数2:填写Context部分,参数3:填写Root部分,Ognl.getValue("name='张三'", context, root);System.out.println(root.getName());//为Context中u1对应的name属性赋值Ognl.getValue("#user1.name ='李四'", context, root);System.out.println(user1.getName());

访问方法

//调用方法为Root中name属性赋值//参数1:填写表达式,参数2:填写Context部分,参数3:填写Root部分,Ognl.getValue("setName('James')", context, root);System.out.println(root.getName());//调用方法为Context中u1对应的name属性赋值Ognl.getValue("#user1.setName('Koby')", context, root);System.out.println(user1.getName());

访问静态方法

//调用静态方法System.out.println(Ognl.getValue("@cn.it.ognl.OGNLUtils@echo('hello')", context, root));//调用Math类中的静态方法,不需要书写完整类型System.out.println(Ognl.getValue("@@random()", context, root));//调用静态属性System.out.println(Ognl.getValue("@@PI", context, root));

创建List|Map

//创建listList list = (List) Ognl.getValue("{1,2,3,4}", context, root);System.out.println(list);//创建mapMap map = (Map) Ognl.getValue("#{'name':'james','age':'18'}", context, root);System.out.println(map);

OGNL表达式与Struts2整合

整合原理

栈结构

结论:Root在访问时,访问时优先访问栈顶对象.

valuestack中的内容

  • Root -> Value Stack Contents
  • Context -> Stack Context

OGNL表达式与struts2整合应用

表单参数封装

属性驱动

<form action="${pageContext.request.contextPath}/Demo1Action" method="post">    用户名:<input type="text" name="name"/><br>    年龄:<input type="text" name="age" /><br>    入职日期:<input type="text" name="hiredate"/> <br>    <input type="submit" value="提交"/></form>

对象驱动

<form action="${pageContext.request.contextPath}/Demo2Action" method="post">    用户名:<input type="text" name="user.name"/><br>    年龄:<input type="text" name="user.age" /><br>    入职日期:<input type="text" name="user.hiredate"/> <br>    <input type="submit" value="提交"/></form>

模型驱动

<form action="${pageContext.request.contextPath}/Demo3Action" method="post">    用户名:<input type="text" name="name"/><br>    年龄:<input type="text" name="age" /><br>    入职日期:<input type="text" name="hiredate"/> <br>    <input type="submit" value="提交"/></form>

配置文件中的应用

在struts2配置文件中使用ognl{name}:从顶端的Action中取得name属性.

<result name="success" type="redirectAction">    <param name="namespace">/</param>    <param name="actionName">/Demo5Action</param>    <!-- 在strust2配置文件中使用${ognl表达式}        ${name}:从root顶端的Action中获得name属性     -->    <param name="name">${name}</param></result>

页面struts标签

/** * OGNL页面取值 */public class Demo8Action extends ActionSupport {    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String execute() throws Exception {        //栈顶Action的name属性        name = "actionTest";        // request域        ActionContext.getContext().put("requestName", "requestTest");        // session域        ActionContext.getContext().getSession().put("sessionName", "sessionTest");        // application域        ActionContext.getContext().getApplication().put("applicationName", "applicationTest");        return SUCCESS;    }}

OGNL表达式取值

<h1>OGNL取值</h1>Action的name属性:<s:property value="name"/><br>ActionContext|requst的name属性:<s:property value="#requestName"/><br>session域的name属性:<s:property value="#session.sessionName"/><br>application域的name属性:<s:property value="#application.applicationName"/><br>

EL表达式取值

<h1>EL表单式取值</h1>Action的name属性:${name}<br>ActionContext|requst的name属性:${requestName}<br>session域的name属性:${sessionName}<br>application域的name属性:${applicationName}<br>

struts2重写了getAttribute()方法,可以从原生request域、ValueStack中的Root、ValueStack中的Context取值。

struts2处理异常机制

  1. 抛出异常
  2. struts.xml中配置异常映射





  3. 页面取出异常信息

${exception.message}

<td>    <font> ${exception.message}</font></td>

自定义拦截器

自定义拦截器方式

方式1:实现Interceptor接口

方式2:继承抽象类AbstractInterceptor

方式3:继承抽象类MethodFilterInterceptor

MethodFilterInterceptor可以指定哪些方法需要拦截或哪些方法不需要拦截

结论

推荐使用第三种,可以定制拦截的方法,也可以不定制,功能强大.

拦截器中的操作

放行

//放行@Overrideprotected String doIntercept(ActionInvocation invocation) throws Exception {    //业务代码    //前处理    System.out.println("MyInterceptor3前处理");    String invoke = invocation.invoke();    //后处理    System.out.println("MyInterceptor3后处理");    return invoke;}

拦截:就是不调用invoke方法,直接返回一个字符串跳转指定的页面.

//拦截处理@Overrideprotected String doIntercept(ActionInvocation invocation) throws Exception {    //业务代码    System.out.println("需要拦截");    //拦截操作不调用invoke方法,直接返回一个字符串跳转指定的页面    return "error";}

配置拦截器

  1. 注册拦截器
  2. 配置拦截器栈
  3. 指定默认拦截器栈
  4. 配置定义拦截方法

指定哪些方法不拦截或不拦截只能选一个配置
注意:受dtt约束,要按顺序配置拦截器

<interceptors>        <!-- 1.注册拦截器 -->        <interceptor name="myInter" class="cn.it.interceptor.MyInterceptor3"></interceptor>             <!-- 2.配置拦截器栈(21个) -->        <interceptor-stack name="myStack">            <!-- 为拦截器指定拦截的方法                 注意:指定哪些方法拦截或不拦截只能选一个配置            -->            <interceptor-ref name="myInter">                 <!-- 指定哪些方法不拦截 -->                 <param name="excludeMethods">execute</param>                 <!-- 指定只拦截哪些方法                  <param name="includeMethods">execute</param>-->            </interceptor-ref>            <!-- 引用默认栈(20个) -->            <interceptor-ref name="defaultStack"></interceptor-ref>        </interceptor-stack>    </interceptors>    <!-- 3.指定默认拦截器栈 -->    <default-interceptor-ref name="myStack"></default-interceptor-ref>

指定全局结果集

<!--全局结果配置 --><global-results>    <result name="toLogin" type="redirect" >/login.jsp</result></globalt-results>
0 0