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

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
//创建list
List list = (List) Ognl.getValue("{1,2,3,4}", context, root);
System.out.println(list);
//创建map
Map 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可以指定哪些方法需要拦截或哪些方法不需要拦截

结论

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

拦截器中的操作

放行

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

    //后处理
    System.out.println("MyInterceptor3后处理");
    return invoke;
}

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

//拦截处理
@Override
protected 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值