• struts2基础——需要注意的几点


    struts是流行和成熟的基于MVC设计模式的web应用程序框架,使用struts可以帮助我们减少运用MVC设计模型来开发web应用的时间。

    目录:

    一、struts2的工作原理及文件结构

    二、三种访问Servlet API的方式

    三、struts接收参数的三种方式

    四、自定义拦截器

    一、struts2的工作原理及文件结构

    注:FilterDispatcher被替成StrutsPrepareAndExecuteFilter(如果使用FilterDispatcher过滤器时,程序员自己写的Filter过滤器必须放在所有过滤器的前面。而StrutsPrepareAndExecuteFilter过滤器可以让程序员在执行action之前写自己的Filter)

    描述Struts流程:

    网页产生HttpServletRequest请求->经过多个过滤器->到达ActionMaaper,判断是否是action请求(如果是)->通过StrutsPrepareAndExecuteFilter过滤器到达Actionproxy,一方面通过configuration Manager(配置管理器)读取struts.xml文档,另一方面创建一个实例,经过一系列的拦截器->执行到Action->返回result(对应了视图)->经过一系列的拦截器(逆序)->通过HttpServletResponse返回到用户实例。

    二、三种访问servlet API的方法

    struts2中没有提供任何一个servlet对象,不存在HttpServletRequest,HttpServletResponse对象。但是Struts2提供了三种方式间接的去访问Servlet API

    1、ActionContext

    通过ActionContext的getContext()静态方法获取ActionContext对象,通过ActionContext对象的一些getSession(),getApplication(),put()等方法,但是千万要注意的是,get获取到的对象都为Map键值对类型。com.opensymphony.xwork2.ActionContext

     1 public String execute() {
     2         if ("ping".equals(username)) {
     3             /*
     4              * ActionContext可以获得Servlet对象 但是无法获得response响应对象获得
     5              * 获得的request、session、Application 都是Map类型
     6              */
     7 
     8             ActionContext.getContext().put("用户名", username);
     9             Map session=ActionContext.getContext().getSession();
    10             Map application=ActionContext.getContext().getApplication();
    11             Map request=(Map)ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);
    12         } else {
    13             ActionContext.getContext().put("info", "信息");
    14         }
    15         return SUCCESS;
    16     }

    2、ServletActionContext

    通过调用ServletActionContext类的一些包括getResponse(),getRequest(),getServletContext()等在内的静态方法,这些静态方法的返回类型是和Servlet中的对象类型是一一对应的。其中getResponse()返回类型为HttpServletResponse,getRequest()返回类型为HttpServletRequest().

     1 public String execute2() throws IOException {
     2         if ("ping".equals(username)) { 
     3             HttpServletResponse response=ServletActionContext.getResponse();
     4             HttpServletRequest request=ServletActionContext.getRequest();
     5             HttpSession session=ServletActionContext.getRequest().getSession();
     6             ServletContext application=ServletActionContext.getServletContext();
     7         } else {
     8             
     9         }
    10         System.out.println(username);
    11         return SUCCESS;
    12     }

    3、实现xxxAware接口

    (1)实现ServletRequestAware,ServletResponseAware,ServletSessionAware  

     1 public class LoginAction extends ActionSupport implements ServletRequestAware
     2 
     3 
     4 private HttpServletRequest request;
     5 //需实现方法 public void setServletRequest(HttpServletRequest request) { this.request=request; } //response示例
     6 public String execute1() throws IOException {
     7         if ("ping".equals(username)) {
     8             response.setContentType("text/html;charset=utf-8");   
     9             PrintWriter out = response.getWriter();   
    10             out.print("<script type='text/javascript'>alert('验证码输入错误!')</script>");   
    11             out.print("<script type='text/javascript'>location.href='/index.jsp'</script>");   
    12             out.flush();   
    13             out.close();  
    14         } else {
    15             response.setContentType("text/html;charset=utf-8");   
    16             PrintWriter out = response.getWriter();   
    17             out.print("<script type='text/javascript'>alert('验证码输入错误!')</script>");   
    18             out.flush();   
    19             out.close();  
    20         }
    21         System.out.println(username);
    22         return SUCCESS;
    23     }

    (2)实现RequestWare、SessionWare、ApplicationWare等接口

    public class LoginAction2 extends ActionSupport implements RequestAware,SessionAware, ApplicationAware {
        
        private Map<String, Object> request;
        private Map<String, Object> session;
        private Map<String, Object> application;
        
        //DI dependency injection
        //IoC inverse of control
        public String execute() {
            request.put("r1", "r1");
            session.put("s1", "s1");
            application.put("a1", "a1");
            return SUCCESS; 
        }
    
        @Override
        public void setRequest(Map<String, Object> request) {
            this.request = request;
        }
    
        @Override
        public void setSession(Map<String, Object> session) {
            this.session = session;
        }
    
        @Override
        public void setApplication(Map<String, Object> application) {
            this.application = application;
        }
        
        
    }

    三、struts三种接收参数方式

    Struts有三种方式接收参数,且这三种方式都是自动完成赋值的setter方法。

    1、使用Action的属性接收参数

    代码:

    struts.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
    
          "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
         
          "http://struts.apache.org/dtds/struts-2.3.dtd">
           
    <struts>
    
    <package name="default" namespace="/" extends="struts-default">
      <action name="LoginAction" method="login" class="com.third.LoginAction1">
        <result>/loginSuccess.jsp</result>
      </action>
    </package>
    
    
    </struts>

    login.jsp(登陆提示页面)

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>login page</h1>
        <form action="LoginAction.action" method="post">
           <table>
              <tr>
                 <td>username:</td>
                 <td><input type="text" name="username"/></td>
              </tr>
               <tr>
                 <td>password:</td>
                 <td><input type="password" name="password"/></td>
              </tr>
           
              <tr> 
                 <td><input type="submit" value="submit"></td>
                 <td><input type="reset" value="reset"></td>
              </tr>
              
           </table>
        
        </form>
    </body>
    </html>

    loginSuccess.jsp(登陆成功提示界面)

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>login success!</title>
    </head>
    <body>
    <h1>login success!</h1>
    </body>
    </html>

    LoginAction.java

     1 package com.third;
     2 
     3 import com.opensymphony.xwork2.ActionSupport;
     4 
     5 public class LoginAction1 extends ActionSupport {
     6 
     7     private String username;
     8     private String password;
     9     
    10     public String login(){
    //这里能够打印出来传入的值,则说明能够自动调用setter方法完成赋值
    11 System.out.println("username:"+username+" password:"+password); 12 return SUCCESS; 13 } 14 15 public String getUsername() { 16 return username; 17 } 18 19 public void setUsername(String username) { 20 this.username = username; 21 } 22 23 public String getPassword() { 24 return password; 25 } 26 27 public void setPassword(String password) { 28 this.password = password; 29 } 30 31 }

    运行结果截图:

    2、使用DomainModel接收参数

    注:这里在表单传值是,必须指明这个属性值,到底穿个action中的那个引用,例如user.username.

    代码:

    struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
    <struts>
       
       <package name="default" namespace="/" extends="struts-default">
          <action name="LoginAction" method="login" class="com.third.LoginAction">
            <result>/loginSuccess.jsp</result>
          </action>
       </package>
      
    </struts>  

    login.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'login.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
      <h1>login page!</h1>
       <form action="LoginAction.action" method="post">
           <table>
              <tr>
                 <td>username:</td>
                 <td><input type="text" name="user.username"/></td>
              </tr>
               <tr>
                 <td>password:</td>
                 <td><input type="password" name="user.password"/></td>
              </tr>
           
              <tr> 
                 <td><input type="submit" value="submit"></td>
                 <td><input type="reset" value="reset"></td>
              </tr>       
           </table>   
        </form>
      </body>
    </html>

    loginSuccess.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'loginSuccess.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
          <h1>login success!</h1>
      </body>
    </html>

    User.java

    package com.third;
    
    public class User {
    
        private String username;
        private String password;
        
        
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }    
    }

    LoginAction.java

     1 package com.third;
     2 
     3 import org.apache.struts2.ServletActionContext;
     4 
     5 import com.opensymphony.xwork2.ActionContext;
     6 import com.opensymphony.xwork2.ActionSupport;
     7 import com.opensymphony.xwork2.inject.Context;
     8 
     9 public class LoginAction extends ActionSupport {
    10 
    11     private User user;
    12     public User getUser() {
    13         return user;
    14     }
    15 
    16     public void setUser(User user) {
    17         this.user = user;
    18     }
    19     public String login(){
    //这里可以打印出传入的值的话,Action完成了自动调用setter方法赋值
    20 System.out.println("username:"+user.getUsername()+" password:"+this.getUser().getPassword()); 21 return SUCCESS; 22 } 23 24 }

    运行结果截图:

    3、使用ModelDriven接受参数

    struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
    <struts>
       
       <package name="default" namespace="/" extends="struts-default">
          <action name="LoginAction" method="login" class="com.third.LoginAction">
            <result>/loginSuccess.jsp</result>
          </action>
       </package>
      
    </struts>    

    login.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'login.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
      <h1>login page!</h1>
       <form action="LoginAction.action" method="post">
           <table>
              <tr>
                 <td>username:</td>
                 <td><input type="text" name="username"/></td>
              </tr>
               <tr>
                 <td>password:</td>
                 <td><input type="password" name="password"/></td>
              </tr>
           
              <tr> 
                 <td><input type="submit" value="submit"></td>
                 <td><input type="reset" value="reset"></td>
              </tr>       
           </table>   
        </form>
      </body>
    </html>

    loginSuccess.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'loginSuccess.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
          <h1>login success!</h1>
      </body>
    </html>

    User.java

    package com.third;
    
    public class User {
    
        private String username;
        private String password;
        
        
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }    
    }

    LoginAction.java

    package com.third;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    import com.opensymphony.xwork2.inject.Context;
    
    public class LoginAction extends ActionSupport implements ModelDriven<User> {
    
        private User user=new User();
        public String login(){
    //这里打印出传入的参数值,说明自动调用setter方法赋值 System.out.println(
    "username:"+user.getUsername()+" password:"+user.getPassword()); return SUCCESS; } @Override public User getModel() { return user; } }

    运行结果截图:

    四、自定义拦截器

    注:特别要注意在使用拦截的器的时候,使用表单传值,会导致Action中获得的属性的值为null,或是其他的默认的初始化值。

    1、实现Interceptor接口

    -void init()方法:初始化拦截器所需要的资源

    -void destory()方法:释放init()中分配的资源

    -String intercept(ActionInvocation invocation)throws Exception:实现拦截器功能,利用ActionInvocation参数获取Action状态,返回result字符串作为逻辑视图。

    代码:

    struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
    <struts>
    
       
       <package name="default" namespace="/" extends="struts-default">
       <!--注册拦截器  -->
          <interceptors>
             <interceptor name="timefigureFilter" class="com.third.TimeInterceptor">
             </interceptor>
          </interceptors>
       
       
          <action name="LoginAction" method="login" class="com.third.LoginAction">
            <result>/loginSuccess.jsp</result>
            <interceptor-ref name="timefigureFilter"></interceptor-ref>
          </action>
       </package>
      
    </struts>    

    login.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'login.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
      <h1>login page!</h1>
       <form action="LoginAction.action" method="post">
           <table>
              <tr>
                 <td>username:</td>
                 <td><input type="text" name="username"/></td>
              </tr>
               <tr>
                 <td>password:</td>
                 <td><input type="password" name="password"/></td>
              </tr>
           
              <tr> 
                 <td><input type="submit" value="submit"></td>
                 <td><input type="reset" value="reset"></td>
              </tr>       
           </table>   
        </form>
      </body>
    </html>

    loginSuccess.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'loginSuccess.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
          <h1>login success!</h1>
      </body>
    </html>

    User.java

    package com.third;
    
    public class User {
    
        private String username;
        private String password;
        
        
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }    
    }

    TimeInterceptor.java

     1 package com.third;
     2 
     3 import javax.servlet.http.HttpServletRequest;
     4 
     5 import org.apache.struts2.ServletActionContext;
     6 
     7 import com.opensymphony.xwork2.ActionInvocation;
     8 import com.opensymphony.xwork2.interceptor.Interceptor;
     9 
    10 public class TimeInterceptor implements Interceptor {
    11 
    12     @Override
    13     public void destroy() {
    14         // TODO Auto-generated method stub
    15 
    16     }
    17 
    18     @Override
    19     public void init() {
    20         // TODO Auto-generated method stub
    21 
    22     }
    23 
    24     @Override
    25     public String intercept(ActionInvocation invocation) throws Exception {
    26         HttpServletRequest request=ServletActionContext.getRequest();
    27         String username=request.getParameter("username");
    28         String password=request.getParameter("password");
    29         request.setAttribute("username", username);
    30         //1执行action之前
    31         long start=System.currentTimeMillis();
    32         //2执行下一个拦截器,直到最后一个拦截器,则执行目标Action
    33         String result=invocation.invoke();
    34         //3执行完action之后
    35         long end=System.currentTimeMillis();
    36         System.out.println("执行Action花费的时间为:"+(end-start)+"ms");
    37         return result;
    38     }
    39 
    40 }

    LoginAction.java

     1 package com.third;
     2 
     3 import org.apache.struts2.ServletActionContext;
     4 
     5 import com.opensymphony.xwork2.ActionContext;
     6 import com.opensymphony.xwork2.ActionSupport;
     7 import com.opensymphony.xwork2.ModelDriven;
     8 import com.opensymphony.xwork2.inject.Context;
     9 
    10 public class LoginAction extends ActionSupport implements ModelDriven<User> {
    11 
    12     private User user=new User();
    13     public String login(){
    //着重看着两行代码运行打印的结果
    14 System.out.println("username:"+user.getUsername());
    //System.out.println("username:"+ServletContext.getRequest().getAttribute("username");//这里也可完成正常的获值
    15 System.out.println("username:"+ServletActionContext.getRequest().getAttribute("username"));
    16 return SUCCESS; 17 } 18 19 @Override 20 public User getModel() { 21 22 return user; 23 } 24 25 }

    运行结果截图:

    注:注意看结果,打印的第一个username的属性值为null,而第二个为表单填写的dasd。这里涉及到拦截器的使用导致的表单传值问题。

    分析:拦截器的使用导致的表单传值问题

    原因:登陆界面填写完成之后,表单需要实现页面跳转,而这些将会交给struts,struts在调用action的过程其实是调用action中的struts.xml配置action标签method属性指定的方法(默认是execute()),而在调用这个方法前会对表单的属性信息将会别匹配赋值给action中同名属性。正常情况下没有自定义的拦截器,通过表单传递的属性值没有问题。

    要完成这个功能,有很大程度上, Struts 2 要依赖与 ValueStack 对象。这个对象贯穿整个 Action 的生命周期 (每个 Action 类的对象实例会拥有一个 ValueStack 对象 ) 。当 Struts 2 接收到一个 action 的请求后,会先建立Action 类的对象实例,但不会调用 Action 方法,而是先将 Action 类的相应属性放到 ValueStack 对象的顶层节点(ValueStack 对象相当于一个栈 ). 只是所有的属性值都是默认的值,如 String 类型的属性值为 null,int 类型的属性值为 0 等。

       在处理完上述工作后, Struts 2 就会调用拦截器链中的拦截器,当调用完所有的拦截器后,最后会调用 Action 类的 Action 方法,在调用 Action 方法之前,会将 ValueStack 对象顶层节点中的属性值赋给 Action 类中相应的属性。大家要注意,在这里就给我们带来了很大的灵活性。也就是说,在 Struts 2 调用拦截器的过程中,可以改变ValueStack 对象中属性的值,当改变某个属性值后, Action 类的相应属性值就会变成在拦截器中最后改变该属性的这个值。

    好多废话~总结就是:在拥有自定义的过滤器时,表单传属性值会先赋值给Action中属性,当运行完过滤器时,才会调用Action中的方法,在调用之前会将 ValueStack 对象中的默认初始化值赋给action中的属性,然后调用action中的方法,这样action中的属性全是ValueStack 对象中的默认初始化值。

    解决的方法:间接访问Servlet的API,通过request对象去访问属性和属性值。如:

    HttpServletRequest request=ServletActionContext.getRequest();

    String username=request.getParameter("username");

    2、方式二:继承AbstractInterceptor类

    -提供了init()和destroy()方法的实现

    -只需要实现intercept()方法即可

    代码:

    struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
    <struts>
    
       
       <package name="default" namespace="/" extends="struts-default">
       <!--注册拦截器  -->
          <interceptors>       
              <interceptor name="timefigureFilter1" class="com.third1.TimeInterceptor">
             </interceptor>
          </interceptors>
          
           <action name="TimeAction" class="com.third1.TimeAction">
            <result>/index.jsp</result>
            <!--引用拦截器  -->
            <interceptor-ref name="timefigureFilter1"></interceptor-ref>
          </action>
          
       </package>
      
    </struts>    

    TimeInterceptor.java

     1 package com.third1;
     2 
     3 import org.apache.struts2.ServletActionContext;
     4 
     5 import com.opensymphony.xwork2.ActionInvocation;
     6 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
     7 
     8 public class TimeInterceptor extends AbstractInterceptor {
     9 
    10     @Override
    11     public String intercept(ActionInvocation invocation) throws Exception {
    12         //1.执行action之前
    13         long start=System.currentTimeMillis();
    14         //2.执行下一个拦截器,如果已经是最后一个拦截器,则执行目标Action
    15         
    16         ServletActionContext.getRequest().setAttribute("username", "小帅哥");
    17         ServletActionContext.getRequest().getSession().setAttribute("username","小美女");
    18         ServletActionContext.getServletContext().setAttribute("username", "少艾");
    19         String result=invocation.invoke();
    20         //3.执行Action之后
    21         long end=System.currentTimeMillis();
    22         System.out.println("执行Action花费的时间:"+(end-start)+"ms");
    23         //获取request对象,调用其setAttribute函数,将时间作为属性保存到request对象中
    24         ServletActionContext.getRequest().setAttribute("time", (end-start));
    25         ServletActionContext.getRequest().getSession().setAttribute("time1",(end-start));
    26         ServletActionContext.getServletContext().setAttribute("time2", (end-start));
    27         return result;
    28     }
    29 
    30 }

    TimeAction.java

     1 package com.third1;
     2 
     3 import com.opensymphony.xwork2.ActionSupport;
     4 
     5 public class TimeAction extends ActionSupport {
     6 
     7     @Override
     8     public String execute() throws Exception{
     9         
    10         for(int i=0;i<3;i++){
    11             Thread.sleep(1000);
    12         }
    13         return SUCCESS;
    14     }
    15 }

    index.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'index.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
      </head>
      
      <body>
       
       <h1>执行Action用户名:<%=request.getAttribute("username") %>(通过request方式获取)</h1>
       <h1>执行Action用户名:<%=session.getAttribute("username") %>(通过session方式获取)</h1>
       <h1>执行Action用户名:<%=application.getAttribute("username") %>(通过application方式获取)</h1>
      
       <h1>执行Action花费的时间:<%=request.getAttribute("time") %>(通过request方式获取)</h1>
       <h1>执行Action花费的时间:<%=session.getAttribute("time1") %>(通过session方式获取)</h1>
       <h1>执行Action花费的时间:<%=application.getAttribute("time2") %>(通过application方式获取)</h1>
      </body>
    </html>

    运行结果截图:

    分析:对比两种颜色标记的代码区,对比一下他们,并且结合结果进行分析。我们不难发现过滤器的调用分为两个阶段,第一个阶段是在产生HttpServletRequest请求之后、action方法调用之前;第二阶段是产生与action之后,jsp页面(Template显示)跳转之后,HttpServletResponse之前。所以当你在 String result=invocation.invoke();   这条语句之后通过request,application,session给它设置属性值,将会没有起到任何作用。

    可以结合struts2的工作原理及文件结构图进行参考。

     

  • 相关阅读:
    iOS
    2016-北京游线路规划
    OC 组合实现多继承
    如何把项目托管到GitHub
    iOS6和iOS7代码的适配(2)——status bar
    iOS6和iOS7代码的适配(1)
    Xcode ARC需要什么版本的环境支持
    内容页直接输出图集函数及使用方法
    vue-cli如何引入bootstrap工具
    实现Sublime Text3中vue文件高亮显示的最有效的方法
  • 原文地址:https://www.cnblogs.com/xiaotiaosi/p/6480730.html
Copyright © 2020-2023  润新知