侧边栏壁纸
博主头像
快乐江湖的博客博主等级

更多内容请点击CSDN关注“快乐江湖”

  • 累计撰写 127 篇文章
  • 累计创建 33 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

第三章Java网络编程-第七节3:Cookie和Session

快乐江湖
2023-10-08 / 0 评论 / 0 点赞 / 4 阅读 / 32886 字

一:Cookie和Session

(1)Cookie

Cookie:是一种用于在Web浏览器和Web服务器之间传递数据的技术。当用户访问一个网站时,该网站可以通过在用户的浏览器中存储一个小文件来创建和使用Cookie。这个小文件包含有关用户在网站上的活动和偏好的信息。Cookie通常用于跟踪用户在网站上的行为、记录登录状态、存储购物车内容以及个性化用户体验等。当用户再次访问同一网站时,浏览器会将Cookie发送回服务器,从而使网站能够识别用户并提供相应的个性化服务。Cookie包含了键值对的信息,每个键值对表示一条数据。其中,键表示数据的名称,值表示数据的内容。除了键值对外,Cookie还可以包含一些其他属性,如过期时间、域名、路径等,用于控制其在浏览器中的行为。尽管Cookie在互联网上广泛使用,但也存在一些安全和隐私方面的考虑。因此,现代浏览器提供了控制Cookie的选项,用户可以选择是否接受、删除或限制Cookie的使用\

Cookie是通过在请求和响应报文中写入Cookie信息来控制客户端的状态,可以这样理解:客户端第一次请求后,服务器会下发一个装有客户信息的“身份铭牌”(也就是set-cookie),后续该客户端再次请求服务器的时候,只需要戴上“身份铭牌”,服务器就能认得然后自动完成认证

可以发现这样做是有很大的风险的,这也意味着在传输过程所有信息等于在“裸奔”,如果让一些不怀好意的人截获Cookie,就会造成很大的麻烦。为了解决Cookie的弊端,Session应运而生

(2)Session

Session:是一种服务器端的存储机制,用于在多个HTTP请求之间维持和跟踪用户会话状态。与Cookie不同,Session数据是存储在服务器上的,而不是在客户端浏览器中

客户端在第一次发送请求时,服务器会创建一个Session,同时会创建一个特殊的Cookie(它其实是一个nameJSEESIONID的固定值,valuesession对象的ID),然后将Cookie发送至客户端;当客户端第二次及以后发送请求时,会携带该nameJSESSION的对象,接着服务器会根据nameJSESSIONID的cookie的valuesessionid)去查询session对象,进行身份确认

所以在你登录一个网站的时候,如果服务器端使用的是Session,那么所有的数据都会保存在服务器上,客户端每次请求服务器的时候会发送当前会话sessionid,服务器则根据当前sessionid标识用户,以确定该用户的身份以及是否具有某种权限。由于数据存在服务器上面,所以相对安全

(3)关系

Cookie和Session共同协作,使得服务器能够跟踪和管理用户的会话状态。Cookie负责在客户端浏览器和服务器之间传递sessionid,而Session则负责存储和管理与用户相关的会话数据。这种组合使得网站能够提供个性化的服务、记录登录状态、存储购物车内容等功能

  • Cookie数据存放在客户端,Seesion数据存放在服务器
  • Session相较于Cookie安全
  • 由于Session考虑了安全,因此会影响服务器的性能
  • 单个Cookie在客户端的限制为3k
  • Cookie和Session经常会配合使用,但也不是说非得配合
  • 完全可以用Cookie来保存一些数据在客户端,这些数据不一定是用户身份信息,也不一定是tokensessioid
  • Session中的tokensessioid也不是非得要通过Cookie来传递

二:相关API

HttpServletRequest类中相关方法

  • Http Session getSession()
    • 如果参数为true:判断当前会话是否存在,如果不存在,就创建一个新的键值对并保存到哈希表中,然后把生成的sessionId返回给浏览器;如果存在,则直接返回对应的HttpSession对象
    • 如果参数为false:判断当前会话是否存在,如果不存在,直接返回null;如果存在则返回对应的HttpSession对象
  • Cookie[] getCookies():返回一个Cookie对象数组(因为可能有多个Cookie)

HttpServletResponse类中相关方法

  • void addCookie(Cookie cookie):将指定的cookie添加到响应中

HttpSession类中相关方法:一个HttpSession对象里面包含多个键值对,我们可以向HttpSession中添加任何我们需要的信息

  • Object getArrtibute(String name):返回在该Session会话中具有指定名称的对象,如果没有则返回null
  • void setAttribute(String name, Object value): 使用指定的名称绑定一个对象到该Session会话
  • boolean isNew(): 判断当前是否是新创建出来的会话

