struts session2用session保存用户信息后,在跳转页面用

博客分类:
在基于struts2开发的web项目中,经常会用到filter过滤器,对session进行验证。如果session失效,则提示登录失效并返回到登录页面。
如下便是简单的实现过程。
首先是Filter: public class FirstFilter implements Filter {
public void init(FilterConfig cong) {
// do nothing
public void doFilter(ServletRequest srequest, ServletResponse sresponse,
FilterChain chain) {
HttpServletRequest requst = (HttpServletRequest)
HttpServletResponse response = (HttpServletResponse)
HttpSession session = requst.getSession();
//从session从取出userid,如果为空说明没有登录,将其转到登录页面.
Object obj = session.getAttribute("userId");
if (obj == null) {
//跳转到登陆页面
response.sendRedirect("/Expert_DataBase/pages/loginTransfer.jsp");
//如果存在则跳出过滤器继续执行
chain.doFilter(srequest, sresponse);
} catch (Exception e) {
e.printStackTrace();
public void destroy() {
//do nothing
接下来要在web.xml里对filter进行配置
&!-- Struts2 --& &!-- 配置Struts2的session的Filter --&
&!-- 声明filter --&
&filter-name&struts-session&/filter-name&
&filter-class&com.zxt.expert.util.FirstFilter&/filter-class&
&!-- 定义Struts2的session Filter拦截的URL --&
&filter-mapping&
&filter-name&struts-session&/filter-name&
&url-pattern&/formengine/zsf_switchSystemMenu.action&/url-pattern&
&/filter-mapping&
&filter-mapping&
&filter-name&struts-session&/filter-name&
&url-pattern&/expertsinfo/*&/url-pattern&
&/filter-mapping&
&filter-mapping&
&filter-name&struts-session&/filter-name&
&url-pattern&/taskinfo/*&/url-pattern&
&/filter-mapping&
&filter-mapping&
&filter-name&struts-session&/filter-name&
&url-pattern&/attachment/*&/url-pattern&
&/filter-mapping&
这个可以自己添加需要进行过滤的路径。
如此,便可以实现对session的过滤了,如果session失效的话,会退回到登录页面。
浏览: 6062 次
来自: 北京
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'很常见的一个应用就是访问某个页面,因为权限不够,进入登陆页面。人性化的设计是能够在登陆之后,系统跳转到用户原本需要访问的页面。这可以借助拦截器来实现。
在我们验证用户登陆的拦截器里面获取请求地址,并存入session。
package com.tuanplus.
import java.util.M
import javax.servlet.http.HttpServletR
import org.apache.struts2.ServletActionC
import com.opensymphony.xwork2.ActionC
import com.opensymphony.xwork2.ActionI
import com.opensymphony.xwork2.interceptor.I
* 验证用户登陆
* @author MZULE
public class UserLoginInterceptor implements Interceptor {
private static final long serialVersionUID = 1514166L;
public void destroy() {
public void init() {
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext context = invocation.getInvocationContext();
// 获取session
Map&String, Object& session = context.getSession();
Object user = session.get("user");
// 用户还未登陆
if (user == null) {
// 获取HttpServletRequest对象
HttpServletRequest req = ServletActionContext.getRequest();
// 获取此请求的地址,请求地址包含application name,进行subString操作,去除application name
String path = req.getRequestURI().substring(10);
// 获得请求中的参数
String queryString = req.getQueryString();
// 预防空指针
if (queryString == null) {
queryString = "";
// 拼凑得到登陆之前的地址
String realPath = path + "?" + queryS
// 存入session,方便调用
session.put("prePage", realPath);
return "login";
// 用户已经登陆,放行
return invocation.invoke();
在用户登陆的action中加入字符串类型的prePage属性,用来存储拦截器放入session的prePage值(即登陆前的请求地址)。
package com.tuanplus.
import com.tuanplus.po.U
import com.tuanplus.service.IUserS
import com.tuanplus.util.AuthCodeU
* 登陆Action
* @author MZULE
public class LoginAction extends BaseAction {
private static final long serialVersionUID = -0438432L;
private IUserService userS
//登录前页面
private String preP
public String execute() {
// 获取登陆的User对象
User seuser = userService.get(user.getEmail());
// 加入session
session.put("user", seuser);
//获取跳转到登陆界面之前的页面地址,由拦截器提供
prePage = (String) session.get("prePage");
//清除session中的数据
session.remove("prePage");
if (prePage == null) {
//不是拦截器跳转到登陆页面的,直接访问的登陆页面
return "myorder";
return SUCCESS;
在struts.xml中配置使用action的属性prePage决定物理视图资源。
&!-- 登陆 --&
&action name="login" class="loginAction"&
&result type="redirectAction"&${prePage}&/result&
&result name="myorder" type="redirectAction"&myOrder&/result&
&result name="input"&/login.jsp&/result&
嗯,一个小技巧,希望对大家有用。
阅读(...) 评论()Struts2 问题 我登录通过action 验证登录成功后 跳转到另外一个页面,怎么实现在跳转页面显示登录的用户_百度知道
Struts2 问题 我登录通过action 验证登录成功后 跳转到另外一个页面,怎么实现在跳转页面显示登录的用户
我有更好的答案
把用户对象放在session中可以在下个页面中取出该对象,HttpSession session =ActionContext.getSession().put(&Object&,String);Object
obj=ActionContext.getSession().get(String);
采纳率:47%
在action校验用户成功后,把登录用户的信息放入Session作用域,然后在跳转后的页面获取Session里面的登录用户信息
为您推荐:
其他类似问题
struts2的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。利用ThreadLocal管理登录用户信息实现随用随取通常在项目中,用户登录后,我们会将用户的信息存到session,如果想在其它地方获取session中的用户信息,我们需要先获取HttpServletRequest,再通过request.getSession得到HttpSession,从而获取到我们想要的用户信息。通常我们会将以上操作提取一个公共方法,如:public static User getSessionUser(HttpServletRequest request)
if(request.getSession().getAttribute( "sessionuser" ) != null)
return (User)request.getSession().getAttribute( "sessionuser" );
return null;
但是这样做也比较麻烦,需要传入一个HttpServletRequest,在Servlet和Struts1中我们可以轻松得到request对象,在SpringMVC中,我们只要在一个controller方法参数里显式加上HttpServletRequest参数也可以轻松获取,如:public String create(HttpServletRequest request,HttpServletResponse response) {}
而在Struts2中,尽管获取request对象有好几种方法,但通常大家会采取在action中实现ServletRequestAware接口并实现setServletRequest方法的方式来获取:private HttpServletRequest request;
public void setServletRequest( HttpServletRequest request )
this.request = request;
我们在处理请求的时候,很多操作都要获取当前用户的ID等信息,由上可见,我们凡是在action的方法中任何一处想要获取session中的用户信息,则必须要先手动获取到HttpServletRequest,是不是比较麻烦,于是基于此,我们可以想出一种解决方案,就是写一个Action的基类,比如叫BaseAction.java,让这个基类去继承ActionSupport,并实现ServletRequestAware接口,并在此类里写一个获取用户信息的公共方法:public class BaseAction extends ActionSupport implements ServletRequestAware
private static final long serialVersionUID = -8565607L;
public HttpServletRequest request;
public void setServletRequest( HttpServletRequest request )
this.request = request;
* 获取session中的用户
public User getSessionUser()
if(request.getSession().getAttribute( "sessionuser" ) != null)
return (User)request.getSession().getAttribute( "sessionuser" );
return null;
然后所有action都去继承这个BaseAction基类,然后直接调用getSessionUser()方法便可轻松获取用户信息:public class UserAction extends BaseAction
private static final long serialVersionUID = -254625L;
public String load()
//获取session用户信息
User user = getSessionUser();
if(user != null)
System.out.println("当前用户:"+user.getUsername());
System.out.println("用户为空");
return "chat";
看上去问题似乎得到了解决,可是以上仅能满足在所有action的方法中随用随取,而实际中我们在做一些DAO操作时,往往要记录操作人的ID,也就是当前登录用户的ID,如发表/修改文章,这个时候,在service层和dao层就要用到session中的用户信息,而通常在一个大型项目中,service层和dao层都是和web层分离开来,都是单独的工程,不依赖servlet api,大家也不会为了在service层或者dao层获取登录用户信息而这么做,这样显得会很奇怪,所以我们只能在action中调用service的时候,将用户信息以参数形式传过去,如: public interface ArticleService
* 保存文章
* @param article 文章信息
* @param user 当前用户
boolean saveArticle(Article article, User user);
如此一来,代码就不够简洁优雅,所有我们想要获取用户信息的方法都要多加一个参数,增强了依赖,和我们想要的“松耦合”背道而弛。所以,对于session中的用户信息,我们不仅想要在action中随用随取,还想在其它普通类中取,即使不依赖servlet api, 我们也要在方法里随用随取,anywhere!为了解决这个问题,我们就要采取一种新的方法来存储用户信息——ThreadLocal。ThreadLocal,顾名思义,就是本地线程,可是这个名字实在容易让人误解,因为其实它是本地线程局部变量的意思,首先我们要知道,我们每个请求都会对应一个线程,这个ThreadLocal就是这个线程使用过程中的一个变量,该变量为其所属线程所有,各个线程互不影响。这里我们要了解一下ThreadLocal的三个方法:ThreadLocal.set(T value); //设置值ThreadLocal.get(); //获取值ThreadLocal.remove(); //移除值所以我们可以借助这个ThreadLocal来存储登录用户的信息,在一个请求中,所有调用的方法都在同一个线程中去处理,这样就实现了在任何地方都可以获取到用户信息了,从而摆脱了HttpServletRequest的束缚。具体实现如下:首先,我们定义一个SessionLocal,在这个类中,我们初始化一个静态的ThreadLocal,其支持泛型,这里类型为用户对应的Bean,因为我们要存储的是用户信息,然后写两个静态方法,setUser用于往ThreadLocal设置用户信息,getUser()用于从ThreadLocal获取用户信息:public class SessionLocal
private static ThreadLocal&User& local = new ThreadLocal&User&();
* 设置用户信息
* @param user
public static void setUser( User user )
local.set( user );
* 获取登录用户信息
public static User getUser()
System.out.println( "当前线程:" + Thread.currentThread().getName() );
return local.get();
在用户登录的时候,我们根据登录名和密码查询到用户信息以后,就调用上面的setUser()方法存储我们的用户信息到线程局部变量中,暂时不保存到session中:SessionLocal.setUser( user );
然后,我们在想要获取用户信息的地方调用getUser()方法即可,比如我在一个action的load方法中:public String load()
User user = SessionLocal.getUser();//获取用户信息
if(user != null)
System.out.println("当前用户:"+user.getUsername());
System.out.println("用户为空");
return "chat";
即使在service实现类里也可以正常获取:public class ArticleServiceImpl implements ArticleService
public boolean saveArticle( Article article )
User user = SessionLocal.getUser();
System.out.println("[service]当前用户:"+user.getUsername());
//To do save article
return true;
可是这时候又出现了问题,在一个线程结束后,我又发起了一次后台请求,这个时候,处理这个请求的线程变成了另外一个线程,线程切换了!!!而这个线程中我们并没有set用户信息到它的ThreadLocal中去,此时我们想要获取用户信息就获取不到了,前面说过,ThreadLocal为各个线程所私有,各线程间不共享,也互不影响,那么问题来了,我们只是在登录的时候,查询用户信息并将其放进当前线程的ThreadLocal,而后续其它请求一旦切换到别的线程,我们的功能就玩不转了,所以我们需要借助一个方法来过滤所有的后台请求(排除非必须登录才能访问的url),给用户信息做个检查,一旦SessionLocal.getUser()为空,那么我们就set进去,so,我们可以借助一个Filter来达到我们的目的。可是上面我们并没有将用户信息放到session中,此时,我们还是绕回去了,我们依然不得不把用户信息给放到session中,不然我们在Filter中如何获取用户信息并set进ThreadLocal,总不能再查一次数据库,所以,将上面的登录处理做个改动,添加用户信息到session:public String login()
User user = new User();
user.setUsername( username );
//存储session
request.getSession().setAttribute( "sessionuser", user );
//存储ThreadLocal
SessionLocal.setUser( user );
System.out.println("用户【"+username+"】登录,存进session,并设置进TheadLocal");
return "chat";
如此,我们在Filter中就可以先判断SessionLocal.getUser()是否为空,如果为空,则从session中取用户,如果session中有,则将用户放到TheadLocal,否则,跳转到首页或者登录页,这里我们定义一个SessionFilter:public class SessionFilter implements Filter
public void destroy()
// TODO Auto-generated method stub
public void doFilter( ServletRequest req, ServletResponse res,
FilterChain chain ) throws IOException, ServletException
HttpServletRequest request = (HttpServletRequest)req;
//排除登录请求
if(request.getRequestURI().contains( "user!login.action" ))
chain.doFilter( req, res );
System.out.println("【请求拦截.】");
HttpSession session = request.getSession();
if(session.getAttribute( "sessionuser") != null)
if(SessionLocal.getUser() == null)
System.out.println("【当前线程"+Thread.currentThread().getName()+"中用户信息为空,从session中set到ThreadLocal.】");
SessionLocal.setUser( (User)session.getAttribute( "sessionuser") );
System.out.println("【用户会话失效,跳转到首页.】");
HttpServletResponse response = (HttpServletResponse)res;
response.sendRedirect( "index.jsp" );
chain.doFilter( req, res );
public void init( FilterConfig arg0 ) throws ServletException
// TODO Auto-generated method stub
再将上面的SessionFilter配置到web.xml,注意顺序一定要在struts2映射之前,不然Filter会没有效果&filter&
&filter-name&sessionFilter&/filter-name&
&filter-class&com.shen.usersession.SessionFilter&/filter-class&
&filter-mapping&
&filter-name&sessionFilter&/filter-name&
&url-pattern&*.action&/url-pattern&
&/filter-mapping&
经过上面的配置,不论线程怎么切换,我们都可以在任何方法中很方便的获取用户信息了,不用传任何参数:User user = SessionLocal.getUser();
以上是通过filter实现请求过滤,在springMVC中,我们可以通过HandlerInterceptor来实现,定义一个类去实现这个HandlerInterceptor接口,在preHandle中去调用SessionLocal中的setUser(user)来设置用户信息,在xml配置这个interceptor的时候,我们可以通过&mvc:exclude-mapping path=""/& 很方便的配置要排除的URL。 111 条评论分享收藏文章被以下专栏收录没有更多推荐了,
不良信息举报
举报内容:
Struts2通过session暂存登录信息
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!}

我要回帖

更多关于 struts session 的文章

更多推荐

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

点击添加站长微信