延申上一篇的2周自动登录功能java登录验证码、2周内自动登录例题、注销
一、现有问题
- HTTP协议是无状态的,不能保存每次提交的信息
- 如果用户发来一个新的请求,服务器无法知道它是否与上次的请求有联系
- 比如登录:点击登录进入首页,而每一次的跳转都是一个新的请求,无法得知是否登录过,跳转到首页,我只知道你点击登录按钮,发送的请求是访问首页,而这个时候,是不知道你之前登录过的数据的
- 状态管理就是将你web服务器和浏览器交互过程中,所涉及的涉及(即状态)保存下来
二、状态管理分类
- 客户端状态管理技术:将状态保存在客户端。代表性的是Cookie技术
- 服务器状态管理技术:将状态保存在服务器端。代表性的是Session技术
三、2周内免登录问题
- 就是在Servlet页面:UserController的login方法里面,把用户登录的username和password存在客户端,注意将状态保存在客户端,所以我们要用Cookie
- 登录数据是保存在客户端的,所以我们在Web服务器端写一个filter页面,对login.jsp页面进行过滤,
- 该filter页面就是获取客户端的Cookie,如果没有数据,说明没有登录过,有数据,那就获取数据(username和password)并实现自动登录
- filter页面:AutoFilter,implements了Filter,@WebFilter(value="/login.jsp")
- 在下一次客户端再次访问login登录页面的时候
- 有filter页面对login.jsp进行过滤
- 如果有数据直接自动登录并跳转到首页
四、Cookie的使用
4.1 Cookie的创建
Cookie ck = new Cookie(name,value);
- 实现自动登录
- 用户填写的username和password
- String content= username+":"+password
- 把content保存在cookie里,name命名为autoLoginUser(自动登录用户)
- 创建Cookie如下
Cookie ck = new Cookie("autoLoginUser",content);
4.2 设置Cookie的访问路径
- 可以指定某个Servlet可以访问这个Cookie
- 代码如下
ck.setPath("/user");
- 将来可以访问上面定义的autoLoginUser的只能是/user或者的/user下面的资源
- 给个“/”就是所有路径都可以访问
4.3 设置Cookie的生命周期
- 取值有3种:>0会认为单位为秒,比如给2*24*60*60,就是2天
- =0 浏览器关闭
- <0 浏览器关闭就没有了,临时存储
- 实现2周自动登录代码如下
ck.setMaxAge(14*24*60*60);//这里设置生命周期为2周
4.4 添加ck到response对象,响应时发送给客户端(就是浏览器)
response.addCookie(ck);
全部代码
String content = username+":"+password;
Cookie ck = new Cookie("autoLoginUser",content);
ck.setPath("/");//所有路径都可以访问
ck.setMaxAge(14*24*6*60);//生命周期为14天
response.addCookie(ck);
五、AutoFilter页面获取Cookie
- 重点就是request.getCookies();获取的是一个cookie数组
- Cookie[] cookies = request.getCookies();
- foreach遍历上面的数组
- 找到name=autoLoginUser的cookie,获取其value值
if(ck.getName().equals("autoLoginUser")){
content = ck.getValue();
}
- 然后对获取的value(赋值给了content),也就是content进行操作
- 因为刚刚给的是username+":"+passwrod,所以还需要对这个字符串进行分割成字符数组
if (content != null) {
String[] str = content.split(":");
String username = str[0];
String passwrod = str[1];
}
- 接下来就是通过cookie获取的username和password实现登录
- 调用业务逻辑层UserServiceImpl的login方法
UserService userService = new UserServiceImpl();
User user = userService.login(username,password);
if(user!=null){
}
- 如果这个查到的user不为空,就把user保存到web服务器端,所以用到Session保存user;如果为空,就是没有登录过,直接pase就行了
- HttpSession session =request.getSession()
- 这里还有个重点,Filter的doFilter方法的参数:req和resp 是ServletRequest、ServletResponse类型,所以还有强转为HttpServletRequest、HttpServletResponse 类型
if(user!=null){
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
HttpSession session = request.getSession();
session.setAttribute("autoLoginUser",user);
response.sendRedirect(request.getContextpath()+"/index.jsp");//跳转到首页
}else{
//没有登录过
chain.doFilter(req,resp);
}
六、AutoFilter页面完整代码
import com.itqf.entity.User;
import com.itqf.service.UserService;
import com.itqf.service.impl.UserServiceImpl;
import com.itqf.utils.Constants;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter("/Login.jsp")
public class AutoFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
String content = null;
for (Cookie cookie : cookies) {
//如果获取到cookie的名字对于Constants.AUTO_NAME
if (cookie.getName().equals(Constants.AUTO_NAME)) {
//就获取这个cookie的value值
content = cookie.getValue();
}
}
if (content != null) {
String[] split = content.split(Constants.FLAG);
String username = split[0];
String password = split[1];
UserService userService = new UserServiceImpl();
User user=userService.login(username, password);
if (user != null) {
HttpSession session = request.getSession();
session.setAttribute("loginUser",user);
HttpServletResponse response = (HttpServletResponse)resp;
response.sendRedirect(request.getContextPath()+"/index.jsp");
}else{
chain.doFilter(req, resp);
}
}
} else {
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
}