struts2 拦截器_Struts 2拦截器示例

struts2 拦截器

Welcome to Struts 2 Interceptor Example. While working on Struts 2, most of the time you will spend on Action Classes but Interceptors are the backbone of Struts 2 Framework.

欢迎使用Struts 2拦截器示例。 在Struts 2上工作时,大多数时候您将花在Action Class上,但是Interceptor是Struts 2 Framework的基础。

Struts 2拦截器 (Struts 2 Interceptor)

Struts 2 interceptors are responsible for most of the processing done by the framework. For example, passing request params to action classes, making Servlet API request, response, session available to Action classes, validation, i18n support etc.

Struts 2拦截器负责框架完成的大多数处理。 例如,将请求参数传递给动作类,使Servlet API请求,响应,会话可用于动作类,验证,i18n支持等。

Struts 2 provides a bunch of interceptors and most of them are defined in struts-default package and used in defaultStack interceptor stack. Interceptors are the power of Struts 2 framework that plays a crucial role in achieving high level of separation of concerns.

Struts 2提供了一堆拦截器,其中大多数是在struts-default包中定义的,并在defaultStack拦截器堆栈中使用。 拦截器是Struts 2框架的强大功能,在实现关注点的高度分离方面起着至关重要的作用。

In our Struts 2 Beginners Tutorial, we looked at the Struts 2 architecture and saw that every request and response passes through interceptors. Hence interceptors can inject different objects, perform specific operations on request and response and do some cross cutting tasks for the application.

在《 Struts 2初学者教程》中 ,我们研究了Struts 2架构,并看到每个请求和响应都通过拦截器传递。 因此,拦截器可以注入不同的对象,根据请求和响应执行特定的操作,并为应用程序执行一些交叉任务。

ActionInvocation is responsible to incapsulate Action classes and interceptors and to fire them in order. The most important method for use in ActionInvocation is invoke() method that keeps track of the interceptor chain and invokes the next interceptor or action. This is one of the best example of Chain of Responsibility pattern in Java EE frameworks.

ActionInvocation负责封装Action类和拦截器,并按顺序触发它们。 在ActionInvocation中使用的最重要的方法是invoke()方法,该方法跟踪拦截器链并调用下一个拦截器或操作。 这是Java EE框架中“责任链”模式的最佳示例之一。

Struts 2 API reads the interceptors defined for an action in the order it’s declared. So if interceptor1 and interceptor2 are defined for action1 then ActionInvocation will invoke them in following chain.

Struts 2 API按照声明的顺序读取为操作定义的拦截器。 因此,如果为action1定义了interceptor1和interceptor2,则ActionInvocation将在随后的链中调用它们。

interceptor1 -> interceptor2 -> action1 -> interceptor2 -> interceptor1

拦截器1->拦截器2->动作1->拦截器2->拦截器1

If any of the interceptor intercept() method decides that action should not get executed, it can return a string value and response will be created from global result with that name from struts configuration file.

如果任何拦截器intercept()方法确定不应执行该操作,则它可以返回一个字符串值,并且将从struts配置文件中具有该名称的全局结果中创建响应。

Struts 2拦截器和全局结果配置 (Struts 2 Interceptors and Global Results configuration)

We can define global results in struts.xml file as:

我们可以在struts.xml文件中将全局结果定义为:

<global-results>
	<result name="login" type="redirect">/login.action</result>
</global-results>

These results can be used by any of the action classes.

这些结果可以被任何动作类使用。

Defining interceptors for a package includes several steps and we need to define them with interceptors, interceptor, interceptor-stack and default-interceptor-ref elements. They should be the first elements of the package or else you will get error message as

为包定义拦截器包括几个步骤,我们需要使用拦截器,拦截器,拦截器堆栈和默认拦截器-ref元素对其进行定义。 它们应该是包的第一个元素,否则您将收到以下错误消息:


interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-
拦截器参考?,默认动作参考?,默认类参考?,全局结果?,全局异常-
mappings?,action*)”.
映射?,动作*)”。

Struts 2拦截器示例 (Struts 2 Interceptor Example)

A simple example of interceptor configuration is:

拦截器配置的一个简单示例是:

<package name="user" namespace="/" extends="struts-default">
	<interceptors>
		<interceptor name="authentication"
			class="com.journaldev.struts2.interceptors.AuthenticationInterceptor"></interceptor>
		<interceptor-stack name="authStack">
			<interceptor-ref name="authentication"></interceptor-ref>
			<interceptor-ref name="defaultStack"></interceptor-ref>
		</interceptor-stack>
	</interceptors>

	<default-interceptor-ref name="authStack"></default-interceptor-ref>
</package>

Note that defaultStack is already configured in struts-default package, that’s why we don’t need to define that in above example.

注意,defaultStack已经在struts-default包中配置了,这就是为什么我们不需要在上面的示例中定义它的原因。

Let’s create a simple application where we will use custom interceptor class to provide authentication for our application. Using interceptor will make our application loosely coupled, flexible and configurable. Our final project will look like below image.

