今天我们来聊一聊我在学习springmvc中,编写一个用户注销功能,废话不多说,咱直接上图:
这是前端登录成功后的主界面
前端代码如下:
<body>
<p>主界面,欢迎【${sessionScope.user.username}】回来!</p>
<h3>
姓名:${sessionScope.user.username}<br/>
年龄:${user.age}<br/>
性别:<c:if test="${sessionScope.user.sex ==1}">男</c:if>
<c:if test="${sessionScope.user.sex == 0}">女</c:if><br/>
出生日:${sessionScope.user.birthday}
</h3>
<button><a href="${pageContext.request.contextPath}/logOut">退出</a></button>
</body>
对应的Controller,我只截取了其中的用户注销方法,我是采用的@SessionAttributes注解来实现添加user到session域中。
@Controller
@SessionAttributes({"user"})
public class UserController {
@RequestMapping(value = "/logOut", method = RequestMethod.GET)
public String logOut(HttpSession session) {
// todo 退出登录有问题
System.out.println("执行了controller");
session.removeAttribute("user");
// session.invalidate();
System.out.println("user的信息 = " + session.getAttribute("user"));
return "login";
}
}
但是当我们点击注销按钮后,返回到主界面,点击刷新,我们依然能够看到user的基本信息,说明我们的controller注销方法清除session域失效,上述代码我们打印结果:
我们可以看到,这里user的信息获取确实是为null,但是在前端主页上却又能显示,这就有点反常,这个bug卡了我一天。
直到我看到了百度上一位大佬的描述,说是@SessionAttributes的问题,这个东西我也是只会皮毛,其内部的原理其实并不理解。
关于此注解的详细解释:从原理层面掌握@SessionAttributes的使用
从此篇文章我们可以得知 ,需要使用@SessionAttributes( ),方法来实现对session域的清除
修改后的controller的代码如下:
@Controller
@SessionAttributes({"user"})
public class UserController {
@RequestMapping(value = "/logOut", method = RequestMethod.GET)
public String logOut(SessionStatus sessionStatus) {
// todo 退出登录有问题
System.out.println("执行了controller");
sessionStatus.setComplete();
return "login";
}
}
注销后的主界面:
我们可以看到页面中并没有显示user的基本信息,则我们可以确定已经删除了session域的user。
验证成功!
总结:
- @SessionAttributes需要清除时,使用SessionStatus.setComplete(),来清除。
- 值得注意的是它只清除@SessionAttributes的session,不会清除HttpSession的数据。
@SessionAttributes
指的是Spring MVC
的Session
。向其中添加值得时候,同时会向HttpSession
中添加一条。- 在
sessionStatus.setComplete()
的时候,会清空Spring MVC
的Session
,同时清除对应键的HttpSession
内容,但是通过,request.getSession.setAttribute()
方式添加的内容不会被清除掉。 - 其他情况下,
Spring MVC
的Session
和HttpSession
使用情况相同。