表白墙完善(数据库,前端,后端Servlet),再谈Cookie和Session。以及一个关于Cookie的练习小程序

目录

表白墙引入数据库 

再谈Cookie和session

得到Cookie

​编辑

设置Cooie

使用Cookie编写一个登入的小界面


表白墙引入数据库 

1.先引入数据库的依赖(驱动包),5.1.49

pom.xml中,在之前的两个之前,再去添加一个

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.49</version>
</dependency>

2.创建本地的数据库

create table messageWall(`from` varchar(20),`to` varchar(20),message varchar(1024));

3.之前的代码中有一段可以删掉了

 //此处把消息保存到内存中(一旦重启服务器,内存数据就会消失了。更科学的做法,应该是保存到数据库里面)
    private List<Message> messageList=new ArrayList<>();

这个代码需要删除,因为我们已经决定使用数据库去存储了,就不需要本地去存了。

 完整代码

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

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.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

class  Message{
    public String from;
    public String to;
    public String message;

    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    //首先要把一个json转化为java对象
    private ObjectMapper objectMapper=new ObjectMapper();
    //此处把消息保存到内存中(一旦重启服务器,内存数据就会消失了。更科学的做法,应该是保存到数据库里面)
    private List<Message> messageList=new ArrayList<>();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //1.需要能够读取请求body,转换成java对象
        Message message=objectMapper.readValue(req.getInputStream(),Message.class);
        //2.得到message之后,需要把message保存到服务器中
        try {
            save(message);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println("服务器收到message:"+message.toString());
        //3.返回响应,(其实没啥大必要,主要是返回一个200ok就行,body可以没有)
        resp.setStatus(200);                          //设置成功状态码,会更加清晰
        resp.getWriter().write("ok");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Message>messageList= null;
        try {
            messageList = load();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        //1.把内存中的这些Message,组织成json格式,返回到响应中
       String respJson=objectMapper.writeValueAsString(messageList);
       //这个代码十分关键,告诉浏览器,返回的响应的body是json格式(utf8编码)
       resp.setContentType("application/json; charset=utf8");
       resp.getWriter().write(respJson);
        // 2.针对List/数组这种,jackon会自动把数据整理成json数组,里面每个对象,又会被jsckon转换成{}json对象(json对象属性名字,也是和Message类的成员名字对应的)

    }
    private void save(Message message) throws SQLException {
        //通过jdbc从数据库中存储数据。
        DataSource dataSource=new MysqlDataSource();
        //useSSL=false 此处的SSL就是HTTPS中的加密方案
        ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/message?characterEncoding=utf8&&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("lcl15604007179");
        //2.建立链接
        Connection connection=dataSource.getConnection();
        //3.构造SQL
        String sql="insert into messageWall values(?,?,?)";
        PreparedStatement statement=connection.prepareStatement(sql);
        statement.setString(1, message.from);
        statement.setString(2, message.from);
        statement.setString(3, message.from);
        //4.执行SQL
        statement.executeUpdate();
        //5.释放资源,关闭连接
        statement.close();
        connection.close();
    }
    private List<Message> load() throws SQLException {
        //通过jdbc,从数据库读取数据
        //1。创建数据源
        DataSource dataSource=new MysqlDataSource();
        ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/message?characterEncoding=utf8&&useSSL=false");
        ((MysqlDataSource) dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("lcl15604007179");
        //2.建立连接
        Connection connection= dataSource.getConnection();
        //3.构造SQL
        String sql="select *from messageWall";
        PreparedStatement statement=connection.prepareStatement(sql);
        //4.执行SQL
        ResultSet resultSet= statement.executeQuery();
        //5.遍历结果集合
     List <Message> messageList=new ArrayList<>();
     while (resultSet.next()){
         Message message=new Message();
         message.from=resultSet.getString("from");
         message.to=resultSet.getString("to");
         message.message=resultSet.getString("message");
         messageList.add(message);
     }
     //关闭连接,释放资源
        resultSet.close();
        statement.close();
        connection.close();
        return messageList;



    }





}

我们可以知道,表白墙上的东西,即使你关闭服务器,我们的数据也是保存的,这也是游戏停服了但是你的数据不丢失的原因。

再谈Cookie和session

Cookie是浏览器在本地持久化存储数据的一种机制

1.Cookie的数据从哪里来?

服务器返回给浏览器的

2.Cookie的数据长什么样子?

Cookie中是键值对结构的数据,并且这里的键值对都是程序员自定义的。

3.Cookie有什么用

Cookie可以在浏览器这边存储一些临时性数据

其中最典型的一种使用方式,就是用来存储“身份标识”

sessionId->Cookie和Session之间的联动了

4.Cookie到哪里去

Cookie的内容会在下次访问该网站的时候,自动被带到HTTP请求中

5.Cookie怎么存储的

浏览器按照不同的域名分别存储Cookie域名和域名之间不能打扰。

Cookie存储在硬盘上的

Cookie存储往往会有一个超时时间(看浏览器不同而定,支付宝很短,安全)

得到Cookie

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/getcookie")
public class GetCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName() + ":" + cookie.getValue());
            }
        } else {
            resp.getWriter().write("当前请求中没有cookie");
        }
        resp.getWriter().write("ok");
    }
}