让我们创建一个简单的应用程序,在这里我们将使用自定义拦截器类为我们的应用程序提供身份验证。 使用拦截器将使我们的应用程序松散耦合,灵活且可配置。 我们的最终项目将如下图所示。

Struts2拦截器示例项目配置文件 (Struts2 Interceptor Example Project configuration Files)

web.xml

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns="https://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>Struts2InterceptorExample</display-name>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

pom.xml

pom.xml

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>Struts2InterceptorExample</groupId>
	<artifactId>Struts2InterceptorExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<dependencies>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.3.15.1</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
		<finalName>${project.artifactId}</finalName>
	</build>
</project>

pom.xml and web.xml configuration files are self understood.

pom.xml和web.xml配置文件是可以理解的。

struts.xml

struts.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"https://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<constant name="struts.convention.result.path" value="/"></constant>

	<package name="user" namespace="/" extends="struts-default">
		<interceptors>
			<interceptor name="authentication"
				class="com.journaldev.struts2.interceptors.AuthenticationInterceptor"></interceptor>
			<interceptor-stack name="authStack">
				<interceptor-ref name="authentication"></interceptor-ref>
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>

		<default-interceptor-ref name="authStack"></default-interceptor-ref>

		<global-results>
			<result name="login" type="redirect">/home.action</result>
		</global-results>

		<action name="home">
			<interceptor-ref name="defaultStack"></interceptor-ref>
			<result>/login.jsp</result>
		</action>

		<action name="login" class="com.journaldev.struts2.actions.LoginAction">
			<interceptor-ref name="defaultStack"></interceptor-ref>
			<result name="success">/welcome.jsp</result>
			<result name="input">/login.jsp</result>
		</action>
		<action name="welcome" class="com.journaldev.struts2.actions.WelcomeAction">
			<result name="success">/welcome.jsp</result>
		</action>

	</package>

</struts>

Notice that I am declaring an interceptor authentication which is referring to class com.journaldev.struts2.interceptors.AuthenticationInterceptor.

注意,我声明了一个拦截器authentication ,该authentication是指类com.journaldev.struts2.interceptors.AuthenticationInterceptor

Also notice that authStack is the default interceptor-stack for the package. I am not using this stack for login.jsp because it’s used for login and at that time user will not have session to authenticate.

另请注意, authStack是该软件包的默认拦截器堆栈。 我没有将这个堆栈用于login.jsp,因为它用于登录,并且那时用户将没有会话可以进行身份​​验证。

结果页 (Result Pages)

login.jsp

login.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<%-- Using Struts2 Tags in JSP --%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Login Page</title>
</head>
<body>
<h3>Welcome User, please login below</h3>
<s:form action="login">
	<s:textfield name="user" label="User Name"></s:textfield>
	<s:textfield name="password" label="Password" type="password"></s:textfield>
	<s:submit value="Login"></s:submit>
</s:form>
</body>
</html>

welcome.jsp

welcome.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Welcome Page</title>
</head>
<body>
<h3>Welcome <s:property value="userName"></s:property></h3>
</body>
</html>

JSP result pages are easy to understand and nothing related to interceptors.

JSP结果页面易于理解,与拦截器无关。

型号类别 (Model Class)

User.java

User.java

package com.journaldev.struts2.models;

public class User {

	private String user;
	private String password;
	private String userName;
	public String getUser() {
		return user;
	}
	public void setUser(String user) {
		this.user = user;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	
}

A simple java bean with properties that are used in result pages. We will use this java bean in action class to hold properties.

一个简单的Java Bean,具有在结果页中使用的属性。 我们将在动作类中使用此java bean来保存属性。

定制拦截器 (Custom Interceptor)

UserAware.java

UserAware.java

package com.journaldev.struts2.interceptors;

import com.journaldev.struts2.models.User;


public interface UserAware {

