struts2框架(四)拦截器,国际化,Ognl表达式

Intercetor, 即为拦截器。
1) 在Struts2中,把每一个功能都用一个个的拦截器实现;用户想用struts的哪个功能的时候,可以自由组装使用。
2)Struts2中,为了方法用户对拦截器的引用,提供了拦截器栈的定义,里面可以包含多个拦截器。 文件夹(文件, 文件2) 拦截器栈(拦截器,拦截器2)
3)Struts2中,如果用户没有指定执行哪些拦截器,struts2有一个默认执行的栈,defaultStack;
一旦如果用户有指定执行哪些拦截器,默认的拦截器栈就不会被执行
拦截器的设计,就是基于组件设计的应用!

1.自定义拦截器

struts2框架(四)拦截器,国际化,Ognl表达式_第1张图片

1.1 编写辅助测试用action

public class HelloAction extends ActionSupport{
    public HelloAction() {
        System.out.println("1. Action实例创建了");
    }
    
    @Override
    public String execute() throws Exception {
        System.out.println("3. 执行了请求处理的方法: execute");
        return super.execute();
    }
}

1.2 编写拦截器类

public class HelloInterceptor implements Interceptor{
    
    // 启动时候执行
    public HelloInterceptor(){
        System.out.println("创建了拦截器对象");
    }

    // 启动时候执行
    @Override
    public void init() {
        System.out.println("执行了拦截器的初始化方法");
    }

    // 拦截器业务处理方法 (在访问action时候执行? 在execute之前执行?)
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("2. 执行Action之前");
        
        // 调用下一个拦截器或执行Action  (相当于chain.doFilter(..)
        // 获取的是: execute方法的返回值
        String resultFlag = invocation.invoke();
        
        System.out.println("4. 拦截器,业务处理-结束" + resultFlag);
        
        return resultFlag;
    }   

    @Override
    public void destroy() {
        System.out.println("销毁....");
    }
}

1.3 进行相关配置


     
        
              
            
            
            
            
            
                
                
                
                
                        
        
                
        
    
        
        
        
            
            
            
                        
        
            /index.jsp
           
    
    

当我们访问helloAction时效果如下:

struts2框架(四)拦截器,国际化,Ognl表达式_第2张图片

可以看到,如过滤器一样,拦截器的构造方法和初始化也是在tomcat服务器启动时执行,当用户访问action时,先创建action实例,然后执行过滤器intercept方法,再执行action的execute方法,执行完后回到intercept。最扣在tomcat停止服务时会销毁拦截器对象。生命周期时序图如下:

struts2框架(四)拦截器,国际化,Ognl表达式_第3张图片

2.国际化

对比servlet的国际化,struts里面更简单

2.1 步骤

a). 写资源文件
基础名.properties  【默认的语言环境的配置】  
基础名_语言简称_国家简称.properties
b). 读取资源文件,再使用

程序:ResourceBundle (同servlet)
JSP:
1)jstl表亲啊 (同servlet)
2)struts标签获取资源文件内容

2.2 实例

1. 写资源文件

Msg.properties 默认的语言环境; 找不到配置就找它
Msg_en_US.properties 美国

2. 加载

    
3. 使用: 标签name值直接写配置文件中的key
<%@taglib uri="/struts-tags" prefix="s" %>

推荐用法:
  
          标签必须放到标签体中。
  

3.Ognl表达式

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

3.1 OgnlContext 的用法

OGNL 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map 的接口。

import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;

import org.junit.Test;

// OgnlContext用法
public class OgnlDemo1 {

    /**
     * 1. Ognl表达式语言语言取值,取非根元素的值,必须用#号
     * @throws Exception
     */
    @Test
    public void testOgnl() throws Exception {
        // 创建一个Ognl上下文对象
        OgnlContext context = new OgnlContext();
        // 放入数据
        User user = new User();
        user.setId(100);
        user.setName("Jack");
        // 【往非根元素放入数据, 取值的时候表达式要用"#"】
        context.put("user", user);
        
        // 获取数据(map)
        // 先构建一个Ognl表达式, 再解析表达式
        Object ognl = Ognl.parseExpression("#user.name");
        Object value = Ognl.getValue(ognl, context, context.getRoot());
        
        System.out.println(value);
    }
    
    /**
     * 2. Ognl表达式语言语言取值,取根元素的值,不用带#号
     * @throws Exception
     */
    @Test
    public void testOgn2() throws Exception {
        // 创建一个Ognl上下文对象
        OgnlContext context = new OgnlContext();
        // 放入数据
        User user = new User();
        user.setId(100);
        user.setName("Jack");
        // 【往根元素放入数据】
        context.setRoot(user);
        
        // 获取数据(map)
        // 先构建一个Ognl表达式, 再解析表达式
        Object ognl = Ognl.parseExpression("address.province");
        Object value = Ognl.getValue(ognl, context, context.getRoot());
        
        System.out.println(value);
    }
    
