我在LoginAction中是这样写的:package cn.nit.action;import java.util.ArrayList;
import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;import cn.nit.hibernate.Users;
import cn.nit.hibernateUtils.HibernateUtils;
import cn.nit.management.UserLogin;import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;/**
 * 教师,管理员登录
 * @author Administrator
 *
 */public class LoginAction extends ActionSupport{
/**
 * 采用模型驱动方式
 */
UserLogin userLogin = new UserLogin();

public UserLogin getUserLogin() {
return userLogin;
} public void setUserLogin(UserLogin userLogin) {
this.userLogin = userLogin;
}

public String execute(){
ActionContext actionContext = ActionContext.getContext();
Map userSession = actionContext.getSession();//获得session
Map applicationMap = actionContext.getApplication();
HttpServletRequest request = ServletActionContext.getRequest();//获得request对象
String sessionID = request.getSession().getId();//获得sessionID
String username = userLogin.getUsername();
String password = userLogin.getPassword();

applicationMap.put(username, sessionID);//K与V类型,每个用户对应一个sessionID
userSession.put("username", username);//将用户添加到session中

System.out.println("得到的验证码" + userSession.get("rand"));
System.out.println("用户名" + username);
System.out.println("密码" + 11);
System.out.println("验证码" + userLogin.getValidate());

Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
String sql = " select u from Users as u where u.userNo= '" + username +"'";

Query query = session.createQuery(sql);
ArrayList userList = (ArrayList)query.list();
tx.commit();
HibernateUtils.close(session);

Users user = new Users();

if(!userSession.get("rand").equals(userLogin.getValidate())){
return "error";
}else if((userList !=null) && (userList.size()>0)){
user = (Users) userList.get(0);

System.out.println("对应表的用户名:" + user.getUserNo());
System.out.println("对应表的密码:" + user.getUserPwd());
if((user.getUserPwd().trim()).equals(password)){
//用户名密码正确,判断用户的角色,现在只是简单的处理
if(user.getUserRole().equals("1")){
System.out.println("你是管理员");
return "admin";
}else{
System.out.println("你是教师");
return "teacher";
}
}
}else{
return "error";
}
return "error";
}
}
可是感觉就不对,因为每个用户请求过来的时候,都会去执行execute()方法,那么applicationMap每次都是空,不可能实现我想要的功能。那要怎么写?我现在都糊涂了。

