【JavaEE】Cookie与Session的前后端交互-表白墙登录设计

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 就是在前后端配合下,感受Cookie的存在!

【JavaEE】Cookie与Session的前后端交互-表白墙登录设计

在Cookie的第一次认识是在这一篇博客:【JavaEE】HTTP应用层协议_s:103的博客-CSDN博客


博客片段:

b4a842520d244529bd712e3d9dc8a581.png

0db4a2f1d805435fb099d5ff0989b37b.png

而现在,就是在前后端配合下,感受Cookie的存在!


1. Cookie与Session


以上的内容是浏览器存储数据的Cookie机制,而Cookie中存储用户身份标识,而身份标识代表什么,应该是存在服务器那一端的~


而这就是后端的Session(会话)机制


而Session一般是在内存中存储的,也就是说服务器刷新就没了


Session则是一个哈希表,key为sessionId(浏览器Cookie在Session记录时产生的session对象的id),value则是对应的信息(小哈希表,Cookie的键值对)!

而这两个机制就是为了提高页面体验用的(暂时寄存信息)

他们之间只是“朋友”而非“伴侣”

完全可以用Cookie来保存一些数据来客户端,这些数据不一定是用户身份信息,也不一定是sessionId(别名token)

Session中的sessionId也不需要非得Cookie/Set-Cookie传递

目前不讲解其他的方式


5b8b6cb8459d4a70b09dd4b39ac58df5.png


在本版本中,用户信息在数据库中,简简单单的存储名字和密码~


1.1 后端doPost的实现


class User{
    public String name;
    public String password;
    public User() {
    }
    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }
}
@WebServlet("/login")
public class LogIn extends HttpServlet {
}



1.1.1 隐藏的全局变量

f4277ee993cd4b388b3a0a93fe9e4d66.png


而这个“全局变量”,就是一个哈希表


1.1.2 获取请求对应的HttpSession对象


这一点,方法内部帮你识别了请求中的Cookie

而其中就有一个属性:sessionId,用这个值就可以直接在总的Session里进行“查询哈希表”操作~


HttpSession session = req.getSession(true);
resp.setContentType("text/html; charset=utf8");//设置响应的字符集


getSession方法,顾名思义,可以获取req对应的session

传入true,不存在此请求的Cookie对应的session,则建立一个,返回新建立的session对象~

自然就帮我们给Cookie设置了sessionId了

传入false,不存在此请求的Cookie对应的session,返回null~

而这个session是引用,其改变殃及总的大Session!

ecbd54183629471193d9ff51a73a2e32.png


1.1.3 约定前后端交互方式


本文重点在于登录页面设计,所以在交互的时候,传递的信息仅仅是用户名和密码~

我用的ajax构造的json格式的字符串~


json前后端相关操作讲解博客:【JavaEE】简单前后端分离小项目-表白墙_s:103的博客-CSDN博客

全局性质的变量:ObjectMapper objectMapper = new ObjectMapper();


User user = objectMapper.readValue(req.getInputStream(), User.class);


1.1.4 验证用户名与密码是否正确


用这个构造出来的对象的属性,在数据库里查询验证即可


JDBC编程基础博客:【MySQL】Java-JDBC_s:103的博客-CSDN博客

String username = "'" + user.name + "'";//获取key对应值
String password = "'" + user.password + "'";
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/Loves?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("mmsszsd666");//这是俺的微信号,欢迎添加,相互学习!
try {
    Connection connection = dataSource.getConnection();
    String sql = "select * from users where name = " + username + "and" + password + ";";
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    //这里的Set并不是,对象为Love的Set集合,而是一个迭代器!
    ResultSet set = preparedStatement.executeQuery();
    //迭代他(是next方法而不是hasNext)
    if(set.next()) {
        //有这个用户
    }else {
        //没有这个用户
    }
    set.close();
    preparedStatement.close();
    connection.close();
} catch (SQLException e) {
    e.printStackTrace();
}


6fe4b2b7f43741f69eece54eb7c0c431.png


1.1.5 没有这个用户的情况


resp.getWriter().write("No");


直接在resp正文中写个“No”


1.1.6 有这个用户的情况


session.setAttribute("username", username);
resp.getWriter().write("欢迎" + username + "!");


调用session.setAttribute方法,向session(小哈希表)中添加键值对


内部则调用了setCookie这样的方法,去设置客户端的Cookie

返回响应里则多了set-Cookie属性

Attribute就是属性的意思


在resp正文中写,欢迎词(是动态的,由用户名决定)


c694e8e025894072b43cde0b8e7a145d.png


1.2 后端代码doGet实现


1.2.1 获取请求对象的HttpSession对象


HttpSession session = req.getSession(false);
resp.setContentType("text/html; charset=utf8");//设置响应的字符集


在这里,无需进行不存在自动创建的逻辑,因为不存在就是不存在,这里又不可能填入信息~

e1c5b71739f94491ace7b8939d45663e.png


1.2.2 非空校验


此请求的Cookie在这里没有记录,session的值就为null


响应写入“No”,结束方法(return)


6337932cd0e747c9ad35a32cd4b9a7d7.png

调用session的getAttribute方法,传入key值,查找value