Cookie类中的相关方法:每个Cookie对象就是一个键值对

  • String getName():返回Cookie的名称(名称在创建之后不能改变)
  • String getValue():获取与Cookie关联的值
  • void setValue(String newValue):设置与Cookie关联的值

三:案例

(1)案例1:用户登录

如下图,当用户登录成功时创建Session,然后重定向的index,并显示欢迎信息。而如果用户没有登录或登录失败直接访问index,则由于没有Seesion,就会出现拒绝访问的信息

当然,如果将Cookie删除后,自然也就是拒绝访问了


IndexServlet.java:用于处理登录后跳转的主页

package login;  
  
  
import javax.servlet.ServletException;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.HttpSession;  
import java.io.IOException;  
  
@WebServlet("/index")  
// 登录成功后跳转到的主页  
public class IndexServlet extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 获取Session,这里的Session就是刚才在登录页时登录成功后创建出来的  
        HttpSession session = req.getSession(false);  
        // 表示登录失败或者就没有登录,没有这样的Session就不让访问  
        if(session == null) {  
            resp.setStatus(403);  
            resp.setContentType("text/html; charset=utf-8");  
            resp.getWriter().write("未登录,拒绝访问主页");  
        }  
  
        // 如果有Session,则去取出对应的用户名,并显示欢迎访问  
        String username = (String) session.getAttribute("username");  
        resp.setContentType("text/html; charset=utf-8");  
        resp.getWriter().write(username + "! 欢迎来到主页");  
    }  
}

LoginServlet.java:Servlet服务器

package login;  
  
import javax.servlet.ServletException;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.HttpSession;  
import java.io.IOException;  
  
  
@WebServlet("/login")  
public class LoginServlet extends HttpServlet {  
  
    // form表单数据将会提交到服务器  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 从请求中获取用户名和密码  
        String username = req.getParameter("username");  
        String password = req.getParameter("password");  
  
        // 验证  
        if ("zhangsan".equals(username) && "123321".equals(password)) {  
            // 成功  
            // 创建Session  
            HttpSession session = req.getSession(true);  
            // 使用session存储信息  
            session.setAttribute("username", "zhangsan");  
            // 让响应重定向到主页  
            resp.sendRedirect("index");  
        } else {  
            // 失败  
            resp.setStatus(403);  
            resp.setContentType("text/html; charset=utf-8");  
            resp.getWriter().write("登录失败,用户名或密码错误");  
  
        }  
  
  
    }  
}

login.html:登录页面(可自己设计)

<!DOCTYPE html>  
<html lang="en">  
  
