Cookie和Session实现保存登录状态免登录。

  首先Cookie和Session都是为了状态管理,HTTP协议是无状态的,不能保存每次提交的信息,即当服务器返回与请求相对应的应答之后,这次事务的所有信息就丢掉了。
  如果用户发来一个新的请求,服务器无法知道它是否与上次的请求有联系。
  对于那些需要多次提交数据才能完成的Web操作,比如登录来说,就成问题了。所以需要状态管理也就是通过Cookie和Session。

一.Cookie

1. 什么是Cookie?
   用我的理解来说,浏览器A在第一次请求服务器B的时候,服务器B会为该浏览器A创建一个Cookie,并在响应时候把这个Cookie一同返回给浏览器A,这样A在请求数据不变的情况下再次请求服务器B的时候会带着这个Cookie,这样服务器B当接收A请求时会辨识出这个Cookie,明白A是访问过B的并可能存储着属于A的数据(在这个过程中存在着session的问题稍后讲解)。

2. Cookie持续多久呢?
可以通过setMaxAge()方法设置Cookie存在时间。
取值说明:

0有效期,单位秒
=0失效
<0内存存储

二.Session
1. 什么是Session
  我的理解,Session是为了给浏览器在服务器端储存自己独有数据的一个集合,只是在服务器端。通过setAttribute()方法存数据,getAttribute()方法取数据。

2.Session持续多久呢?

默认不设置的话保持30分钟。
有两种设置Session的方法:
(1)setMaxInactiveInterval()方法,单位秒
(2)在web.xml中配置 ,单位分钟

  <session-config>
    <session-timeout>20</session-timeout>
  </session-config>

三.用户登陆过程中的cookie和session保持过程
过程
  假设没有设置其他cookie情况下,A在第一次访问B时,B会为A创建一个属于A的session,并在B响应A时通过cookie保存sessionid响应给A。这样A在第二次访问B的时候,A带着cookie(此时里面有sessionid)请求B,B收到请求后会通过cookie的sessionid辨识出属于A的session,这就是整个过程。

四.Cookie和Session实现用户登录保存用户登录状态一定时间免登陆。

1.设计思路:
  首先,用户登录成功后保存用户登陆的用户名到Cookie,同时设置Cookie的有效时间,在下次用户想免输入登陆时,直接判断Cookie是否含有该用户的用户名,如果有则直接登陆不需要输入,否则需要重新输入用户名和密码。
  
2.代码实现:
  为了大家看着方便,我尽可能把所有servlet分开写了。
(1)KeepLoginServlet(用户登录)
  

@WebServlet("/keeploginservlet")
public class KeepLoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public KeepLoginServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();

        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        // 从session中获取验证码
        String vcode = (String) session.getAttribute("vcode");

        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String code = request.getParameter("code");

        PrintWriter out = response.getWriter();

        // System.out.println("输入的code:"+code);
        // System.out.println("生成的vcode:"+vcode);

        if (!vcode.equals(code)) {
            out.write("<html>"
                    + "<head><script type='text/javascript'> alert('验证码错误!');location='login.html';</script></head>"
                    + "<body></body></html>");
            return; // 不继续执行,重新返回login.html页面
        }

        if ("123".equals(username)) {
            if ("123".equals(password)) {

                // 创建cookie并将成功登陆的用户保存在里面
                Cookie cookie = new Cookie("username", username);
                cookie.setMaxAge(60); // 设置一分钟有效
                response.addCookie(cookie); // 服务器返回给浏览器cookie以便下次判断

                response.sendRedirect(request.getContextPath() + "/index.html"); // 重定向到index.html
            } else {
                out.write("<html>"
                        + "<head><script type='text/javascript'> alert('密码错误!');location='login.html';</script></head>"
                        + "<body></body></html>");
                return;
            }
        } else {
            out.write("<html>"
                    + "<head><script type='text/javascript'> alert('不存在该用户!');location='login.html';</script></head>"
                    + "<body></body></html>");
            return;
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

  在这判断用户输入是否正确,因为是测试,所以用户名和密码写死都是123,验证码是一个工具类下面会给出代码,如果用户登录成功则将这个用户保存到Cookie里,设置过期时间为1分钟,以便下次免登陆。

(2)KeepLoginServlet(验证码)
  这里为了节省空间直接给出doGet方法,这里有一个验证码的jar包ValidateCode .jar非常方便大家可以自行查找。地址是(@WebServlet(“/vcodeservlet”))
  

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();

        //创建验证码图片流
        ValidateCode validateCode = new ValidateCode(120,50,4,20);
        validateCode.write(response.getOutputStream());

        //将验证码存入session中
        session.setAttribute("vcode", validateCode.getCode());
    }

