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

时间:2020-02-23 14:36:14  来源:igfitidea点击:

Struts 2 Action类没有提供任何获取Servlet API请求,响应,会话和属性的方法。
但是有时我们需要在操作类中访问它们,例如检查HTTP方法或者使用会话属性或者设置cookie或者标头作为响应。

因此,Struts 2 API提供了很多接口,我们可以在操作类中实现这些接口,以将这些对象注入到操作类中。
所有这些接口均以" Aware"结尾,并在" org.apache.struts2.interceptor"包中进行了定义。

所有这些接口都声明了setter方法,Struts 2 API通过这些方法将Action类中的Servlet API组件注入。
这是Java EE框架中依赖注入的一个很好的例子。

这些* Aware接口为:

  • SessionAware:此接口提供对操作类中的会话属性的访问,并声明单个方法setSession(Map <String,Object> sessionAttributes)
    请注意,我们无法通过实现此接口来获取HttpSession,这仅仅是为了访问会话属性。

  • ApplicationAware:此接口提供对操作类中的上下文属性(如Map)的访问。
    我们可以通过将值放在上下文映射中来向应用程序上下文添加属性。
    该接口声明单个方法setApplication(Map <String,Object> applicationAttributes)

  • RequestAware:此接口提供对操作类中的请求属性的访问,它包含单个方法setRequest(Map <String,Object> requestAttr)
    仅当在Servlet环境中使用Action类时,此接口才适用。
    由于此接口将Action绑定到servlet环境,因此应尽可能避免这样做,因为单元测试之类的事情将变得更加困难。

  • ServletRequestAware:我们可以在操作类中实现此接口,以访问HttpServletRequest对象。
    仅当在Servlet环境中使用Action时,此接口才有意义。
    它定义了一个单一方法为" setServletRequest(HttpServletRequest request)"。

  • ServletResponseAware:Struts 2动作类可以实现此接口来访问HttpServletResponse对象。
    然后,我们可以使用响应对象添加标题或者cookie。
    它将单个方法定义为" setServletResponse(HttpServletResponse response)"。

  • CookiesAware:此接口旨在以请求的形式提供对Map形式的cookie的访问。
    它包含单个方法setCookiesMap(Map <String,String> cookies)
    要使用此接口,struts-default软件包中定义了两个拦截器,它们是:
    但是它们不是defaultStack拦截器堆栈的一部分,因此我们需要将它们包括在动作类中,如下所示。

但是这些拦截器是非常新的,在我对Struts 2版本2.3.15.1的测试中,我发现它没有起作用。
我查看了Struts 2 API文档,但没有找到任何帮助。
如果我发现任何问题,或者如果您知道缺少什么,我将更新该帖子,请通过注释告知我们。
解决方法是使用ServletRequestAware和ServletResponseAware接口获取请求cookie或者设置cookie作为响应。

  • PrincipalAware:我们可以在操作类中实现此接口,以从HttpServletRequest对象获取Principal信息。
    该接口与PrincipalProxy一起使用以提供用户ID和主体详细信息。

让我们看看一个简单的Struts 2项目中所有这些接口的实际作用。
我们的最终项目结构如下图所示。

Struts2配置文件

web.xml

<interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"
<interceptor name="cookieProvider" class="org.apache.struts2.interceptor.CookieProviderInterceptor"

pom.xml

<action name="home" class="com.theitroad.struts2.actions.HomeAction">
	<interceptor-ref name="cookie"></interceptor-ref>
	<interceptor-ref name="cookieProvider"></interceptor-ref>
	<interceptor-ref name="defaultStack"></interceptor-ref>
	<result name="success">/home.jsp</result>
</action>

struts.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>Struts2Example</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>

配置文件不言自明,易于理解。

Struts2 JSP页面

login.jsp

<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>Struts2Example</groupId>
	<artifactId>Struts2Example</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>

home.jsp

<?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">
		<action name="login">
			<result>/login.jsp</result>
		</action>
		<action name="home" class="com.theitroad.struts2.actions.HomeAction">
			<interceptor-ref name="cookie"></interceptor-ref>
			<interceptor-ref name="cookieProvider"></interceptor-ref>
			<interceptor-ref name="defaultStack"></interceptor-ref>
			<result name="success">/home.jsp</result>
		</action>

	</package>

</struts>

JSP页面也非常简单,仅用于在请求中发送一些数据,然后在结果页面中使用它们。

Struts2动作类

HomeAction.java

<%@ 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>Login Page</title>
</head>
<body>
<s:form action="home" method="post">
<s:textfield label="User Name" name="user"></s:textfield>
<s:textfield label="Password" name="password"></s:textfield>
<s:submit label="Login"></s:submit>
</s:form>
</body>
</html>

一个动作类,用于实现所有* Aware接口并使用它们在服务器日志文件中记录一些数据。

一旦执行了登录操作,然后多次击中主页操作,我们就会获得以下日志。

<%@ 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>Home Page</title>
</head>
<body>
<h3>Welcome <s:property value="user"</h3>
</body>
</html>

请注意,请求cookie为NULL,但是我在浏览器中检查了请求和响应,并且它在请求中发送了cookie。