📅  最后修改于: 2020-11-11 04:57:25             🧑  作者: Mango
拦截器在概念上与servlet过滤器或JDK代理类相同。拦截器允许横切功能与操作以及框架分开实现。您可以使用拦截器实现以下目标-
在调用动作之前提供预处理逻辑。
调用动作后提供后处理逻辑。
捕获异常,以便可以执行替代处理。
Struts2框架中提供的许多功能都是使用拦截器实现的。
示例包括异常处理,文件上载,生命周期回调等。实际上,由于Struts2在拦截器上强调了其许多功能,因此每个动作不太可能分配7或8个拦截器。
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 。这将产生以下屏幕-
现在,在给定的文本框中输入任何单词,然后单击“说你好”按钮以执行定义的操作。现在,如果您要检查生成的日志,您将找到以下文本:
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类及其执行方法。
现在,我们需要注册我们的拦截器,然后像在上一个示例中调用默认拦截器一样对其进行调用。要注册新定义的拦截器,将
/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 。这将产生以下屏幕-
现在,在给定的文本框中输入任何单词,然后单击“说你好”按钮以执行定义的操作。现在,如果您要检查生成的日志,您将在底部找到以下文本:
Pre-Processing
Inside action....
Post-Processing
可以想象,为每个动作配置多个拦截器将很快变得非常难以管理。因此,拦截器由拦截器堆栈管理。这是一个示例,直接来自strutsdefault.xml文件-
上面的股份称为basicStack ,可以在您的配置中使用,如下所示。该配置节点位于
我们已经了解了如何将拦截器应用于操作,应用拦截器堆栈没有什么不同。实际上,我们使用完全相同的标签-
view.jsp
上面的“ basicStack”注册将通过hello动作注册所有六个拦截器的全部股份。应该注意的是,拦截器是按照配置它们的顺序执行的。例如,在上述情况下,将首先执行异常,其次是servlet-config,依此类推。