(3)FindCookieServlet(判断用户是否可以免登陆)
  这里是实现的逻辑是:遍历所有cookie看是否含有username,如果含有username说明用户登陆过,可以免输入直接登陆。地址是(@WebServlet(“/dindcookieservlet”))
  

protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        boolean flag = false;
        PrintWriter out = response.getWriter();

        // 判断cookie是否有username,如果有代表登陆过
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println(URLDecoder.decode(cookie.getName(), "utf-8"));
                if (URLDecoder.decode(cookie.getName(), "utf-8").equals("username")) { // 表明已经登陆过了,就直接跳转了
                    flag = true;
                }
            }
        }

        if(flag) {
            response.sendRedirect(request.getContextPath() + "/index.html");

        }else {
            out.write("<html>"
                    + "<head><script type='text/javascript'> alert('没有登陆过,请登录!');location='login.html';</script></head>"
                    + "<body></body></html>");
        }


    }

(4)ReturnClearCookie(清除用户保存的cookie)
  Cookie是没有直接删除指定cookie的方法的,所以我可以找到cookie里的username并把他的有效时间设置成0秒,这样间接实现了删除Cookie里的username。地址是(@WebServlet(“/returnclearcookie”))。
  

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //这里就是把username的cookie设置成0秒有效期,就是直接删除掉了
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println(URLDecoder.decode(cookie.getName(), "utf-8"));
                if (URLDecoder.decode(cookie.getName(), "utf-8").equals("username")) { // 表明已经登陆过了,就直接跳转了
                    cookie.setMaxAge(0);
                    response.addCookie(cookie);
                }
            }
        }
response.sendRedirect(request.getContextPath()+"/login.html");
    }

(5)两个页面
  login.html
  

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页面</title>
<style type="text/css">
.dv_error {
    color: red;
}
</style>
</head>
<body>
    <form action="/myday13_zhuangtaiguanli/keeploginservlet" method="post">
        <label>账号:</label><input type="text" id="username" name="username"><br />
        <label>密码:</label><input type="password" id="password" name="password"><br />
        <label>密码:</label><input type="text" id="code" name="code"><img id="img1" src="/myday13_zhuangtaiguanli/vcodeservlet" onclick="changeImg()" /><a href="javascript:void(0)" onclick="changeImg()">看不清换一张</a><br />
        <input type="button" onclick="check()" value="登录">
        <label><a href="/myday13_zhuangtaiguanli/dindcookieservlet" >已经登陆,直接登陆</a></label>
    </form>
    <script type="text/javascript">
         function check(){
             var username = document.getElementById("username")
             var password = document.getElementById("password")
             var code = document.getElementById("code")
             if(username.value == ""){
                 alert("请输入用户名")
             }else if(password.value == ""){
                 alert("请输入密码")
             }else if(code.value == ""){
                 alert("请输入验证码");
             }else{
                 document.forms[0].submit()
             }
         }
         function changeImg(){
             var img1 = document.getElementById("img1")
             img1.src="/myday13_zhuangtaiguanli/vcodeservlet?num"+Math.random();
         }
    </script>
</body>
</html>

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>欢迎登录...</h1>
<a href="/myday13_zhuangtaiguanli/returnclearcookie">退出登陆并不保留登陆信息</a><br/>
<a href="login.html">退出登录,但5分钟内免登陆</a>
</body>
</html>

五.测试结果
测试
  这是第一次登陆成功结果,通过开发者工具可以清楚看到,Cookie保存了username,以便下次判断。


测试2
  这是免登陆的结果截图,可以清楚看到,Cookie里是有username的,所以可以直接跳转进来。


这里写图片描述
  这是点击清除Cookie退出或Cookie过期时,点击免输入的结果,细心观察可以看到,此时Cookie已经没有username了,并且sessionid是没有变的。所以是登陆不进去需要重新输入的。

六.总结
  在Servlet里Cookie和Session是一个非常重要的概念,熟悉Cookie和Session的过程和应用场景是非常必要的,也要了解两者的关系。
  一口气写完,想必有多处不足和失误,欢迎提出疑惑。也欢迎大家随时沟通交流。

猜你喜欢

转载自blog.csdn.net/a754895/article/details/82632747