📜  Struts 2-拦截器

📅  最后修改于: 2020-11-11 04:57:25             🧑  作者: Mango


拦截器在概念上与servlet过滤器或JDK代理类相同。拦截器允许横切功能与操作以及框架分开实现。您可以使用拦截器实现以下目标-

  • 在调用动作之前提供预处理逻辑。

  • 调用动作后提供后处理逻辑。

  • 捕获异常,以便可以执行替代处理。

Struts2框架中提供的许多功能都是使用拦截器实现的。

示例包括异常处理,文件上载,生命周期回调等。实际上,由于Struts2在拦截器上强调了其许多功能,因此每个动作不太可能分配7或8个拦截器。

Struts2框架拦截器

Struts 2框架提供了一个很好的现成的拦截器列表,这些拦截器已经预先配置好并可以使用。下面列出了几个重要的拦截器-

Sr.No Interceptor & Description
1

alias

Allows parameters to have different name aliases across requests.

2

checkbox

Assists in managing check boxes by adding a parameter value of false for check boxes that are not checked.

3

conversionError

Places error information from converting strings to parameter types into the action’s field errors.

4

createSession

Automatically creates an HTTP session if one does not already exist.

5

debugging

Provides several different debugging screens to the developer.

6

execAndWait

Sends the user to an intermediary waiting page while the action executes in the background.

7

exception

Maps exceptions that are thrown from an action to a result, allowing automatic exception handling via redirection.

8

fileUpload

Facilitates easy file uploading.

9

i18n

Keeps track of the selected locale during a user’s session.

10

logger

Provides simple logging by outputting the name of the action being executed.

11

params

Sets the request parameters on the action.

12

prepare

This is typically used to do pre-processing work, such as setup database connections.

13

profile

Allows simple profiling information to be logged for actions.

14

scope

Stores and retrieves the action’s state in the session or application scope.

15

ServletConfig

Provides the action with access to various servlet-based information.

16

timer

Provides simple profiling information in the form of how long the action takes to execute.

17

token

Checks the action for a valid token to prevent duplicate formsubmission.

18

validation

Provides validation support for actions

请查阅Struts 2文档以获取有关上述拦截器的完整详细信息。但是,我将向您展示如何在Struts应用程序中通常使用拦截器。

如何使用拦截器?

让我们看看如何在我们的“ Hello World”程序中使用一个已经存在的拦截器。我们将使用计时器拦截器,其目的是测量执行一个动作方法所花费的时间。同时,我正在使用params拦截器,其目的是将请求参数发送到操作。您可以在不使用此拦截器的情况下尝试示例,并且会发现未设置name属性,因为参数无法执行该操作。

我们将保留在示例一章中创建的HelloWorldAction.java,web.xml,HelloWorld.jsp和index.jsp文件,但让我们修改struts.xml文件以添加拦截器,如下所示-




   
   
   
      
         
         
         /HelloWorld.jsp
      
   

右键单击项目名称,然后单击导出> WAR文件以创建War文件。然后,将此WAR部署在Tomcat的webapps目录中。最后,启动Tomcat服务器并尝试访问URL http:// localhost:8080 / HelloWorldStruts2 / index.jsp 。这将产生以下屏幕-

Hello World Struts 4

现在,在给定的文本框中输入任何单词,然后单击“说你好”按钮以执行定义的操作。现在,如果您要检查生成的日志,您将找到以下文本:

