我在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每次都是空,不可能实现我想要的功能。那要怎么写?我现在都糊涂了。
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每次都是空,不可能实现我想要的功能。那要怎么写?我现在都糊涂了。
个人想法,只是个建议
涉及到竞争资源、定时器等操作。
放到session中?每次用户请求过来,重新产生session,这个session肯定与第一次产生的session不同,怎么比较?
能不能明白点,是不是我理解错了?还是?谢谢你了
把用户信息存放到哪?因为每次用户请求过来,会重新生产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()方法中,所以每次请求过来的时候,会重新产生,所以怎么比较?
把全局context放哪?每次用户请求过来,LoginAction都会执行,那就没效果了啊。大家帮帮我!能不能详细的说下。
全局context,就是生命周期贯穿你的整个应用启动到结束的一个对象。你可以使用一个static的对象或者别的什么的。总之保证它的生命周期和唯一性就行了。
然后还写一个管理类,定时去检查用户是不是在线,多长时间没有操作将自动清除
3. web.xml配置Listener,你先写吧!不要用表什么的,那是很烦,而且不准确。就管理session就可以了
用session怎么管理,我的LoginAction.java就是我贴出来的,在发贴那里,说实话我认为我那样写肯定是错的,因为每当有用户请求过来,就会产生session,把sessionID放到 Map applicationMap中,所以如果再有用户请求过来,又会重新产生session,那应该怎么写?帮个忙?
/**
* @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;
}
写起来比较多,你自己实现一下吧
这是我一开始的想法,就是把用户产生的sessionID来判断用户是否已经登录了。结果已失败而告终。
◆Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
◆Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题) ---------------------Struts2 新特性-------------------------------------------------------------你可以在Struts2里设置属于自己用户的变量啊
当用户登录时先从Context中检查Map中有无此username的KEY,来判断用户是否登录.
由于Map中存放的value是用户的session,所以还可以使后登陆用户踢掉先前用户.
不过要在工程下加一个session的监听器,当用户session失效时要及时把用户在Context的Map里面的K/V移除掉.
不然的话在context中存放对应用户应该是最直观的,但是数据量是个问题,这种解决方案不够抽象和彻底
哪怕每次执行execute()方法,userSession也不会为空,所以你只要userSession.put("userName",userName)存进去便可,
你的userSession.put() 和applicationSession.put 写错位置了,应该要登陆后才能put,登陆成功后,再执行execute()可直接 userSession.containsKey(userName)
对于你所说“哪怕每次执行execute()方法,userSession也不会为空,所以你只要userSession.put("userName",userName)存进去便可,”,不行啊,我去从userSession中去比较的时候,一直都没发现该用户,而且还是可以登录,然后我就把值给输入出来了,全部为空。为什么说userSession在服务器上没关闭就不会为空?是真的吗?是不是自动等session过期还是?
对于你后面所说的“你的userSession.put() 和applicationSession.put 写错位置了,应该要登陆后才能put,登陆成功后,再执行execute()可直接 userSession.containsKey(userName)”,说得很正确,这代码我写错了,但是问题还是归咎于我前面的问题,因为我输入userSession中的内容,发现为空,所以根本不可能会在userSession中找到找到相关的登录信息。
作为单个类的静态变量,应该就可以了
在线访问量太大的话,推荐在数据库中多设立个字段,如果访问量少的话就你这个方法就可以了,或者可以参考spring的单点登录
在页面上写 用js 访问session的代码(可以使用ajax)(用定时器 定时访问当前登录用户的session,保持 session的可用性)。
当浏览器异常退出,或者被关闭, session将不会再被访问到,这样session超时10秒,就会销毁。 或者用户注销 ,服务器主动销毁session。当一个用户登录的时候 只要浏览器没有被关闭,session应该是一直都有效的。 只要用户一关闭浏览器。过十秒后,session就会超时销毁。当一个用户已经登录,这个账户再次登录的时候,只需判断是否在session存在。。如果存在 则是已经登录 不存在则没有登录 这样就可以处理很多的异常情况,例如:浏览器被任务管理器强制关闭。。