<head>  
    <meta charset="UTF-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
    <title>登录页面</title>  
    <style>  
        * {  
            margin: 0;  
            padding: 0;  
        }  
  
        a {  
            text-decoration: none;  
        }  
  
        input,  
        button {  
            background: transparent;  
            border: 0;  
            outline: none;  
        }  
  
        body {  
            height: 100vh;  
            background: linear-gradient(#141e30, #243b55);  
            display: flex;  
            justify-content: center;  
            align-items: center;  
            font-size: 16px;  
            color: #03e9f4;  
        }  
  
        .loginBox {  
            width: 400px;  
            height: 364px;  
            background-color: #0c1622;  
            margin: 100px auto;  
            border-radius: 10px;  
            box-shadow: 0 15px 25px 0 rgba(0, 0, 0, .6);  
            padding: 40px;  
            box-sizing: border-box;  
        }  
  
        h2 {  
            text-align: center;  
            color: aliceblue;  
            margin-bottom: 30px;  
            font-family: 'Courier New', Courier, monospace;  
        }  
  
        .item {  
            height: 45px;  
            border-bottom: 1px solid #fff;  
            margin-bottom: 40px;  
            position: relative;  
        }  
  
        .item input {  
            width: 100%;  
            height: 100%;  
            color: #fff;  
            padding-top: 20px;  
            box-sizing: border-box;  
        }  
  
        .item input:focus+label,  
        .item input:valid+label {  
            top: 0px;  
            font-size: 2px;  
        }  
  
        .item label {  
            position: absolute;  
            left: 0;  
            top: 12px;  
            transition: all 0.5s linear;  
        }  
  
        .btn {  
            padding: 10px 20px;  
            margin-top: 30px;  
            color: #03e9f4;  
            position: relative;  
            overflow: hidden;  
            text-transform: uppercase;  
            letter-spacing: 2px;  
            left: 35%;  
        }  
  
        .btn:hover {  
            border-radius: 5px;  
            color: #fff;  
            background: #03e9f4;  
            box-shadow: 0 0 5px 0 #03e9f4,  
            0 0 25px 0 #03e9f4,  
            0 0 50px 0 #03e9f4,  
            0 0 100px 0 #03e9f4;  
            transition: all 1s linear;  
        }  
  
        .btn>span {  
            position: absolute;  
        }  
  
        .btn>span:nth-child(1) {  
            width: 100%;  
            height: 2px;  
            background: -webkit-linear-gradient(left, transparent, #03e9f4);  
            left: -100%;  
            top: 0px;  
            animation: line1 1s linear infinite;  
        }  
  
        @keyframes line1 {  
  
            50%,  
            100% {  
                left: 100%;  
            }  
        }  
  
        .btn>span:nth-child(2) {  
            width: 2px;  
            height: 100%;  
            background: -webkit-linear-gradient(top, transparent, #03e9f4);  
            right: 0px;  
            top: -100%;  
            animation: line2 1s 0.25s linear infinite;  
        }  
  
        @keyframes line2 {  
  
            50%,  
            100% {  
                top: 100%;  
            }  
        }  
  
        .btn>span:nth-child(3) {  
            width: 100%;  
            height: 2px;  
            background: -webkit-linear-gradient(left, #03e9f4, transparent);  
            left: 100%;  
            bottom: 0px;  
            animation: line3 1s 0.75s linear infinite;  
        }  
  
        @keyframes line3 {  
  
            50%,  
            100% {  
                left: -100%;  
            }  
        }  
  
        .btn>span:nth-child(4) {  
            width: 2px;  
            height: 100%;  
            background: -webkit-linear-gradient(top, transparent, #03e9f4);  
            left: 0px;  
            top: 100%;  
            animation: line4 1s 1s linear infinite;  
        }  
  
        @keyframes line4 {  
  
            50%,  
            100% {  
                top: -100%;  
            }  
        }  
    </style>  
</head>  
  
<body>  
<div class="loginBox">  
    <h2>login</h2>  
    <form action="login" method="post">  
        <div class="item">  
            <input type="text" required name="username">  
            <label for="">userName</label>  
        </div>  
        <div class="item">  
            <input type="password" required name="password">  
            <label for="">password</label>  
        </div>  
        <button class="btn" id="submitBtn">submit  
            <span></span>  
            <span></span>  
            <span></span>  
            <span></span>  
        </button>  
    </form>  
</div>  
</body>  
  
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>  
<script>  
    $(document).ready(function() {  
        $("#submitBtn").click(function(event) {  
            event.preventDefault(); // 阻止表单默认提交行为  
  
            var username = $('input[name="username"]').val();  
            var password = $('input[name="password"]').val();  
  
            $.ajax({  
                url: "login",  
                type: "post",  
                data: {  
                    username: username,  
                    password: password  
                },  
                success: function(response) {  
                    // 请求成功的处理逻辑  
                    alert("登录成功!");  
                },  
                error: function(jqXHR, textStatus, errorThrown) {  
                    // 请求失败的处理逻辑  
                    if (jqXHR.status == 403) {  
                        alert("用户名或密码错误,请重新输入!")  
                    }  
                }  
            });  
        });  
    });  
</script>  
</html>

(2)案例2:上传文件

如下图,在浏览器中点击提交按钮后将选择的文件提交给服务器,然后让服务器保存该文件(用由于这里的服务器在本地,所以带来的效果可能不那么明显)

A:相关API

HttpServletRequest类中相关方法

  • Part getPart(String name):获取请求中给定name的文件
  • Collection<Part> getParts():获取所有的文件

Part类中相关方法

  • String getSubmittedFileNamed():获取提交的文件名
  • String getContentType():获取提交的文件类型
  • long getSize():获取文件的大小
  • void write(String path):将提交的文件数据写入磁盘文件

B:代码

upload.html:上传文件页面

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>上传文件</title>  
</head>  
<body>  
  
<!--注意:使用form表单提交文件时必须加上 enctype="multipart/form-data--><form action="upload" method="post" enctype="multipart/form-data">  
    <input type="file" name="myfile">  
    <input type="submit" name="提交">  
</form>  
  
</body>  
</html>

uploadServlet.java:Servlet服务器

package upload;  
  
import javax.servlet.ServletException;  
import javax.servlet.annotation.MultipartConfig;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.Part;  
import java.io.IOException;  
  
@WebServlet("/upload")  
// 专门针对上传文件的注解  
@MultipartConfig  
public class UploadServlet extends HttpServlet {  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 这里参数中的 name 和input标签中的name一致  
        Part part = req.getPart("myfile");  
        // 获取文件名  
        System.out.println(part.getSubmittedFileName());  
        // 获取文件大小  
        System.out.println(part.getSize());  
        // 获取文件类型  
        System.out.println(part.getContentType());  
        // 保存文件  
        part.write("D:/programData/temp/test.jpg");  
    }  
}
0

评论区