- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Struts2 ActionContext 中的数据详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
ActionContext 。
ActionContext是Action的上下文,Struts2自动在其中保存了一些在Action执行过程中所需的对象,比如session, parameters, locale等。Struts2会根据每个执行HTTP请求的线程来创建对应的ActionContext,即一个线程有一个唯一的ActionContext。因此,使用者可以使用静态方法ActionContext.getContext()来获取当前线程的ActionContext,也正是由于这个原因,使用者不用去操心让Action是线程安全的.
无论如何,ActionContext都是用来存放数据的。Struts2本身会在其中放入不少数据,而使用者也可以放入自己想要的数据。ActionContext本身的数据结构是映射结构,即一个Map,用key来映射value。所以使用者完全可以像使用Map一样来使用它,或者直接使用Action.getContextMap()方法来对Map进行操作.
Struts2本身在其中放入的数据有ActionInvocation、application(即ServletContext)、conversionErrors、Locale、action的name、request的参数、HTTP的Session以及值栈等。完整的列表请参考它的Javadoc(本文附录有对它包含内容的讨论).
由于ActionContext的线程唯一和静态方法就能获得的特性,使得在非Action类中可以直接获得它,而不需要等待Action传入或注入。需要注意的是,它仅在由于request而创建的线程中有效(因为request时才创建对应的ActionContext),而在服务器启动的线程中(比如fliter的init方法)无效。由于在非Action类中访问其的方便性,ActionContext也可以用来在非Action类中向JSP传递数据(因为JSP也能很方便的访问它).
ValueStack与ActionContext的联系和区别:
相同点:它们都是在一次HTTP请求的范围内使用的,即它们的生命周期都是一次请求。 不同点:值栈是栈的结构,ActionContext是映射(Map)的结构。 联系:ValueStack.getContext()方法得到的Map其实就是ActionContext的Map。查看Struts2的源代码可知(Struts2.3.1.2的org.apache.struts2.dispatcher.ng.PrepareOperations的第79行,createActionContext方法),在创建ActionContext时,就是把ValueStack.getContext()作为ActionContext的构造函数的参数。所以,ValueStack和ActionContext本质上可以互相获得。 注意:在一些文档中,会出现把对象存入“stack's context”的字样,其实就是把值存入了ActionContext。所以在阅读这些文档时,要看清楚,到底是放入了栈结构(即值栈),还是映射结构(值栈的context,即ActionContext).
如何获得ActionContext:
在自定义的拦截器中:使用ActionInvocation.getInvocationContext()或者使用ActionContext.getContext()。 在Action类中:让拦截器注入或者使用ActionContext.getContext()。 在非Action类中:让Action类传递参数、使用注入机制注入或者使用ActionContext.getContext()。注意:只有运行在request线程中的代码才能调用ActionContext.getContext(),否则返回的是null。 在JSP中:一般不需要获得ActionContext本身.
如何向ActionContext中存入值:
在拦截器、Action类、非Action类等Java类中:使用ActionContext.put(Object key, Object value)方法。 在JSP中:标签<s:set value="..."/>默认将值存入ActionContext中(当然,<s:set>标签还可以把值存到其他地方)。另外,许多标签都有var属性(以前用的是id属性,现在id属性已被弃用),这个属性能向ActionContext存入值,key为var属性的值,value为标签的value属性的值。(有些文档写的是向ValueStack的context存入值,其实是一样的) 。
如何从ActionContext中读取值:
在拦截器、Action类、非Action类等Java类中:使用ActionContext.get(Object key)方法。 在JSP中:使用#开头的Ognl表达式,比如<s:property value="#name"/>会调用ActionContext.get("name")方法。注意:如果某标签的属性默认不作为Ognl表达式解析,则需要使用%{}把表达式括起来,于是就会出现类似“%{#name}的表达式”。(“#”的更多用途参见这里) 。
总之,在JSP中使用ActionContext一方面是由于它是映射结构,另一方面是能读取Action的一些配置。当你需要为许多Action提供通用的值的话,可以让每个Action都提供getXXX()方法,但更好的方法是在拦截器或JSP模板中把这些通用的值存放到ActionContext中(因为拦截器或JSP模板往往通用于多个Action)。 一些例子:
Java代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 本类将演示拦截器中对ActionContext的操作
publicclass MyInterceptor
extends
AbstractInterceptor {
public
String intercept(ActionInvocation invocation)
throws
Exception {
// 获得ActionContext
ActionContext actionContext = invocation.getInvocationContext();
// 存入值
Person person =
new
Person();
actionContext.put(
"person"
, person);
// 获取值
Object value = actionContext.get(
"person"
);
// 获取HttpServletRequest
HttpServletRequest request = (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);
// 获取request的Map,即HttpServletRequest.getAttribute(...)和HttpServletRequest.setAttribute(...)所操作的值
Map requestMap = (Map) actionContext.get(
"request"
);
// 其他代码
// ......
return
invocation.invoke();
}
}
|
Java代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// 本类将演示在Action中对ActionContext进行操作
publicclass MyAction
extends
ActionSupport {
@Override
public
String execute()
throws
Exception {
// 获得值栈
ActionContext actionContext = ActionContext.getContext();
// 存入值
Person person =
new
Person();
// 这是之前例子中定义的类
actionContext.put(
"person"
, person);
// 获取值
Object object = actionContext.get(
"person"
);
// 其他代码
// ......
return
SUCCESS;
}
}
|
Html代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<!DOCTYPE html>
<
html
>
<
head
>
<
metahttp-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
>
<
title
>JSP Page</
title
>
</
head
>
<
body
>
<!-- 本JSP将演示在JSP中对ActionContext的使用 -->
<!-- 本JSP为MyAction对应的JSP -->
<!-- 由于Action中已经向ActionContext存入了key为"person"的值,所以可以使用“#person”来获取它,如下 -->
<
s:propertyvalue
=
"#person"
/>
<!-- 获得person的name属性,如下 -->
<
s:propertyvalue
=
"#person.name"
/>
<!-- 获得Struts2在ActionContext中存入的值,比如request的Map,如下 -->
<
s:propertyvalue
=
"#request"
/>
<!-- 获得Struts2在ActionContext中存入的值,比如session的Map,如下 -->
<
s:propertyvalue
=
"#session"
/>
<!-- 获得Struts2在ActionContext中存入的值,request请求传递的GET参数或POST参数的Map,如下 -->
<
s:propertyvalue
=
"#parameters"
/>
<!-- 以下演示在JSP中把值存入ActionContext中 -->
<!-- 存入一个字符串"myName",key为"myKey",如下 -->
<
s:setvalue
=
"%{'myName'}"
var
=
"myKey"
/>
<!-- 使用s:bean标签来创建一个对象,并把它存入ActionContext中,key为myObject,如下 -->
<
s:beanname
=
"com.example.Person"
var
=
"myObject"
/>
<!-- 之后就可以用“#”来读取它们,如下 -->
<
s:propertyvalue
=
"#myKey"
/>
<
s:propertyvalue
=
"#myObject"
/>
</
body
>
</
html
>
|
3. HttpServletRequest类或request的Map Struts2中提供了两种对request的操作:一种是Web服务器提供的HttpServletRequest类,这和传统Java Web项目中的操作request的方式相同;另一种是一个“request的Map”,即封装了HttpServletRequest的attributes的映射类,操作该Map相当于操作HttpServletRequest的attributes。之所以提供了Map的操作方式,一是方便操作,二是能方便使用Ognl在JSP标签中读取request。无论如何,这两个request是互通的。至于request的生命周期等概念,与其他的Java Web项目没有区别,本文不再详述.
使用HttpServletRequest类还是request的Map 。
虽然两者是互通的,但就读取request的attributes而言,使用request的Map要方便许多,并且不会暴露不必要的接口。当然,HttpServletRequest有一些request的Map没有的方法,使用这些方法时当然还是要用前者.
使用request的Map还是ActionContext:
两者都是Map,两者的生命周期都是一个请求。 传统的Java Web项目中,往往是通过request的attributes来向JSP传递值的:先在Servlet里setAttribute(),然后在JSP里getAttribute()。当然在Struts2的项目中,你仍然可以使用这个方法,然而抛弃了Struts2提供的传递功能是得不偿失的。虽然笔者没有找到官方文档说一定要用ActionContext替换request的Map,也没有发现程序中有能获得ActionContext却获得不了request的Map的地方,但在Struts2框架下,操作ActionContext要比操作request的Map更加方便。因此,笔者建议:尽量使用ActionContext而不是request的Map来传递值。 request的Map有时候会包含其他框架设置的值,比如Spring框架。获取这些值的时候就需要用request的Map了,因为ActionContext里没有。 通过ActionContext可以获得HttpServletRequest类:“HttpServletRequest request = (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);”。 通过ActionContext也可以获得request的Map:“Map requestMap = (Map) actionContext.get("request");”。因此,在JSP标签中,使用表达式“#request”就可以获得request的Map的数据.
如何获得HttpServletRequest:
如果已经有ActionContext,则使用“actionContext.get(StrutsStatics.HTTP_REQUEST)”来获得HttpServletRequest。 在自定义的拦截器中,先获得ActionContext,再通过ActionContext来获得。 在Action中,先获得ActionContext,再通过ActionContext来获得。或者让Action实现ServletRequestAware接口,并使用ServletConfigInterceptor拦截器,这样这个拦截器就会注入HttpServletRequest。 在JSP中,一般不需要获得HttpServletRequest.
如何获得request的Map:
如果已经有ActionContext,则使用“actionContext.get("request")”来获得。 在自定义的拦截器中,先获得 ActionContext,再通过ActionContext来获得。 在Action中,先获得ActionContext,再通过ActionContext来获得。或者让Action实现RequestAware接口,并使用ServletConfigInterceptor拦截器,这样这个拦截器就会注入Map request。 在JSP中,用“#request”来获得request的Map,用“#request.key”或者“#request['key']”来读取Map中的值.
总之,request仍然符合Java Web网站的一般规律。不过笔者建议使用者应尽量避免用request传值.
一些例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 本类将演示拦截器中对HttpServletRequest和request的Map的操作
publicclass MyInterceptor
extends
AbstractInterceptor {
public
String intercept(ActionInvocation invocation)
throws
Exception {
// 获得ActionContext
ActionContext actionContext = invocation.getInvocationContext();
// 获得HttpServletRequest
HttpServletRequest httpServletRequest=(HttpServletRequest)actionContext.get(StrutsStatics.HTTP_REQUEST);
// 获得request的Map
Map requestMap = (Map) actionContext.get(
"request"
);
// 创建一个类作为实例
Person person =
new
Person();
// 以下两行的语句作用相同
httpServletRequest.setAttribute(
"person"
, person);
requestMap.put(
"person"
, person);
// 其他代码
// ......
return
invocation.invoke();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 本类将演示在Action中对HttpServletRequest和request的Map进行操作(静态方法获得ActionContext)
publicclass MyAction
extends
ActionSupport {
@Override
public
String execute()
throws
Exception {
// 获得ActionContext
ActionContext actionContext = ActionContext.getContext();
// 获得HttpServletRequest
HttpServletRequest httpServletRequest=(HttpServletRequest)actionContext.get(StrutsStatics.HTTP_REQUEST);
// 获得request的Map
Map requestMap = (Map) actionContext.get(
"request"
);
// 创建一个类作为实例
Person person =
new
Person();
// 以下两行的语句作用相同
httpServletRequest.setAttribute(
"person"
, person);
requestMap.put(
"person"
, person);
// 其他代码
// ......
return
SUCCESS;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// 本类将演示在Action中使用ServletRequestAware获得HttpServletRequest(注意:要使用ServletConfigInterceptor拦截器)
publicclass MyAction
extends
ActionSupport
implements
ServletRequestAware {
private
HttpServletRequest request;
//此方法是接口ServletRequestAware的方法
publicvoid setServletRequest(HttpServletRequest request) {
this
.request = request;
}
@Override
public
String execute()
throws
Exception {
// HttpServletRequest已在该类的字段中准备好,可直接使用
// ......
return
SUCCESS;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// 本类将演示在Action中使用ServletRequestAware获得request的Map(注意:要使用ServletConfigInterceptor拦截器)
publicclass MyAction
extends
ActionSupport
implements
RequestAware {
Map<String, Object> request;
// 该方法是接口RequestAware的方法
publicvoid setRequest(Map<String, Object> request) {
this
.request = request;
}
@Override
public
String execute()
throws
Exception {
// request的Map已在该类的字段中准备好,可直接使用
// ......
return
SUCCESS;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<title>JSP Page</title>
</head>
<body>
<!-- 本JSP将演示在JSP中对request的Map的使用 -->
<!-- 本JSP为MyAction对应的JSP -->
<!-- request的Map是Struts2自动在ActionContext中存入的值(key为request),所以使用“#”来访问ActionContext,从中读取request -->
<s:property value=
"#request"
/>
<!-- 以下两行均是访问request的Map中key为“name”的值 -->
<s:property value=
"#request.name"
/>
<s:property value=
"#request['name']"
/>
</body>
</html>
|
3. Parameters,即GET请求或POST请求的参数 。
Parameters为GET或POST等请求时浏览器向服务器传递而来的参数。在传统的Java Web项目中,使用HttpServletRequest.getParameter()等方法来获取参数,并且可以直接使用HttpServletRequest.getParameterMap()来获得一个封装了参数的Map。而在Struts2中,Struts2直接把上述Map存放到了ActionContext中,key为“parameters”。另外,ActionContext还直接提供了ActionContext.getParameters()方法来获得这个Map。因此,在Struts2的各个部件中操作parameters的方法和操作request的Map的方法十分相似,本段不再详述.
4. HttpServletSession类和session的Map 。
传统Java Web项目中的session是我们都熟悉的,我们用它来记录一个用户的会话状态。Struts2把HttpServletSession封装到了一个Map中,即“session的Map”,这类似对request的处理。然而为了节省系统资源,我们在不需要session的时候不会创建session。可能正是因为这个缘故,Struts2中没有把HttpServletSession放入ActionContext中,如果你的程序需要使用HttpServletSession,应该先获得HttpServletRequest,然后使用getSession()或getSession(boolean b)来获得它,同时决定是否需要创建session。对于session的Map,Struts2仍然把它放入了ActionContext中(key为"session"),但是不要担心,这个Map的机制使得只有put新值时才会创建session。总之,Struts2中对HttpServletSession的操作要先通过HttpServletRequest来获得它,而对session的Map的操作与对request的Map的操作如出一辙,本段不再详述.
5. ServletContext和application的Map 。
传统的Java Web项目中,ServletContext用来存放全局变量,每个Java虚拟机每个Web项目只有一个ServletContext。这个ServletContext是由Web服务器创建的,来保证它的唯一性。ServletContext有一些方法能操作它的attributes,这些操作方法和操作一个Map类似。于是,Struts2又来封装了:它把ServletContext的attributes封装到了一个Map中,即“application的Map”,并且也放入的ActionContext中(key为application),因此,对application的Map的操作就如果对request的Map操作,本段不再详述。 至于对ServletContext的操作,与HttpServletRequest的操作类似:Struts2将ServletContext放到了 ActionContext中,并且ServletConfigInterceptor提供了对ServletContext的注入接口ServletContextAware。因此,本段不再详述。 注意:在Ognl表达式中使用“#application”可以得到application的Map,而不是ServletContext。然而在JSP嵌入的Java代码中(比如“<% application.getAttribute(""); %>”),application为ServletContext,而不是Map.
最后此篇关于Struts2 ActionContext 中的数据详解的文章就讲到这里了,如果你想了解更多关于Struts2 ActionContext 中的数据详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
ActionContext ActionContext是Action的上下文,Struts2自动在其中保存了一些在Action执行过程中所需的对象,比如ses
我的问题是: 在Struts2中,每个action对象都有自己对应的ActionContext和ValueStack吗? 换句话说,对于每个新请求,都会创建一个新的操作对象。这是否意味着每次创建新的操
最近我将 struts2 版本从 2.0.11 更新到了当前的 2.2.3。不幸的是,我现在遇到了一些奇怪的问题,到目前为止我还无法解决。 当我尝试获取 ActionContext 时: Action
我有一个关于 struts2 链接操作的非常复杂的问题,提前感谢您耐心阅读我的问题。我会尽力描述清楚。 下面是我的struts.xml:
我正在尝试在 Struts2 中编写一个拦截器,它根据某些条件将请求重定向到不同的操作。我的拦截器工作正常,如下所示。 public String intercept(ActionInvocati
Struts ActionContext 在测试期间为 null。 使用 Struts2 JUnit 插件我进行了以下测试: public class MainActionIT extends Str
我查了很久这个资料,网上好像没有很多。 为简单起见,我们如何访问 ActionContext通过标签? 基本上我想得到 com.opensymphony.xwork2.ActionContext.lo
我在struts2中使用SessionAware,但是当我获取session的值时它返回null。我的 Action 类和方法是- public class CustomLocation extend
背景: 我想使用通过 Ninject 注入(inject)的 IAuthenticationFilter 实现来验证对我的 Web API 的 POST 请求。要验证请求,我需要访问请求正文。 问题:
我正在使用 cucumber-jvm 在一个以 Struts 2 和 Tomcat 作为我的 Servlet 容器的应用程序上编写验收测试(测试行为)。在我的代码中的某个时刻,我需要从 Struts
在此代码中,我使用 ActionContext 从 Request 对象获取 Session 和 ServletActionContext。我觉得这是一种不好的做法,因为必须仅将 ActionCont
我正在调整 http://displaytag.svn.sourceforge.net/viewvc/displaytag/trunk/displaytag/src/main/java/org/dis
阅读了通过 ActionContext.getContext().getSession() 获取 session 映射与通过注入(inject) session 映射之间的差异之后SessionAwa
我需要设置一个 ServletRequest Struts2 拦截器(不是操作类)中的属性。 ActionContext暴露一个Map控制请求属性,就像它对 session 属性所做的那样? 我看到
我正在通过 maven 运行 JUnit 测试,其中正在测试进行以下调用的 struts 操作 java 方法: // Gets this from the "org.apache.struts2.u
我正在尝试模拟这个 Controller : public IActionResult List() { Response.Headers.Add("contentRange"
我目前正在这样做,但如果找不到 key ,它会抛出异常。 此代码段位于从 ActionFilterAttribute 继承的 Web API 过滤器中,在覆盖方法 OnActionExecuting
我在 Microsoft.AspNetCore.Mvc.Controller 中找不到 ActionContext 在我将我的版本更改为 AspNetCore 1.0.0-preview1 之后 这是
我在 IActionContextAccessor 使用 asp.net core 的内置 DI 容器时遇到一些问题。 IActionContextAccessor.ActionContext 属性在
我需要知道如何创建自定义 IModelBinder在 MVC 4 中,它已被更改。 必须实现的新方法是: bool BindModel(HttpActionContext actionContext,
我是一名优秀的程序员,十分优秀!