我正在使用Spring开发一个应用程序。我在登录和注销方面遇到了麻烦。我使用登录凭据登录应用程序(例如,userName:john,pass:doe)并转到管理员页面,然后我从应用程序注销。但这次我使用不同的登录凭据(例如userName:jack,pass:white)进行登录。当我转到管理页面并调试我的应用程序@ModelAttribute(value = "myUser") User loggedInUser
时AdminController
显示旧的用户值。我不明白为什么会这样。有人可以帮忙吗?
我的源代码如下:
@Controller
@RequestMapping("/LoginController")
@SessionAttributes({"myUser"})
public class LoginController
{
private static String LOGIN_URL = "login/login_";
private static String INDEX_URL = "main/index";
@Autowired
private IUserService userService = null;
@RequestMapping("/login")
public ModelAndView login(@RequestParam(value="userName", required=false) String argUserName, @RequestParam(value="password", required=false) String argPassword, HttpServletRequest req)
{
ModelAndView modelAndView = new ModelAndView();
// Assume argUserName and argPassword not null
User loginUser = this.userService.getUser(argUserName, argPassword);
HttpSession ses = req.getSession();
// Assume loginUser not null
ses.setAttribute("myUser", loginUser);
modelAndView.setViewName(LoginController.INDEX_URL);
return modelAndView;
}
@RequestMapping("/logout")
public String logout(HttpServletRequest argReq, HttpServletResponse argResp) throws ServletException, IOException
{
HttpSession session = argReq.getSession(false);
Enumeration<?> attributeNames = session.getAttributeNames();
while(attributeNames.hasMoreElements())
{
String attrName = (String)attributeNames.nextElement();
if(session.getAttribute(attrName) != null)
{
session.setAttribute(attrName,null);
//session.removeAttribute(attrName);
attributeNames = session.getAttributeNames();
}
}
// close session
session.invalidate();
return LoginController.LOGIN_URL;
}
}
AdminController
@Controller
@RequestMapping("/AdminController")
@SessionAttributes({"myUser"})
public class AdminController
{
private static String SETTINGS_PAGE = "settings/index";
@RequestMapping("/index")
public ModelAndView index(@ModelAttribute(value = "myUser") User loggedInUser, HttpSession ses)
{
ModelAndView modelAndView = new ModelAndView();
Map<String, Object> map = new HashMap<String, Object>();
map.put("loggedInUserId", loggedInUser.getUserID());
map.put("userName", loggedInUser.getUserName());
modelAndView.addAllObjects(map);
modelAndView.setViewName(AdminController.SETTINGS_PAGE);
return modelAndView;
}
}
答案 0 :(得分:2)
对于初学者来说,@SessionAttributes
并非旨在将数据存储在不同控制器之间的会话中。其用途仅用于在请求之间存储同一控制器的数据。如果要在请求之间的会话中存储项目,请自行将它们存储在会话中,而不要依赖@SessionAttributes。注释的the javadoc中也提到了这一点(尽管可能有点含糊不清)。
如果要删除@SessionAttributes
缓存的对象,则不能简单地清除会话,但必须使用SessionStatus
对象(可以添加为参数)来标记这些对象的使用对象完成。
你的注销方法是详细的,简单地调用session.invalidate()
就足够了,但我想这是你尝试解决问题的方法之一。此外,当您使用Servlet 3.0容器时,只需调用request.logout()
即可(或与session.invalidate()
一起调用)
我的最终建议是使用Spring Security而不是尝试开发自己的安全解决方案。
答案 1 :(得分:2)
删除此注释
@SessionAttributes({"myUser"})