	public void setUser(User user);
}

An interface similar to Struts 2 API *Aware interface, we will use it in our custom interceptor to inject values in action class. To learn more about Struts 2 API *Aware interface, please read:

与Struts 2 API * Aware接口类似的接口,我们将在自定义拦截器中使用它来将值注入操作类。 要了解有关Struts 2 API * Aware接口的更多信息,请阅读:

How to get Servlet Session, Request, Response, Context Attributes in Struts 2 Action

如何在Struts 2操作中获取Servlet会话,请求,响应,上下文属性

AuthenticationInterceptor.java

AuthenticationInterceptor.java

package com.journaldev.struts2.interceptors;

import java.util.Map;

import com.journaldev.struts2.models.User;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class AuthenticationInterceptor implements Interceptor {

	private static final long serialVersionUID = -5011962009065225959L;

	@Override
	public void destroy() {
		//release resources here
	}

	@Override
	public void init() {
		// create resources here
	}

	@Override
	public String intercept(ActionInvocation actionInvocation)
			throws Exception {
		System.out.println("inside auth interceptor");
		Map<String, Object> sessionAttributes = actionInvocation.getInvocationContext().getSession();
		
		User user = (User) sessionAttributes.get("USER");
		
		if(user == null){
			return Action.LOGIN;
		}else{
			Action action = (Action) actionInvocation.getAction();
			if(action instanceof UserAware){
				((UserAware) action).setUser(user);
			}
			return actionInvocation.invoke();
		}
	}

}

This is our custom interceptor class that is implementing com.opensymphony.xwork2.interceptor.Interceptor interface. init() and destroy() are interceptor lifecycle methods that we can implement to initialize and destroy some resources used in interceptor intercept() method.

这是实现com.opensymphony.xwork2.interceptor.Interceptor接口的自定义拦截器类。 init()和destroy()是拦截器生命周期方法,我们可以实现这些方法来初始化和销毁​​拦截器intercept()方法中使用的某些资源。

intercept() is the method invoked by ActionInvocation class, so this is where our interceptor code goes. We can get session attributes from ActionInvocation reference and use it to make sure session is valid. If we don’t find the attribute, we are returning global result “login” that will redirect user to login page. If session is valid, then we are injecting user into action class. instanceof keyword is used to make sure that action class is implementing UserAware interface. Finally we are calling ActionInvocation invoke() method that will call the next interceptor or action class in the chain.

Intercept()是ActionInvocation类调用的方法,因此这就是我们的拦截器代码所在的位置。 我们可以从ActionInvocation参考获取会话属性,并使用它来确保会话有效。 如果找不到该属性,则将返回全局结果“登录”,该结果会将用户重定向到登录页面。 如果会话有效,那么我们会将用户注入到动作类中。 instanceof关键字用于确保操作类正在实现UserAware接口。 最后,我们调用ActionInvocation invoke()方法,该方法将调用链中的下一个拦截器或操作类。

动作班 (Action Classes)

LoginAction.java

LoginAction.java

package com.journaldev.struts2.actions;

import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.journaldev.struts2.models.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class LoginAction extends ActionSupport implements SessionAware, ModelDriven<User>{

	private static final long serialVersionUID = -3369875299120377549L;

	@Override
	public String execute(){
		System.out.println("inside execute");
		if("pankaj".equals(user.getUser()) && "admin".equals(user.getPassword())){
			user.setUserName("Pankaj Kumar");
			sessionAttributes.put("USER", user);
			return SUCCESS;
		}
		return INPUT;
	}
	
	private User user = new User();
	private Map<String, Object> sessionAttributes = null;

	@Override
	public void setSession(Map<String, Object> sessionAttributes) {
		this.sessionAttributes = sessionAttributes;
	}
	
	@Override
	public User getModel() {
		return user;
	}
	
}

Notice that LoginAction is implementing SessionAware interface to get session attributes and if user is validated, then putting user attribute in session to be used in authentication interceptor for validation. Notice that LoginAction is not implementing UserAware interface.

请注意,LoginAction正在实现SessionAware接口以获取会话属性,并且如果验证了用户,则将用户属性放在会话中以在身份验证拦截器中用于验证。 请注意,LoginAction没有实现UserAware接口。

WelcomeAction.java

WelcomeAction.java

package com.journaldev.struts2.actions;

import com.journaldev.struts2.interceptors.UserAware;
import com.journaldev.struts2.models.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class WelcomeAction extends ActionSupport implements UserAware, ModelDriven<User> {

	private static final long serialVersionUID = 8111120314704779336L;

	@Override
	public String execute(){
		return SUCCESS;
	}
	
	private User user;
	@Override
	public void setUser(User user) {
		this.user=user;
	}
	
	public User getUser(User user){
		return this.user;
	}

	@Override
	public User getModel() {
		return this.user;
	}

}

Notice that WelcomeAction is implementing UserAware interface and our AuthenticationInterceptor is injecting it to the action class behind the scene. Notice that action class is simple and there is no code for validating the user session or to set the user bean.

注意,WelcomeAction正在实现UserAware接口,我们的AuthenticationInterceptor将其注入到幕后的action类中。 请注意,动作类很简单,没有用于验证用户会话或设置用户Bean的代码。

From above action classes code, it’s clear that if we use interceptors smartly, we can reduce a lot of code redundancy for common tasks that we need to do for multiple actions.

从上面的动作类代码中可以清楚地看出,如果我们聪明地使用拦截器,我们可以减少执行多个动作所需的常见任务的大量代码冗余。

When we execute above project, we get following response pages.

当我们执行以上项目时,我们得到以下响应页面。

If you are not logged in and you will try to invoke login.action, our authentication interceptor will forward you to login page and action class will never be invoked.

如果您尚未登录,并且尝试调用login.action,则我们的身份验证拦截器会将您转发到登录页面,并且永远不会调用action类。

That’s all for Struts 2 interceptors tutorial, it’s one of the important features of Struts 2 and you should try to use it for reusability.

这就是Struts 2拦截器教程的全部内容,这是Struts 2的重要功能之一,您应该尝试将其用于可重用性。

翻译自: https://www.journaldev.com/2210/struts-2-interceptor-example

struts2 拦截器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值