设置Cooie

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/setcookie")
public class SetCookieServlet extends HttpServlet {
    //期望通过doGet方法,把一个自定义的cookie数据返回到浏览器这边。
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie=new Cookie("date","2023-09-23");
        resp.addCookie(cookie);
        Cookie cookie1=new Cookie("time","19:55");
        resp.addCookie(cookie1);
        resp.getWriter().write("setCookie ok");
    }
}

我们需要是先设置Cookie之后,就可以此时拿到Cookie的内容,当然Cookie里面的数据,只是在浏览器休息休息,真正发挥作用,还是得在服务器这边的逻辑生效的。

Cookie结合Session实现登入效果,此时就能更清楚的看出来

sessionId是一个广义的概念,不同的库中具体实现过程会有一些细节的差异,在Servlet里,把这个属性具体叫做JSESSIONID

getSession背后做的事情(会话,就相当于账户,用户和服务器的交流,之前有没有这个账户)

1.读取请求中的Cookie,看Cookie里面是否有JESSIONID属性,以及值是什么,如果没有,就认为需要创建新的会话,如果有,就拿着这个ID去查询当前的session是否存在

要是session存在,就直接返回该session

要是session不存在,就准备创建新的会话。

2.如果当前确实需要创建会话,就会创建一个Session对象,同时生成唯一的一个JESSIONID,以JSESSIONID为key,SESSION对象为value,把这个键值对插入到服务器上述的哈希表中

3.刚才生成的JESSIONID又会通过addCookie方法,加入到响应中,此时响应里就会带有Set-Cookie字段,这里的值就是JSEEION=xxxxxxx通过响应,就把JSESSIOID返回到浏览器这边了。

这一行小小的,能量大大的🙉🙉🙉

 HttpSession session=req.getSession(true);

问题1:什么情况会有sessionId但是没有session呢

服务器这边存的session对象也是在内存中进行的

比如把sessionId返回给浏览器了,sessionId和session对象是保存在服务器内存的,此时如果服务器重启了,内存中这些会话数据就没了,但是浏览器中的Cookie还是存在的

session存在内存中不太合理,实践中往往会把这种会话保存到其他介质上,来达到持久化存储目的(mysql,redis)

使用Cookie编写一个登入的小界面

简单的一个小的前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<form action="login" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit"  value="登入">
<!--  当前页面是一个form表单-->
  </form>
</body>
</html>

后端的登入代码编写

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 {
        //先验证用户的登入状态,如果未登入,就要求用户要先登入一下
        HttpSession session=req.getSession(false);
        if(session==null){
            //用户尚未登入
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("请先登入,再访问主页");
            return;
        }
        //已经登入成功了
        //就可以取出之前的attribute
        String username=(String) session.getAttribute("username");
        Long time=(Long) session.getAttribute("time");
        System.out.println("username="+username+",time"+time);
        //根据这样的内容构造页面
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("欢迎您,"+username+"!上次登入时间"+time);
    }
}

