Actspringsessioncontextt.getContext().getSession(),里面的session会在手机浏览器使用过程丢失

上下文(context)ActionContext介绍(在Struts2中) -
- ITeye技术网站
一种属性的有序序列,它们为驻留在环境内的对象定义环境。在对象的激活过程中创建上下文,对象被配置为要求某些自动服务,如同步、事务、实时激活、安全性等等。多个对象可以存留在一个上下文内。也有根据上下文理解意思的意思。
介绍(在中)
在Web应用程序开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话 (Session)的一些信息, 甚至需要直接对JavaServlet Http的请求(HttpServletRequest),响应(HttpServletResponse)操作.
我们需要在Action中取得request请求参数"username"的值:
ActionContext context = ActionContext.getContext();
Map params = context.getParameters();
String username = (String) params.get("username");
ActionContext(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放放的是Action在执行时需要用到的对象
一般情况,我们的ActionContext都是通过:ActionContext context = (ActionContext) actionContext.get();来获取的.我们再来看看这里的actionContext对象的创建:
static ThreadLocal actionContext = new ActionContextThreadLocal();,
ActionContextThreadLocal是实现ThreadLocal的一个内部类.ThreadLocal可以命名为"线程局部变量",它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本, 而不会和其它线程的副本冲突.这样,我们ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的.
下面我们看看怎么通过ActionContext取得我们的HttpSession:
Map session = ActionContext.getContext().getSession();
ServletActionContext(com.opensymphony.webwork. ServletActionContext),这个类直接继承了我们上面介绍的ActionContext,它提供了直接与JavaServlet相关对象访问的功能,它可以取得的对象有:
1, javax.servlet.http.HttpServletRequest:HTTPservlet请求对象
2, javax.servlet.http.HttpServletR:HTTPservlet相应对象
3, javax.servlet.ServletContext:Servlet 上下文信息
4, javax.servlet.ServletConfig:Servlet配置对象
5, javax.servlet.jsp.PageContext:Http页面上下文
下面我们看看几个简单的例子,让我们了解如何从ServletActionContext里取得JavaServlet的相关对象:
1, 取得HttpServletRequest对象:
HttpServletRequest request = ServletActionContext. getRequest();
2, 取得HttpSession对象:
HttpSession session = ServletActionContext. getRequest().getSession();
ServletActionContext 和ActionContext有着一些重复的功能,在我们的Action中,该如何去抉择呢?我们遵循的原则是:如果ActionContext能够实现我们的功能,那最好就不要使用ServletActionContext,让我们的Action尽量不要直接去访问JavaServlet的相关对象.在使用ActionContext时有一点要注意:不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许没有设置,这时通过ActionContext取得的值也许是null.
如果我要取得Servlet API中的一些对象,如request,response或session等,应该怎么做?在Strutx 2.0你可以有两种方式获得这些对象:非IoC(控制反转Inversion of Control)方式和IoC方式.
A、非IoC方式
 要获得上述对象,关键Struts 2.0中com.opensymphony.xwork2.ActionContext类.我们可以通过它的静态方法getContext()获取当前 Action的上下文对象. 另外,org.apache.struts2.ServletActionContext作为辅助类(Helper Class),可以帮助您快捷地获得这几个对象.
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
B、IoC方式
要使用IoC方式,我们首先要告诉IoC容器(Container)想取得某个对象的意愿,通过实现相应的接口做到这点.具体实现,请参考例6 IocServlet.java.
例6 classes/tutorial/NonIoCServlet.java
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpS
import org.apache.struts2.ServletActionC
import com.opensymphony.xwork2.ActionC
import com.opensymphony.xwork2.ActionS
Public class NonIoCServlet extends ActionSupport {
public String getMessage() {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
public String execute() {
sb.append(request.getParameter("msg"));
sb.append("&br&Response Buffer Size: ");
sb.append(response.getBufferSize());
sb.append("&br&Session ID: ");
sb.append(session.getId());
message = sb.toString();
//转换为字符串。
return SUCCESS;
//与LoginAction类似的方法。
例6 classes/tutorial/IoCServlet.java
import java.util.M
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpS
import org.apache.struts2.interceptor.ServletRequestA
import org.apache.struts2.interceptor.ServletResponseA
import org.apache.struts2.interceptor.SessionA
import com.opensymphony.xwork2.ActionC
import com.opensymphony.xwork2.ActionS
publicclass IoCServlet extends ActionSupport implements SessionAware,
ServletRequestAware, ServletResponseAware {
private HttpServletR
private HttpServletR
this.att =
publicvoid setServletRequest(HttpServletRequest request) {
this.request =
publicvoid setServletResponse(HttpServletResponse response) {
this.response =
public String execute() {
.put("msg", "Hello World from Session!");
HttpSession session = request.getSession();
StringBuffer sb =new StringBuffer("Message from request: ");
sb.append(request.getParameter("msg"));
sb.append("&br&Response Buffer Size: ");
sb.append(response.getBufferSize());
sb.append("&br&Session ID: ");
sb.append(session.getId());
message = sb.toString();
return SUCCESS;
例6 Servlet.jsp
&%@ page contentType="text/ charset=UTF-8" %&
&%@ taglib prefix="s" uri="/struts-tags"%&
&title&Hello World!&/title&
&s:property value="message" escape="false"/&
&br&Message from session: &s:property value="#session.msg"/&
例6 classes/struts.xml中NonIocServlet和IoCServlet Action的配置
&action name="NonIoCServlet" class="tutorial.NonIoCServlet"&
&result&/Servlet.jsp&/result&
&action name="IoCServlet" class="tutorial.IoCServlet"&
&result&/Servlet.jsp&/result&
 运行Tomcat,在浏览器地址栏中键入http://localhost:8080/Struts2_Action /NonIoCServlet.action?msg=Hello%20World! 或http://localhost:8080/Struts2_Action/IoCServlet.action?msg=Hello%20World!
 在Servlet.jsp中,我用了两次property标志,第一次将escape设为false为了在JSP中输出&br&转行,第二次的value中的OGNL为"#session.msg",它的作用与session.getAttribute("msg")等同.
附:ActionContext的常用方法(来自Struts2.0
getContext()
getSession()
类的常用方法
//该方法主要用于验证的方法之中
fieldName,
errorMessage)
方法的来源,见后面补充的常用方法:
常用于校验登陆程序的账号和密码是否为空,可以加入方法。例如public void validate() {
if (null == login.getUserID() || "".equals(login.getUserID())) {
this.addFieldError("login.userID", "学号不能为空");
if (null == login.getUserPassword()
|| "".equals(login.getUserPassword())) {
this.addFieldError("login.userPassword", "密码不能为空");
浏览 20358
清晨迎朝阳
浏览: 42269 次
来自: 杭州
protected static void cleanUp(S ...
有点迷惑。是不是每个请求都需要经过 ActionContext ...struts2 action里ActionContext.getContext().getSession() 报空错误_读书人
struts2 action里ActionContext.getContext().getSession() 报空错误
&来源:读书人网&【读书人网():综合教育门户网站】
struts2 action里ActionContext.getContext().getSession() 报空异常点击右边红色标题查看本文完整版:stru
struts2 action里ActionContext.getContext().getSession() 报空异常 点击右边红色标题查看本文完整版:struts2 action里ActionContext.getContext().getSession() 报空异常在struts2action里ActionContext.getContext().getSession() 总是报空异常 ------解决方法--------------------ActionContext ac = ActionContext.getContext(); ac.getSession(); ------解决方法--------------------ServletActionContext.getRequest().getSession();    114网址导航小女子想向各位请教个问题,关于& request.getSession(). - ITeye问答
小女子想向各位请教个问题
&& public List&ServiceMVO& getServiceList(HttpServletRequest request) {
&&&&&&& List&ServiceMVO& serviceAList = new ArrayList&ServiceMVO&();
&&&&&&& serviceAList = (List&ServiceMVO&) request.getSession().getAttribute(
&&&&&&&&&&&&&&& "serviceList");
&&&&&&& if (serviceAList == null) {
&&&&&&&&&&& try {
&&&&&&&&&& //从数据库中取得数据list
&&&&&&&&&&&&&&& serviceAList = shiryouInputService.getTblServiceMByMobile();
&&&&&&&&&&& } catch (SQLException e) {
&&&&&&&&&&&&&&& // TODO Auto-generated catch block
&&&&&&&&&&&&&&& e.printStackTrace();
&&&&&&&&&&& }
&&&&& //把从数据库中取得数据list放到session里去&
&&&&&&&&&&& request.getSession().setAttribute("serviceList", serviceAList);
&&&&&&& }
&&&&&&& return serviceAL
&&& }
这个方法,我远本的意思是数据库把数据取来以后,放入session,下次访问这个方法的时候,直接去session中取这个list就好了。可是事实上上,每次,访问这个方法的时候,它都是去取一遍数据库的,当画面提交后再次访问 (List&ServiceMVOrequest.getSession().getAttribute( "serviceList")的值一直是null,各位知道这是为什么吗?
HttpServletRequest request的这个参数,在BaseAction类里通过ServletActionContext.getRequest();取得的
用的框架是struts2+spring+ibatis
问题补充:liveHappy 写道用struts2的session 放数据的时候这么用。
ActionContext.getContext().getSession().put("serviceList", serviceList);
取的时候:
ActionContext.getContext().getSession().get("serviceList");然后转型
我们框架中统一取得request 和session& 的写法是:
HttpServletRequest request = ServletActionContext.getRequest();
&&&&&&&&&&& // セッションを取得する
& Map session = ActionContext.getContext().getSession();。
这个我知道。我想问的是,为何我想上面那样写就不对呢?
因为这个页面是做手机页面开发用的,刚开始没有用框架,而是用最原始在页面上写逻辑,我只是把写在页面上的逻辑放在一个独立的类文件里了。所以才用最原始的
public String getSubmitRedirect(HttpServletRequest request,
&&&&&&&&&&& HttpServletResponse response) throws IOException {
}这种方法,页面上直接调用这个方法用。
问题补充:enet_java 写道将 request.getSession() 定义为一个session变量,然后通过session变量来set和get试试。
我刚发现一个事情,我上面所述的情况在手机模拟器里才存在这样的情况,在ie测试时候,第一次访问& public List&ServiceMVO& getServiceList(HttpServletRequest request) 这个方法时候,session里是有值的。
难道是手机是不支持session的?
问题补充:liveHappy 写道手机也应该支持的。
但是我刚debug的时候,用手机模拟器和ie分别测试了,ie页面提交,再次跳入那个方法适合,session里是有值的,而手机模拟器就没有,依然去读了数据库
问题补充:lizhi92574 写道那就是你手机模拟器出现问题了。session处理有问题
谢谢
问题补充:fxmabo 写道你代码有问题,这样改就可以了:
public List&ServiceMVO& getServiceList(HttpServletRequest request) {
List&ServiceMVO& serviceAList = new ArrayList&ServiceMVO&();
serviceAList = (List&ServiceMVO&) request.getSession().getAttribute(
"serviceList");
if (serviceAList == null) {
//从数据库中取得数据list
serviceAList = shiryouInputService.getTblServiceMByMobile();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//把从数据库中取得数据list放到session里去
request.getSession().setAttribute("serviceList", serviceAList);
return serviceAL
[color=red]request.getSession().setAttribute("serviceList", serviceAList); [/color]
为何要放外面呢?把数据库中取得的数据放session里就好了,如果进来时候
serviceAList = (List&ServiceMVO&) [color=red]request.getSession().getAttribute(
"serviceList"); [/color]
是有值的话,为何还要再进行request.getSession().setAttribute("serviceList", serviceAList);呢
问题补充:fxmabo 写道由于你一进来就将List&ServiceMVO& serviceAList = new ArrayList&ServiceMVO&();所以serviceAList 就是为空,就进不了调用数据库的方法,然后你用session取到的值也是空的。将这行代码改为List&ServiceMVO& serviceAList =就可以了
不过这个代码还存在很大问题,serviceAList = (List&ServiceMVO&) request.getSession().getAttribute(&&&
&&&&&&&&&&&&&&& "serviceList");&&&
这一行可能出现NullPointerException,一般我是这样写的:
public List&ServiceMVO& getServiceList(HttpServletRequest request) {
Session session=request.getSession();
List&ServiceMVO& serviceAList =
serviceAList =(session.getAttribute("serviceList")==null)?(new ArrayList&ServiceMVO&()):((List&ServiceMVO&)(session.getAttribute("serviceList"));
if (serviceAList == null) {
serviceAList = shiryouInputService.getTblServiceMByMobile();
} catch (SQLException e) {
e.printStackTrace();
session.setAttribute("serviceList", serviceAList);
return serviceAL
谢谢你,不管怎么样,学习了,以后我会注意的,谢谢师兄
由于你一进来就将List&ServiceMVO& serviceAList = new ArrayList&ServiceMVO&();所以serviceAList 就是为空,就进不了调用数据库的方法,然后你用session取到的值也是空的。将这行代码改为List&ServiceMVO& serviceAList =就可以了
不过这个代码还存在很大问题,serviceAList = (List&ServiceMVO&) request.getSession().getAttribute(&&&
&&&&&&&&&&&&&&& "serviceList");&&&
这一行可能出现NullPointerException,一般我是这样写的:
public List&ServiceMVO& getServiceList(HttpServletRequest request) {
Session session=request.getSession();
List&ServiceMVO& serviceAList =
serviceAList =(session.getAttribute("serviceList")==null)?(new ArrayList&ServiceMVO&()):((List&ServiceMVO&)(session.getAttribute("serviceList"));
if (serviceAList == null) {
serviceAList = shiryouInputService.getTblServiceMByMobile();
} catch (SQLException e) {
e.printStackTrace();
session.setAttribute("serviceList", serviceAList);
return serviceAL
你代码有问题,这样改就可以了:
public List&ServiceMVO& getServiceList(HttpServletRequest request) {
List&ServiceMVO& serviceAList = new ArrayList&ServiceMVO&();
serviceAList = (List&ServiceMVO&) request.getSession().getAttribute(
"serviceList");
if (serviceAList == null) {
//从数据库中取得数据list
serviceAList = shiryouInputService.getTblServiceMByMobile();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//把从数据库中取得数据list放到session里去
request.getSession().setAttribute("serviceList", serviceAList);
return serviceAL
如果实在不行你试一试这个行不行,我也没实验过,死马当活马医。
获得session的sessionid,用它处理看看。
我去帮你查了一下,确实也有很多人遇到了这样的问题.
那就是你手机模拟器出现问题了。session处理有问题
手机也应该支持的。
将 request.getSession() 定义为一个session变量,然后通过session变量来set和get试试。
用struts2的session 放数据的时候这么用。
ActionContext.getContext().getSession().put("serviceList", serviceList);
取的时候:
ActionContext.getContext().getSession().get("serviceList");然后转型
session是针对每个用户的一个缓存,不同用户上来肯定不同的session,这样的存储性能方面也是个问题吧。
如果你的这个getTblServiceMByMobile获取的数据跟客户端用户没有任何关系,可以考虑放入一个全局的static map中,这样检查一下map,如果有,就从map中获取,没有再进行查库的操作。性能问题也解决了。
已解决问题
未解决问题服务器主动删除session问题
来源:csdn
【在最近的项目中,遇到一个问题。在每次用户登录的时候,都把用户的信息保存在session值中。所以现在有个问题,如果在后台管理端把该用户删除,但是由于此用户的信息保存在session中,如果此用户一直没有重新登录,则没有达到删除的效果,即用户仍然可以登录操作。现在想,能否在服务器端主动删除此session???达到彻底删除用户的效果。。。。。】
后台删除之后,从session中remove掉这个用户信息啊
但是你怎么知道这个用户的session对象呢?
项目是这样做的,每次用户登录成功之后,都取session对象,把用户信息保存其中,如下:
Map&String, Object& session = ActionContext.getContext().getSession();
session.put(“username”, username);
是啊,删除这个username的map值就可以了。或者你强制用户退出下
我在描述下场景。有后台管理和前台用户两套系统。每次用户登录都会存session,session.put(“username”, username);
现在的问题
1)后台管理员可以获取前台的这个session么?
2)即便可以获得,那么简单的remove,是针对哪个用户?还是全部的用户session都没有了?
该回复于 21:58:22被版主删除
删除这个username的map值就可以了。或者你强制用户退出下
如果多个用户登录,你怎么确定哪个用户对应的map值啊
可以将key值设置成唯一的,在username后面拼接
这确实是一种解决问题的办法。。。
这个你的定义以个服务器全局的变量,也就是每个用户都能存取的变量map,每个用户登录的时候都以自己的登录名为KEY,session为值放到这个map里,每次删除用户的时候,查找这个map,如果有以删除用户名的session,取出来销毁了,
否则的话不行,因为每个用户的session是独立的,其他的用户是得不到的,所以是不能操作其他的用户的session的。
楼上说的好像是说所有的用户用的是一个session吗
session是有id的 每个用户对应一个吧,
如果按楼上说的好像是用户A放到session中的东西,用户B也能取到?
lhliaiuiang:
lz的意思是这个人当前已经登录的时候,后台突然把他删除了,需要让他不能继续操作了么?
如果这样需要对每次请求的session做验证,可以在filter中,验证当前session中的user是否被删除,被删除的就session.invalidate(),然后重定向到登录页面让他去登录,重新登录的时候就会发现被删除了
jyf211314:
session有效期设置30分钟就好了,用户不操作30分钟以后session自动清空,用户信息自然也没了
什么叫服务器的全局变量?
比如用户B的权限比较大,登录之后,想删掉用户A
每次都在filter中做判断,会不会使网站的访问速度降低,因为按你所说,每一个请求都要判断相应的session,都要做一次数据库的查询、、、这样会不会影响到速度???
你定义一个类,类里边定义一个静态的变量,其他所有的类都能访问,这就是服务器全局变量。
如果这个用户做了某种投机取巧的方法,保证一直处于操作状态,那岂不是一直都相当于删除不了吗?
session存到全局变量中了,每次删除的时候检查这个全局变量就行了。如果有该用户的session就销毁就行,
你filter 还是正常拦截检查每个操作是否有session,不用查数据库,
跟平常Map&String, Object& session = ActionContext.getContext().getSession();这样有区别么?
你定义一个全局的 Map( map=new hashMap();
之后每个用登录的时候就把他的session放到map里,以用户的登录名为KEY.
明白了,相当于把所有登录的session都放在一个全局变量里,相当于他在服务运行的时候,其登录信息全部保存在服务器的内存中。如果用户登录量大的话,应该对内存没有太大影响吧。。。。
几千个用户应该没问题
跟不设置这个全局变量,只是每个用户的key值唯一,然后每次使用的时候直接取。
Map&String, Object& session = ActionContext.getContext().getSession();
session.get("usernameA");
有什么区别呀???
我觉得这个session一直在内存中,知道超时和销毁时才不在内存中, 用全局的变量保存也只是指向了这个对象,便于取到每个用户的session。不会影响服务器的。session超时和销毁时,会指向null,你还的自己试试。我没做过web的这种操作,只做过socket的。
非常感谢。。。
session本身是和map很类似,当一个用户登录时候调用
Map&String, Object& session = ActionContext.getContext().getSession();这个时候取到的是你当前的用户对应的会话对象,而你是娶不到别的用户的会话对象的。
而我们现在要做的事取到别的用户的会话对象并销毁,所以要把每个用户对应的会话以用户的名字为KEY,session为值存到全局变量里。
session是每个用户对应一个的, 比如A用户 放到session里的东西,B用户是获取不到的 ,说明每个用户是对应自己的session的, 并不是所有用户共用一个session的。
jyf211314:
完全没这个必要,你想想 你的用户我想是后台管理员客服吧?他要是投机取巧你直接冻结账号不可用不就好了?再说了 你还能检测到你的管理员客服有没有投机取巧恶意刷新恶意操作么?呵呵 这个不能吧?退一步讲你就算是能够检测得到
删除了他的session让他强制退出 那么他在刷新页面一直F5刷新登录 你是不是还得请个专门的客服来删除它的session呢?办法很简单 直接用权限大的管理员把他的账号冻结为不可用 登录都没法登录 或者直接删除账号就好了,更何况你的客服是你花钱请来的你觉得他会那么蠢敢这种吃力不讨好的事儿啊,账号是你公司超级管理员给的,别人也不知道啊,安全,管理员数量毕竟少数,公司在大也不会很多,你这个想法是多余的,如果是前台用户 游客这类型的类似于商城和微博啊这种用户的话 就跟没必要session删除了 你的portal可不就是让他们浏览和查看的么 前台用户是否恶意刷新和操作 你跟没法检测了 你说对么?
jyf211314:
如果你只是想在删除账户的时候吧session也同时删除 那么也是可以的 每次登陆的session都放入一个Map之中,删除账户的时候用删除账户的ID将session从map中移除,同时在你的拦截器中拦截费登录请求的时候用当前登录用户的ID去这个Map中查找是否有session,如果存在就继续访问,如果不存在就直接将请求redirect道登录页面 ok,如果觉得会因为用户数量大而会增大内存开销这也是不可避免的,同样你也可以将session信息放入redis之中缓存起来也是一样的
1.在你的登录方法中将每次登录的session放入Map&userId,session&之中
2.在你的拦截器preXX方法中拦截非登录的请求,首先用当前登录用户的ID去上述Map中取相关的session,如果存在则说明账户没有删除,可以继续访问,如果不存在相关session则说明账户已被删除,那么同时将当前登录用户的session销毁,同时将请求redirect道登录界面即可
lhliaiuiang:
使用缓存呗。 要删除的用户在数据库中物理/逻辑删除完之后,存入缓存中,filter验证时读缓存,invalid之后要记得remove缓存
zyb134506:
从Map中获取对应用户的Session,然后执行Session.invalidate();让该用户Session失效就可以了.这样就清楚指定用户的登录信息.
J2EE是不分Session是属于哪个用户的, 记住HTTP是无状态协议, 每次是根据浏览器Cookie定位缓存中的用户信息(Session).
谢谢你码了这么多字,其实我都不怎么明白你说的东西。。。。。
认同。。。基本也就是这种方式了
怎么使用缓存???真是第一次听说,望指教。。。。
你的困惑主要在于无法随心所欲的控制某个用户的session,所以我不多说什么,你的重点要放在思考session和数据库联系起来。相信我,当你的session与数据库有了联系后,很多问题都会结局,我这里不说具体实现是因为我讲不完里面的太多,所以还得靠你自己去慢慢耐心的学习。另外不知道你清不清楚HttpSessionBindingListener的用法 这个类对我前面说的思路有很大的启发
为什么不来个 退出登录
注销 session
每次都去数据库查询+开二级缓存,感觉这样不错
HTTP是无状态协议,然后呢?我真的体会不到你的想法。。。。
zyb134506:
无状态也就是说每次请求和用户是谁都没有关联.所以不用担心当前用户能不能读取其他用户数据的问题.
你这个问题最后怎么解决的啊
我试过了。用全局静态变量可行
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动}

我要回帖

更多关于 sessioncontext的作用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信