    /**
     * 3.Ognl对 静态方法调用的支持
     * @throws Exception
     */
    @Test
    public void testOgn3() throws Exception {
        // 创建一个Ognl上下文对象
        OgnlContext context = new OgnlContext();
        
        // Ognl表单式语言,调用类的静态方法
        //Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
        // 由于Math类在开发中比较常用,所以也可以这样写
        Object ognl = Ognl.parseExpression("@@floor(10.9)");
        Object value = Ognl.getValue(ognl, context, context.getRoot());
        System.out.println(value);
    }
}

3.2 ValueStack

ValueStack实际是一个接口,在Struts2中利用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2利用OGNL的基础。
ValueStack贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前Action 对象和其他相关对象.Struts2框架把 ValueStack 对象保存在名为 “struts.valueStack” 的request请求属性中。

3.2.1 ValueStack的获取

    // 获取值栈对象的2种方式
    private void getVs() {
        // 获取值栈对象,方式1:
        HttpServletRequest request = ServletActionContext.getRequest();
        ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack");

        // 获取值栈对象,方式2:
        ActionContext ac = ActionContext.getContext();
        ValueStack vs2 = ac.getValueStack();

        System.out.println(vs1 == vs2);// true
    }

3.2.2 ValueStack的数据结构

通过调试可以看到:struts中的ValueStack为其实现类OgnlValueStack,核心包含了作为Map栈的OgnlContext对象和继承了ArrayList的对象栈的CompoudRood对象,其中OgnlContext还封装了CompoudRood对象。

struts2框架(四)拦截器,国际化,Ognl表达式_第4张图片

数据结构图如下:

struts2框架(四)拦截器,国际化,Ognl表达式_第5张图片
对象栈: Struts  把动作和相关对象压入 ObjectStack 中--List
Map栈: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中
    Struts 会把下面这些映射压入 ContextMap 中
        parameters: 该 Map 中包含当前请求的请求参数
        request: 该 Map 中包含当前 request 对象中的所有属性
        session: 该 Map 中包含当前 session 对象中的所有属性
        application:该 Map 中包含当前 application  对象中的所有属性
        attr: 该 Map 按如下顺序来检索某个属性: request, session, application

3.3 Ognl表达式

3.3.1 #的作用

a) 用来区分访问的是Map栈不审List栈

 #号主要用于访问访问Map栈信息,不使用#号主要用于访问List(对象栈)信息。
 举例:
      
      
          // 获取对象栈信息(默认从栈顶检索)

Struts2的property 标签中value属性值会特意的将其中的值以OGNL表达式的方式进行运行。

b) 在JSP页面构建Map集合

格式:#{key:value,key:value...}
举例
      Struts2的radio标签主要任务是在页面中显示单选按钮
      
运行结果源码:

3.3.2 $号的作用

$号的作用
      在国际化资源文件中,引用OGNL表达式
      在Struts2配置文件中,引用OGNL表达式
举例
      ognl.xml配置文件
       
              /ognl/ognl.jsp?username=${#request.username}
       
       在ognl.jsp中获取携带的参数:
       

3.3.3 %号的作用

$号的作用
      “%”符号的作用是在当Struts2标签的属性值为OGNL表达式时OGNL表达式却被理解为字符串类型原样输出时,用于通知执行环境%{}里的是OGNL表达式。 
举例
      Struts2中的textfield标签主要用于在页面中显示一个文本输入框数据。类似input
      
      此时#request.username被理解为一个普通的字符串,因此直接显示。因为这里脱离了
      运行OGNL的环境即:环境。
      通知运行环境将#request.username以OGNL表达式运行:
      
总结
       为了方便使用%{}我们可以在任何地方都直接添加%{}来确保运行OGNL表达式:
       

4.Struts2标签

4.1 if/elseif/else标签

if/elseif/else 基本的流程控制.‘If’标签可单独使用也可以和‘Else If’标签和(或)一个多个‘Else’一起使用

少年
中年
老年

4.2 property标签

用于输出指定值:

格式:
     
 default:可选属性, 如果需要输出的属性值为null,则显示该属性指定的值
 escape:可选属性,指定是否格式化HTML代码。
 value:   可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值。

举例:

:输出栈顶的值

4.3 debug标签

struts的调试标签:可以观测值栈数据

4.4 iterator标签

用于对集合进行迭代,这里的集合包含List、Set和数组。



    
    




    


    
    
一、.构建 list集合

一、.构建 map集合

你可能感兴趣的:(struts2框架(四)拦截器,国际化,Ognl表达式)