重定向的内容编写 

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 {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取到用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (username == null || password == null || username.equals("") || password.equals("")) {
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("请求的参数不完整");
            return;
        }
        //2.验证用户密码是否正确
        //正常的验证,是从数据库读取数据
        //注册账号就会给数据库插入用户名和密码,登入的时候就是验证当前用户名是否存在,以及密码是否匹配
        //当前为了简单,先不引入数据库,直接通过硬编码的方式来判定用户名和密码
        //此处约定,合法的用户名是:zhangsan,密码:123
        if (!username.equals("zhangsan")) {
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("用户名错误!");
            return;
        }
        if (!password.equals("123")) {
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("密码错误");
            return;
        }
        //3.登入成功了,此时可以给这个用户创建会话(就是这个人在不在账户上)
        HttpSession session = req.getSession(true);
        //会话总,可以顺便保存点自定义的数据,比如保存一个登入的时间戳
        //setAttribute后面的value是个Object,想要存什么都可以!!
        session.setAttribute("username", username);
        session.setAttribute("time", System.currentTimeMillis());
        //4.让页面自动跳转到网站主页
        //此处约定的路径是index(使用Servlet生成一个动态页面)
        resp.sendRedirect("index");
    }
}

当前程序设计三个部分进行联动——以下是登入成功的效果

1.登入界面(静态的html,使用form构造http请求)

2.LoginServlet(doPost处理登入的逻辑流程 1234)

3.IndexServlet(doGet处理主页的生成)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/152817.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RT-DETR算法优化改进:轻量级上采样CARAFE算子 | 注意力机制大作战

💡💡💡本文独家改进: 上采样操作CARAFE,具有感受野大、内容感知、轻量级、计算速度快等优点,引入RT-DETR二次创新; 1)代替Upsample进行使用; 推荐指数:五星 RT-DETR魔术师专栏介绍: https://blog.csdn.net/m0_63774211/category_12497375.html ✨✨✨魔改创…

Seatunnel及web搭建流程

准备工作 Java环境 要求java8或者java11&#xff0c;并设置JAVA_HOME&#xff0c;如果JAVA_HOME无效&#xff0c;需要设置为有效状态。 echo ${JAVA_HOME} 创建安装软件目录 sudo mkdir -p /opt/seatunnel/backend sudo mkdir -p /opt/seatunnel/web 下载软件 从https://…

新手小白看过来——带你快速入门跨境电商

近几年来&#xff0c;国内外贸交易是越来越火爆&#xff0c;其中跨境电商成为了2023年的热门风口行业&#xff0c;尽管现在做跨境电商的从业者有很多&#xff0c;但仍然有许多0基础小白想通过跨境电商获取人生的第一桶金&#xff0c;那么新手应该如何在跨境电商领域取得成功呢&…

jedis连接redis