INFO: Server startup in 3539 ms
27/08/2011 8:40:53 PM 
com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Executed action [//hello!execute] took 109 ms.

在这里,由于计时器拦截器而产生了底线,该计时器拦截器告诉操作执行了总共109ms的操作。

创建自定义拦截器

在应用程序中使用自定义拦截器是提供横切应用程序功能的一种优雅方法。创建自定义拦截器很容易;需要扩展的接口是以下Interceptor接口-

public interface Interceptor extends Serializable {
   void destroy();
   void init();
   String intercept(ActionInvocation invocation)
   throws Exception;
}

顾名思义,init()方法提供了一种初始化拦截器的方法,destroy()方法提供了用于清除拦截器的工具。与动作不同,拦截器可跨请求重用,并且需要是线程安全的,尤其是intercept()方法。

ActionInvocation对象提供对运行时环境的访问。它允许访问动作本身和方法,以调用该动作并确定该动作是否已被调用。

如果不需要初始化或清除代码,则可以扩展AbstractInterceptor类。这提供了init()和destroy()方法的默认nooperation实现。

创建拦截器类

让我们在Java资源> src文件夹中创建以下MyInterceptor.java-

package com.tutorialspoint.struts2;

import java.util.*;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {

   public String intercept(ActionInvocation invocation)throws Exception {

      /* let us do some pre-processing */
      String output = "Pre-Processing"; 
      System.out.println(output);

      /* let us call action or next interceptor */
      String result = invocation.invoke();

      /* let us do some post-processing */
      output = "Post-Processing"; 
      System.out.println(output);

      return result;
   }
}

如您所见,实际的动作将通过invocation.invoke()调用使用拦截器执行。因此,您可以根据需要进行一些预处理和一些后处理。

框架本身通过对ActionInvocation对象的invoke()进行第一次调用来启动该过程。每次调用invoke()时,ActionInvocation都会查询其状态并执行下一个拦截器。调用所有已配置的拦截器后,invoke()方法将导致动作本身被执行。

下图通过请求流显示了相同的概念-

动作调用

创建动作类

让我们在Java资源> src下创建一个Java文件HelloWorldAction.java,其包名称为com.tutorialspoint.struts2 ,其内容如下。

package com.tutorialspoint.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {
   private String name;

   public String execute() throws Exception {
      System.out.println("Inside action....");
      return "success";
   }  

   public String getName() {
      return name;
   }

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

这是我们在前面的示例中看到的同一类。我们具有用于“ name”属性的标准getter和setter方法,以及具有返回字符串“ success”的execute方法。

创建一个视图

让我们在Eclipse项目的WebContent文件夹中创建以下jsp文件HelloWorld.jsp

Hello World
   
   
   
      Hello World, 
   

创建主页

我们还需要在WebContent文件夹中创建index.jsp 。该文件将用作初始操作URL,用户可以单击该URL告诉Struts 2框架调用HelloWorldAction类的已定义方法并呈现HelloWorld.jsp视图。

Hello World
   
   
   
      

Hello World From Struts2


上面的视图文件中定义的hello操作将使用struts.xml文件映射到HelloWorldAction类及其执行方法。

配置文件

现在,我们需要注册我们的拦截器,然后像在上一个示例中调用默认拦截器一样对其进行调用。要注册新定义的拦截器,将标记直接放置在struts.xml文件中的标记下。您可以像上一个示例一样跳过默认拦截器的此步骤。但是在这里让我们注册并如下使用它-





   
   

      
         
      

      
         
         
         /HelloWorld.jsp
      

   

应该注意的是,您可以在标签内注册多个拦截器,同时可以在标签内调用多个拦截器。您可以使用不同的操作调用相同的拦截器。

需要在WebContent的WEB-INF文件夹下创建web.xml文件,如下所示:



   
   Struts 2
   
   
      index.jsp
   
   
   
      struts2
      
         org.apache.struts2.dispatcher.FilterDispatcher
      
   

   
      struts2
      /*
   

右键单击项目名称,然后单击导出> WAR文件以创建War文件。然后,将此WAR部署在Tomcat的webapps目录中。最后,启动Tomcat服务器并尝试访问URL http:// localhost:8080 / HelloWorldStruts2 / index.jsp 。这将产生以下屏幕-

Hello World Struts 4

现在,在给定的文本框中输入任何单词,然后单击“说你好”按钮以执行定义的操作。现在,如果您要检查生成的日志,您将在底部找到以下文本:

Pre-Processing
Inside action....
Post-Processing

堆叠多个拦截器

可以想象,为每个动作配置多个拦截器将很快变得非常难以管理。因此,拦截器由拦截器堆栈管理。这是一个示例,直接来自strutsdefault.xml文件-


   
   
   
   
   
   

上面的股份称为basicStack ,可以在您的配置中使用,如下所示。该配置节点位于节点下。每个标记都引用一个拦截器或一个在当前拦截器堆栈之前配置的拦截器堆栈。因此,在配置初始拦截器和拦截器堆栈时,确保名称在所有拦截器和拦截器堆栈配置中都是唯一的,这一点非常重要。

我们已经了解了如何将拦截器应用于操作,应用拦截器堆栈没有什么不同。实际上,我们使用完全相同的标签-


   
   view.jsp

上面的“ basicStack”注册将通过hello动作注册所有六个拦截器的全部股份。应该注意的是,拦截器是按照配置它们的顺序执行的。例如,在上述情况下,将首先执行异常,其次是servlet-config,依此类推。