我用的是S2SH,怎样防止一个用户登录后,其他用户就不能用相同的用户名在登录?好像struts2的action是多实例的吧?

解决方案 »

  1.   

    貌似session不行吧,楼上的兄弟,你试过吗?
      

  2.   

    application 应该可以,还有一种就是在数据库里面用户表标记登录状态
      

  3.   

    在session中可以public String login(){

    return SUCCESS;
    }

    public void validate() {
    if(ServletActionContext.getContext().getSession().get("username")==null)
    {
    ServletActionContext.getContext().getSession().put("username", username);
    }else{
    addFieldError("username", "该用户已登录");
    }
    }
      

  4.   

    不用框架。通过过滤,之后判断session id
      

  5.   

    一般都是放到application或在数据库中定义一个字段吧;
    不过我觉得还是放到application的好,将信息放入application再用一个listener来监听,用户推出就remove掉,这样能简单点儿吧
      

  6.   

    application 应该可以,还有一种就是在数据库里面用户表标记登录状态
    public String login(){
            
            return SUCCESS;
        }
        
        public void validate() {
            if(ServletActionContext.getContext().getSession().get("username")==null)
            {
                ServletActionContext.getContext().getSession().put("username", username);
            }else{
                addFieldError("username", "该用户已登录");
            }
        }
      

  7.   

    支持。 可以用session 去服务器判断 这个session是否已经登录public String login(){
            
            return SUCCESS;
        }
        
        public void validate() {
            if(ServletActionContext.getContext().getSession().get("username")==null)
            {
                ServletActionContext.getContext().getSession().put("username", username);
            }else{
                addFieldError("username", "该用户已登录");
            }
        }
      

  8.   

    可以放到application或在数据库中定义一个状态字段;
    放到application可能简单点,不过我还是喜欢定义字段。
    设置一个字段,可以设值是0、1,登录时验证用户名和密码的同时通过这个字段的值判断状态,为0表示未登录,通过验证后设为1,为1则表示登录,提示用户不能登录。
      

  9.   

    你用一个账号进CSDN 在换台机器还用这个账号登陆CSDN 你看看会怎么样?
      

  10.   

    放在session里,同时将登陆首次成功登陆的IP保存到数据库里,登陆的时候判断即可。
      

  11.   

    每个用户都有自己的session  你判断就行了 如果重复 跳转错误页面!
      

  12.   

    其实方法很多在数据库中添加一个字段做状态标记比较方便!application 也完全可以你也可以将userInfo 和 电脑的Ip 关联  都能实现
      

  13.   

    1.application可以实现
    2.数据库中建立表用于标示登录状态
     
      

  14.   

    我一般都是在数据库中多加个状态列来实现的,application也可以。
      

  15.   

    是的,我们的做法是后面登录的把前面登录的踢出来,有点暴力,有可能前面人家还在输入数据呢。最好是发现session存在的时候先给个提示是不是要踢出前面的登录,和qq一样。数据库这种实现就比较不好了,考虑下开发,测试的成本,还是别这样吧。如果用户登录了,服务器在测试的时候关闭了,数据库的数据谁去清空? 难道还要记录一下用户最后操作的时间? 搞的复杂了
      

  16.   


    session是可行的,数据库中建字段,这个方法不太好,因为如果用户不是正常的退出,那字段没有更改,那下次用户就登不进去了,所以,我认为最好就是写监听器,监听session
      

  17.   

    --上面说错了
    是web服务器重启了,所有session都失效了
    那么数据库中的状态还得全部都去重置一下,很不经济啊
      

  18.   

    STRUTS2 TOKEN机制,也可以用JS代码控制按钮.
      

  19.   

    简单的可以在数据库做操作,比如登入了算1,没登入算2,但是要考虑非正常下线,需要启动一个job定时扫描,如果长时间未做操作的话,算自动下线,或者session失效的时候也行复杂点的话 建议单点登入
      

  20.   

    监听session id即可!跟框架无关!我来找找代码。网上也有。
      

  21.   

    ackage com.nbchina.listener;import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;public class SessionListener implements HttpSessionListener {
    private static HashMap hUserName = new HashMap();//保存sessionID和username的映射
    @Override
    public void sessionCreated(HttpSessionEvent arg0) {}
    @Override
    public void sessionDestroyed(HttpSessionEvent arg0) {}
      /*
      * isAlreadyEnter-用于判断用户是否已经登录以及相应的处理方法
      * @param sUserName String-登录的用户名称
      * @return boolean-该用户是否已经登录过的标志
      */
      @SuppressWarnings("unchecked")
    public static boolean isAlreadyEnter(HttpSession session,String sUserName){
      boolean flag = false;
      //如果该用户已经登录过,则使上次登录的用户掉线(依据使用户名是否在hUserName中)
      if(hUserName.containsValue(sUserName)){
    flag = true;
    //遍历原来的hUserName,删除原用户名对应的sessionID(即删除原来的sessionID和username)
    Iterator iter = hUserName.entrySet().iterator();
    Map.Entry entry;
    while (iter.hasNext()){
    entry = (Map.Entry)iter.next();
    Object key = entry.getKey();
    Object val = entry.getValue();
    if(((String)val ).equals(sUserName)){
    // hUserName.remove(key);//产生java.util.HashMap$HashIterator.nextEntry错误
    iter.remove();
    }
    }
    hUserName.put(session.getId(),sUserName);//添加现在的sessionID和username
    System.out.println("hUserName = " + hUserName);
      }else{
      flag = false;
      hUserName.put(session.getId(),sUserName);
      System.out.println("hUserName = " + hUserName);
      }
      return flag;
      }   /*
      * isOnline-用于判断用户是否在线
      *  @param session HttpSession-登录的用户名称
      *  @return boolean-该用户是否在线的标志
      */   public static boolean isOnline(HttpSession session){
      boolean flag = true;
      if(hUserName.containsKey(session.getId())){
      flag = true;
      }else{
      flag = false;
      }
      return flag;
      }
    }以上是核心代码。
    下面是过滤public class MemberValidateFilter implements Filter { public void destroy() {
    } public void doFilter(ServletRequest req, ServletResponse resp,
    FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest)req;
    Member member = WebUtil.getMember(request);
    if(member==null){
    HttpServletResponse response = (HttpServletResponse) resp; 
    response.sendRedirect(SiteUrl.readUrl("member.logonui"));
    return ;//必须有return,否则还会继续执行。
    }
    if(!SessionListener.isOnline(request.getSession())){
    HttpServletResponse response = (HttpServletResponse) resp; 
    response.sendRedirect(SiteUrl.readUrl("client.member.offline"));
    return ;//必须有return,否则还会继续执行。
    }
    chain.doFilter(req, resp);
    } public void init(FilterConfig config) throws ServletException {
    }}
      

  22.   


    不好意思,解决方案肯定是有的。你登陆时候有SESSION ID 吧 USER 人的字段加一个 如 CURRENTSESSIONID进行操作得时候把CURRENTSESSIONID UPDATE 一下 制1
    操作完成后再把CURRENTSESSIONID UPDATE 一下 制0操作过程中别人用同名的帐号操作 判断 字段 CURRENTSESSIONID 为 1 就返回不操作
    如果为0 则可操作。
      

  23.   

    package com.ideal.web.listener;import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.*;
    import java.util.*;
    import org.apache.log4j.Logger;public class ContextSingleListener extends HttpServlet implements
    ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
    ServletContext context = sce.getServletContext();


    context.setAttribute("user_list", new Hashtable());
    } //Notification that the servlet context is about to be shut down
    public void contextDestroyed(ServletContextEvent sce) {
    ServletContext context = sce.getServletContext();
    context.removeAttribute("user_list");
    }
    }
    |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||package com.ideal.web.listener;import java.util.HashMap;
    import java.util.Hashtable;import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;import org.apache.log4j.Logger;public class SessionSingleListener extends HttpServlet implements
    HttpSessionListener {
          在这里进行判断
    public void sessionCreated(HttpSessionEvent se) {
    Hashtable user_list = (Hashtable) se.getSession().getServletContext()
    .......... } public void sessionDestroyed(HttpSessionEvent se) {
    Hashtable user_list = (Hashtable) se.getSession().getServletContext()
    .getAttribute("user_list");
    if (null != user_id) {
    logger.info("用户:" + user_id + "退出。");
    user_list.remove(user_id);
    }
    }
    }
      

  24.   


    我觉得session不行吧,session的作用域是当前会话,另一个人再开一个IE登录算另一个会话了吧
      

  25.   

    session 是可以的吧 自己做做就知道了
    俺以前毕业设计的时候用过。
      

  26.   

    我试过了,我代码是这样写的:HttpSession session = request.getSession();
    if(session.getAttribute("username")==null)
    {
        System.out.println("save session");
        session.setAttribute("username",name);
    }
    else
    {
        System.out.println("已登录");
    }是这样执行的:打开IE,使用A用户登录,控制台输出save session。再开另一个IE,再使用A用户登录,控制台还是输出save session
      

  27.   


    就差个xml配置了。就上面两个java文件。
    之后一个配置web.xml内放置    <filter>
            <filter-name>MemberLogonValidate</filter-name>
            <filter-class>com.xxxxx.filter.MemberValidateFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>MemberLogonValidate</filter-name>
            <url-pattern>/client/*</url-pattern>
        </filter-mapping>
      这段配置是/client/*目录开头下所有的路径都用MemberValidateFilter进行过滤总共就两个文件。一个web.xml内配置一下。没了,就这么多。以下我在完整贴一下贴过的代码。
    MemberValidateFilter.javapackage com.xxxxxx.filter;import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import com.xxxxxx.bean.member.Member;
    import com.xxxxxx.listener.SessionListener;
    import com.xxxxxx.util.SiteUrl;
    import com.xxxxxx.util.WebUtil;
    import com.opensymphony.xwork2.ActionContext;public class MemberValidateFilter implements Filter { public void destroy() {
    } public void doFilter(ServletRequest req, ServletResponse resp,
    FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest)req;
    Member member = WebUtil.getMember(request);
    if(member==null){
    HttpServletResponse response = (HttpServletResponse) resp; 
    response.sendRedirect(SiteUrl.readUrl("member.logonui"));
    return ;//必须有return,否则还会继续执行。
    }
    if(!SessionListener.isOnline(request.getSession())){
    HttpServletResponse response = (HttpServletResponse) resp; 
    response.sendRedirect(SiteUrl.readUrl("client.member.offline"));
    return ;//必须有return,否则还会继续执行。
    }
    chain.doFilter(req, resp);
    } public void init(FilterConfig config) throws ServletException {
    }}SessionListener.java package com.xxxx.listener;import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;public class SessionListener implements HttpSessionListener {
    private static HashMap hUserName = new HashMap();//保存sessionID和username的映射
    @Override
    public void sessionCreated(HttpSessionEvent arg0) {}
    @Override
    public void sessionDestroyed(HttpSessionEvent arg0) {}
      /*
      * isAlreadyEnter-用于判断用户是否已经登录以及相应的处理方法
      * @param sUserName String-登录的用户名称
      * @return boolean-该用户是否已经登录过的标志
      */
      @SuppressWarnings("unchecked")
    public static boolean isAlreadyEnter(HttpSession session,String sUserName){
      boolean flag = false;
      //如果该用户已经登录过,则使上次登录的用户掉线(依据使用户名是否在hUserName中)
      if(hUserName.containsValue(sUserName)){
    flag = true;
    //遍历原来的hUserName,删除原用户名对应的sessionID(即删除原来的sessionID和username)
    Iterator iter = hUserName.entrySet().iterator();
    Map.Entry entry;
    while (iter.hasNext()){
    entry = (Map.Entry)iter.next();
    Object key = entry.getKey();
    Object val = entry.getValue();
    if(((String)val ).equals(sUserName)){
    // hUserName.remove(key);//产生java.util.HashMap$HashIterator.nextEntry错误
    iter.remove();
    }
    }
    hUserName.put(session.getId(),sUserName);//添加现在的sessionID和username
    System.out.println("hUserName = " + hUserName);
      }else{
      flag = false;
      hUserName.put(session.getId(),sUserName);
      System.out.println("hUserName = " + hUserName);
      }
      return flag;
      }   /*
      * isOnline-用于判断用户是否在线
      *  @param session HttpSession-登录的用户名称
      *  @return boolean-该用户是否在线的标志
      */   public static boolean isOnline(HttpSession session){
      boolean flag = true;
      if(hUserName.containsKey(session.getId())){
      flag = true;
      }else{
      flag = false;
      }
      return flag;
      }
    }
    所有都在这儿了,很简单,你照套即可。说好了,100分都给我。呵呵
      

  28.   

    引用 46 楼 superrain_zy 的回复:
    Java codeHttpSession session = request.getSession();
    if(session.getAttribute("username")==null)
    {
        System.out.println("save session");
        session.setAttribute("username",……
      

  29.   

    当用户第一次登录时在SESSION中注册ID,然后每一次登录都在SESSION中云判断此用户有没有登录,如果已经登录就不用再登录啦。
      

  30.   

    我真的想把分都给你,但是
    import com.xxxxxx.bean.member.Member;
    import com.xxxxxx.util.SiteUrl;
    import com.xxxxxx.util.WebUtil;
    少这三个类呀,我也照套不出来呀,你也不写注释,这三个类是干什么的,调不通我也不能发分给你呀
      

  31.   

    就算新学也不能新到如此地步巴??一个是用户类。里面很简单。就id和name。一般自己编写的。跟你自己用户有关系,用来登陆赋予session值。
    SiteUrl没有没关系。去掉可以的。
    webUti就是获取session。你可以去掉的。自己写。
    我尽力了。就算网上人家的例子,也就给我这么多。
      

  32.   

    放到application可能简单点 ,效率也高点
      

  33.   

    Seesion设置为1分钟 每画面加入AJAX连后台 每分钟一次 30次 
      

  34.   


    1、我从来没说自己是高手!
    2、你要在这儿骂人不要脸首先检视一下自己。你说我不要脸的理由就是我没有自己使用就贴来这儿。好,我抓图给你证据看看。另外,其实我不用抓图,稍微有点经验的人都知道,所有核心代码都在这儿了!你这种人人品真太差了,上来就乱喉乱叫!!3、你非要纠结我是否用过,请你跟我打赌,你给我邮箱,我抓图把我用过的这些发送过去。若我用过,你来这儿开贴子道歉!我若没用过,我开贴子倒贴你100分。怎么java论坛多出这么多没有教养乱喉乱叫的低素质的人啊!?!
      

  35.   

    不管人家要分也好,什么也罢。。总之解决办法在不考虑Application 和存库的前提下 的第三种办法。 而且是可用的。。 
    在这骂起来实属不明智之举啊   
      

  36.   

    单点登录不是那么简单的,我今天晚上想了几个小时,还是没有给弄出来,监听session是不行的,关闭浏览器session不会消失,session消失是根据tomcat容器控制,http是无状态连接,服务器不知道你关闭了浏览器。
    后来我打算用flex跟服务器建立socket和session绑定,一旦浏览器关闭,socket断开就可以把session失效,本想没有问题的,但是后来发现浏览器页面刷新或者跳转到其他页面,flex socket就断开了,所以没办法了,现在还没有想到什么办法啊 哎
      

  37.   

    看了这么多回复,有帮助的不多~~~ 难道这个问题就这么复杂、、? 我听说spring提供了工具 只需配置一下即可
      

  38.   

      使用Spring security如何防止用户的重复登录呢?如果用户账号已登录,这时再进行第二次或多次登录,需要阻止这样的多次登录。一.在web.xml中配置listener<listener>
            <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
    二.在security.xml中配置Hibernate ORM提供了三种继承映射策略
    <session-management>
                <concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
    </session-management>
      max-sessions表示最多允许多少次重复登录。如果没有配置error-if-maximum-exceeded,那么用户账号的第二次登录会使第一次登录失效,而配置了的话,那么第二次登录会被阻止。通常的做法是阻止第二次登录。