package com.wsd;import redis.clients.jedis.Jedis;import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Properties;public class Redis {public static void main(String[] args) {//读取properti…

侧面多级菜单(一个大类、一个小类、小类下多个物体)

效果&#xff1a; 说明&#xff1a; 左右侧面板使用Animator组件控制滑入滑出。左侧面板中&#xff0c;左的左里面是大类&#xff0c;左的右有绿色的小类&#xff0c;绿色的小类下有多个真正的UI图片按钮。 要点&#xff1a; 结合了一点EasyGridBuilderPro插件的UI元素&…

天津市专业大数据培训班,大数据就业岗位的多样性

大数据技术应用广泛&#xff0c;几乎涉及到了各个行业和领域。毕业后&#xff0c;我们可以选择从事大数据工程师、数据分析师、数据科学家等职业&#xff0c;也可以选择进入金融、医疗、电商等行业进行数据分析和决策支持。 大数据就业岗位多样 大数据培训所涉及的就业岗位有…

【从入门到起飞】JavaSE—IO工具包(Commons-io,Hutool) (2)

&#x1f38a;专栏【JavaSE】 &#x1f354;喜欢的诗句&#xff1a;天行健&#xff0c;君子以自强不息。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f33a;工具包Commons-io⭐使用步骤&#x1f6f8;新建一个文…

国内也可以做伦敦金的吗?给你答案

虽然伦敦金是国际市场上的贵金属投资方式&#xff0c;但国内投资者同样有机会参与其中&#xff0c;最简单的方式就是通过香港的持牌平台&#xff0c;在网上开设一个账号&#xff0c;并往其中注入一定的资金之后&#xff0c;就可以展开交易。 国内投资者可以炒伦敦金&#xff0c…

Spring Bean的生命周期详细梳理

1. 理解Bean的生命周期 1.1 生命周期的各个阶段 在Spring IOC容器中&#xff0c;Bean的生命周期大致如下&#xff1a; 实例化&#xff1a;当启动Spring应用时&#xff0c;IOC容器就会为在配置文件中声明的每个<bean>创建一个实例。属性赋值&#xff1a;实例化后&#…

Python大语言模型实战-利用MetaGPT框架自动开发一个游戏软件(附完整教程)

实现功能 MetaGPT是一个应用在软件开发领域的多智能体框架&#xff0c;其主要创新点在于将SOP标准流水线和Agent结合在了一起&#xff0c;使得拥有不同技能的Role之间配合完成一项较为复杂的任务。本文将用一个案例来演示整个流程。 实现代码 项目地址&#xff1a;https://gi…

MapApp 地图应用

1. 简述 1.1 重点 1&#xff09;更好地理解 MVVM 架构 2&#xff09;更轻松地使用 SwiftUI 框架、对齐、动画和转换 1.2 资源下载地址: Swiftful-Thinking:https://www.swiftful-thinking.com/downloads 1.3 项目结构图: 1.4 图片、颜色资源文件图: 1.5 启动图片配置图: 2. Mo…

(Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分代码&#xff1a; 四、完整代码数据说明手册&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matalb平台…

微服务测试怎么做

开发团队越来越多地选择微服务架构而不是单体结构&#xff0c;以提高应用程序的敏捷性、可扩展性和可维护性。随着决定切换到模块化软件架构——其中每个服务都是一个独立的单元&#xff0c;具有自己的逻辑和数据库&#xff0c;通过 API 与其他单元通信——需要新的测试策略和新…

python 基础语法学习 (二)

多变量赋值 当你在Python中进行多变量赋值时&#xff0c;你可以在一行代码中同时为多个变量分配值。这种方法可以简化代码并提高可读性。下面是一些关于Python多变量赋值的基本知识&#xff1a; 基本赋值&#xff1a;你可以使用等号&#xff08;&#xff09;将一个值分配给一…

SimaPro生命周期评估建模与碳足迹分析流程

SimaPro以系统和透明的方式轻松建模和分析复杂的生命周期&#xff0c;通过确定供应链中每个环节的热点&#xff0c;从原材料的提取到制造&#xff0c;分销&#xff0c;使用和处置&#xff0c;衡量所有生命周期阶段的产品和服务对环境的影响。SimaPro是过去25年评估生命周期的最…

容联云发布生成式应用,让每个企业都拥有大模型沟通能力

基于容联云自主研发的赤兔大模型能力&#xff0c;容联云容犀机器人真正将大模型强大的理解能力、知识学习能力、总结能力、挖掘能力、推理能力融入于实际落地应用中。 开创性的打造生成式场景化智能问答、生成式智能辅助、AI运营话术库&#xff0c;帮助企业洞悉更精准的客户真…

【游戏开发】嘿!要听听我与口袋方舟的故事嘛

目录 写在前面 我与口袋方舟的邂逅 口袋方舟编辑器 027版本正式公测 更新亮点 粉丝福利 写在后面 写在前面 哈喽小伙伴们下午好呀&#xff0c;这里是一只有趣的兔子。最近博主在到处整活给大家谋福利&#xff0c;这次兔哥打听到了一个劲爆的消息&#xff0c;口袋方舟正…

加密数字货币:机遇与风险并存

随着区块链技术的发展和普及&#xff0c;加密数字货币逐渐走入人们的视线。作为一种以数字形式存在的资产&#xff0c;加密数字货币具有去中心化、匿名性和安全性高等特点&#xff0c;为人们提供了一种全新的支付方式和投资选择。然而&#xff0c;加密数字货币市场也存在着较高…

跨界融合 开放共享∣2023中国林草经济发展博鳌大会即将开启

2023第二届中国林草经济发展博鳌大会&#xff08;以下简称“2023 林草大会”&#xff09;将于11月19-20日在海南博鳌亚洲论坛国际会议中心盛大开幕。本次活动由海南省商务厅、海南省林业局支持&#xff0c;中国林业产业联合会、中国林产工业协会、华侨茶业发展研究基金会、北京…

CPU版本的pytorch安装

1.安装&#xff1a;Anaconda3 2.安装&#xff1a;torch-2.0.1cpu-cp311 2.安装&#xff1a;torchvision-0.15.2cpu-cp311-cp311-win_amd64 测试是否安装成功 cmd 进入python import torch print(torch.__version__) print(torch.cuda.is_available())