解决方案 »

  1.   

    我目前有一个想法,就是去写个类,把applicationMap中的类型放到一个类,然后每次都去比较?不知道可行不可行,我想知道你们有什么想法,吸收吸收!!!
      

  2.   

    我也遇过这个问题,我哪是的做法是 记录IP和登录时间,当有人在用同一个号登陆时,首先去SESSION里找IP是不是相同的,如果相同就是同一个人,可以重复登录,否则就不与登录。
      

  3.   

    将登录状态保存在DB中如何,放在application里面,不知道你的站点访问量多大!
    个人想法,只是个建议
      

  4.   

    记住登陆状态需要持久化User表应当多个状态字段另外,登陆方法应当同步,不过很影响效率,一般来说,网站都没这个需求一般都是企业应用什么的才要求这样
      

  5.   

    spring的security框架有这个功能,实现单点登陆。
      

  6.   

    登陆之后把用户信息存储一下,当然也可以放在全局上下文里不一定非得放进数据库,再加个session的listener,对用户session失效时把记录的信息移除一下。
      

  7.   

    把已登录的账号放map里进行匹配,并将此账号进行操作时的时间进行记录,最后每隔一段时间删掉最后操作时间长于n分钟的记录。
    涉及到竞争资源、定时器等操作。
      

  8.   

    增加一个全局context,记录所有登录人员的信息。其实系统监控应该也需要这样的信息。然后通过这些登录人员信息再对登录人员进行比较。(一般来说不允许2人同时登陆。后来者踢掉先登录者)。至于怎么维护这个全局信息,可以采用轮询或者别的方式。
      

  9.   

    楼主给你个链接 http://zhidao.baidu.com/question/98349521.html
      

  10.   


    放到session中?每次用户请求过来,重新产生session,这个session肯定与第一次产生的session不同,怎么比较?
    能不能明白点,是不是我理解错了?还是?谢谢你了
      

  11.   


    把用户信息存放到哪?因为每次用户请求过来,会重新生产ActionContext actionContext = ActionContext.getContext();
            Map userSession = actionContext.getSession();//获得session
            Map applicationMap = actionContext.getApplication();
            HttpServletRequest request = ServletActionContext.getRequest();//获得request对象
             String sessionID = request.getSession().getId();//获得sessionID我这个代码是放在execute()方法中,所以每次请求过来的时候,会重新产生,所以怎么比较?
      

  12.   


    把全局context放哪?每次用户请求过来,LoginAction都会执行,那就没效果了啊。大家帮帮我!能不能详细的说下。
      

  13.   


    全局context,就是生命周期贯穿你的整个应用启动到结束的一个对象。你可以使用一个static的对象或者别的什么的。总之保证它的生命周期和唯一性就行了。
      

  14.   

    欢迎各位java大侠、小虾加入QQ高级群:45271133  群满500人为止,热烈邀请大侠们加入指点~!
      

  15.   

    真是项目不能存放在session中, 一般都会有一张表专门管理在线用户 
    然后还写一个管理类,定时去检查用户是不是在线,多长时间没有操作将自动清除
      

  16.   

    代码比较多,要发好几个类,我把思路说一下吧!1.   实现 HttpSessionListener,HttpSessionBindingListener2.   private static  Map<String,HttpSession> onLineUsers = new LinkedHashMap<String, HttpSession> (); //这里是static的,并且放的是session,登录以后有的session
    3. web.xml配置Listener,你先写吧!不要用表什么的,那是很烦,而且不准确。就管理session就可以了
      

  17.   


    用session怎么管理,我的LoginAction.java就是我贴出来的,在发贴那里,说实话我认为我那样写肯定是错的,因为每当有用户请求过来,就会产生session,把sessionID放到 Map applicationMap中,所以如果再有用户请求过来,又会重新产生session,那应该怎么写?帮个忙?
      

  18.   


    /**
     * @author blliy117
     *
     */
    public class OnLineLoginUser implements HttpSessionListener,HttpSessionBindingListener { private static  Map<String,HttpSession> onLineUsers = new LinkedHashMap<String, HttpSession> (); 

    public void sessionCreated(HttpSessionEvent se) {

    } public void sessionDestroyed(HttpSessionEvent se) {


    } public void valueBound(HttpSessionBindingEvent event) {

    } public void valueUnbound(HttpSessionBindingEvent event) {

    }

    public static void addUser(Object obj){

    }
    public static void removeUser(Object obj){

    }

    public static List getUsers(){
    List userList = new ArrayList();
    for(String userName : onLineUsers.keySet()){
    HttpSession session = onLineUsers.get(userName);
    if(session!=null && session.getAttribute("user")!=null){
    userList.add(session.getAttribute("user"));
    }
    }


    return userList;
    }
    写起来比较多,你自己实现一下吧
      

  19.   

    为什么存SessionID呢?用户ID没有?也许我很菜。
      

  20.   


    这是我一开始的想法,就是把用户产生的sessionID来判断用户是否已经登录了。结果已失败而告终。
      

  21.   

    线程模式:
      ◆Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
      ◆Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题) ---------------------Struts2 新特性-------------------------------------------------------------你可以在Struts2里设置属于自己用户的变量啊 
      

  22.   

    sesseion.getattribute("username");可以获得user的名称 ID之类的信息的嘛,这个东西把所有的session用map管理人员少的话还是可以的 如果像游戏那种一下100W+的用户登陆那就~。存数据库没什么不好的 出错的几率也小啊  在application启动的时候 设置所有的登录状态为未登录 防止出错后用户永远不能登陆
      

  23.   

    http://topic.csdn.net/u/20091010/09/2a81917a-42f4-4304-8c62-648750616921.html
      

  24.   

    在Context中建立一个Map<String,Sission>,存放的是用户名和用户的session.
    当用户登录时先从Context中检查Map中有无此username的KEY,来判断用户是否登录.
    由于Map中存放的value是用户的session,所以还可以使后登陆用户踢掉先前用户.
    不过要在工程下加一个session的监听器,当用户session失效时要及时把用户在Context的Map里面的K/V移除掉.
      

  25.   

    100W+在线什么样的服务器也受不了,存Map里value值是引用的,KEY是字串,相比于其他用户服务来说占用不了多少空间吧.
      

  26.   

    最简单也是最实际的,在用户的属性中,增加一个字段,表示在线状态咯
    不然的话在context中存放对应用户应该是最直观的,但是数据量是个问题,这种解决方案不够抽象和彻底
      

  27.   

    你现在用的userSession 是从actionContext.getSession()中获得,只要你不停服务,
    哪怕每次执行execute()方法,userSession也不会为空,所以你只要userSession.put("userName",userName)存进去便可,
    你的userSession.put() 和applicationSession.put 写错位置了,应该要登陆后才能put,登陆成功后,再执行execute()可直接 userSession.containsKey(userName)
      

  28.   


     对于你所说“哪怕每次执行execute()方法,userSession也不会为空,所以你只要userSession.put("userName",userName)存进去便可,”,不行啊,我去从userSession中去比较的时候,一直都没发现该用户,而且还是可以登录,然后我就把值给输入出来了,全部为空。为什么说userSession在服务器上没关闭就不会为空?是真的吗?是不是自动等session过期还是?
    对于你后面所说的“你的userSession.put() 和applicationSession.put 写错位置了,应该要登陆后才能put,登陆成功后,再执行execute()可直接 userSession.containsKey(userName)”,说得很正确,这代码我写错了,但是问题还是归咎于我前面的问题,因为我输入userSession中的内容,发现为空,所以根本不可能会在userSession中找到找到相关的登录信息。
      

  29.   

    ActionContext actionContext = ActionContext.getContext();
     作为单个类的静态变量,应该就可以了 
    在线访问量太大的话,推荐在数据库中多设立个字段,如果访问量少的话就你这个方法就可以了,或者可以参考spring的单点登录
      

  30.   

    先设置session 的有效期为10秒(设置比较短的时间)
    在页面上写 用js 访问session的代码(可以使用ajax)(用定时器 定时访问当前登录用户的session,保持 session的可用性)。
    当浏览器异常退出,或者被关闭, session将不会再被访问到,这样session超时10秒,就会销毁。 或者用户注销 ,服务器主动销毁session。当一个用户登录的时候 只要浏览器没有被关闭,session应该是一直都有效的。 只要用户一关闭浏览器。过十秒后,session就会超时销毁。当一个用户已经登录,这个账户再次登录的时候,只需判断是否在session存在。。如果存在 则是已经登录 不存在则没有登录 这样就可以处理很多的异常情况,例如:浏览器被任务管理器强制关闭。。