如果这个value为null,则响应写入No,结束方法(return)

value为空代表session中不存在key为username的键值对,为什么呢

5263e0df80984bf3969b23ceaf8fa2e7.png


这是因为在doPost建立session的时候,是在一开始,其中是有可能没有进行添入的操作的

而这样子做,是为了给这一个客户端发来的请求,“提前留位置”

if(session == null) {//不存在这条记录
    resp.getWriter().write("No");
    return;
}
String username = (String)session.getAttribute("username");
if(username == null) {
    resp.getWriter().write("No");
    return;
}


1.2.3 用户名在session中查得到


向响应中写入成功访问含义的字符串(动态) -> 报喜


resp.getWriter().write("欢迎" + username + "!");


1.3 前端代码


前端页面分为:


表白墙主页 wall.html

登录页面 login.html

其中登录页面我直接抄了之前博客系统页面的“博客登录页”:前端综合项目-个人博客网页设计_s:103的博客-CSDN博客


效果:

2f23edfe4e3e4d97831388af4c0150f5.png


改动:(导航栏删了一些信息)


form表单去掉了

点击submit按钮,调用js函数login()

37afc4dc8f9346a69dd0af1a9feeaefa.png


1.3.1 表白墙主页


如果浏览器Cookie里的信息在服务器中有记录 --> 正常

否则 --> 登录异常(跳转到登录页面)

这也是为什么刚才我要在body里写No的原因,就是为了判断这两种情况


jQuery.ajax({
    type: "get",
    url: "login",
    success: function (body) {
        if (body == "No") {
            window.location.href = "login.html";
        }else {
            alert(body);
        }
    },
});


这条语句需要在每次刷新的时候执行~

此代码发送给/login程序一个get请求,返回一个响应


body为No,跳转到登录页面(login.html)

正常,弹框


a9263efcc5f44c9aa2310f7b352b7311.png


1.3.2 表白墙登录页


login函数

在此函数内要获取username和password(进行非空校验),并且构造json对象,转化为json字符串,用ajax构造请求,传给客户端


到这里,你可能意识到了,虽然get和post是没有本质区别的,但是一个服务器的不同请求,是要进行不同逻辑的,则才有了不同的请求方法来区分,后端可以以此区分,进行不同逻辑


function login() {
    var name = jQuery("#username");
    var password = jQuery("#password");
    if (name.val().trim() == "") {
        alert("请输入是谁!");
        name.focus();
        return;
    }
    if (password.val().trim() == "") {
        alert("请输入想对谁说!");
        password.focus();
        return;
    }
    var keyValue = {
        name: name.val(),
        password: password.val(),
    };
    jQuery.ajax({
        type: "post",
        url: "login",
        contentType: "application/json; charset=utf8",//设置body的格式为json
        data: JSON.stringify(keyValue),//转换json对象为json字符串
        success: function (body) {
            if (body == "No") {
                alert("用户名或者密码错误!");
            } else {
                window.location.href = "wall.html";
            }
        },
    });
}


同样的,通过响应是否为No去判断

No,密码输入错误,弹框

非No,跳转到表白墙主页(登录成功)


7fdd8e30b832400d83098bed4b694ae9.png

发送get请求

在此ajax语句中,需要向后端发送get请求,判断浏览器的Cookie的信息是否对的上(对的上则自动直接跳转到表白墙主页,不然的话,则说明登录失效)


jQuery.ajax({
    type: "get",
    url: "login",
    success: function (body) {
        if (body != "No") {
            window.location.href = "wall.html";
        } else {
            alert("登录失效");
        }
    },
});

1bde851ea4ee4b97a798c7ccd0c3cfe3.png



1.4 目录结构


ddcbc61120174b8b99e22e8ab609a5a4.png


2. 测试


虽然一个设备只能登录一个账号,但是多个设备可以登录同一个账号,这也无大碍~

image.png

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
存储 自然语言处理 API
Session、cookie、token有什么区别?
Session、cookie、token有什么区别?
24 1
|
2月前
|
存储 开发框架 NoSQL
ASP.NET WEB——项目中Cookie与Session的用法
ASP.NET WEB——项目中Cookie与Session的用法
36 0
|
2月前
|
存储 安全 API
Cookie,Session和Token
Cookie,Session和Token
|
15天前
|
存储 JSON 安全
|
1月前
|
数据采集 存储 安全
登录态数据抓取:Python爬虫携带Cookie与Session的应用技巧
登录态数据抓取:Python爬虫携带Cookie与Session的应用技巧
|
1月前
|
存储 安全 搜索推荐
Django中Cookie和Session的使用
Django中Cookie和Session的使用
21 0
|
1月前
|
存储 安全 对象存储
Cookie和Session的区别:从原理到应用
【2月更文挑战第18天】
58 6
|
1月前
|
存储 搜索推荐 安全
【Web开发】cookie和session
【Web开发】cookie和session
|
2月前
|
存储 搜索推荐 安全
Java Web开发中的会话管理:Cookie与Session对比
Java Web开发中的会话管理:Cookie与Session对比
|
2月前
|
存储 前端开发 Java
【JavaEE进阶】 获取Cookie和Session
【JavaEE进阶】 获取Cookie和Session