如何在Struts 2操作中获取Servlet会话,请求,响应,上下文属性
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。