HTTP请求中的cookie与session(servlet实现登录页面的表单验证)

一、cookie 与 session

1)cookie 与 session 的定义

2)相关的servlet中的 方法

二、代码实现 登录页面

1)先用 vscode 编写登录页面

注意文件的路径 在webapp路径下

<!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>

<body>
  <!-- 使用form表单,实现登录效果 -->
  <div>
    <h1 style="text-align: center;">登录页面</h1>
    <form action="login" method="post" style="width: 300px; margin:0 auto">
      <table>
        <tr>
          <td>用户名:</td>
          <td><input type="text" name="username"></td>
        </tr>

        <tr>
          <td>密码:</td>
          <td><input type="password" name="password"></td>
        </tr>

      </table>
      <input type="submit" value="登录" style="width: 100px; height: 30px; margin-left:100px;">
    </form>
  </div>
</body>

</html>

打开smart tomcat 登录网址

2)编写登录 验证form表单逻辑

在maven项目里java目录下,创建LoginServlet的包,用于区分其他的代码

在包里创建 LoginServlet 的类,继承HttpServlet这个类

登录逻辑

package LoginServlet;

import sun.security.jgss.HttpCaller;

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.获取http请求(由于post请求是form表单格式,所以可以直接用getParameter获取里面的内容)
        //在读取请求的时候,最好设置字符编码集(否则,如果用户名是中文,那么读取的时候就是乱码)
        req.setCharacterEncoding("utf8");
        String username = req.getParameter("username");//获取用户名
        String password = req.getParameter("password");//获取密码
        //2.验证用户名和密码(一般来说是要从数据库中验证密码)
        //此时为了简单验证,把正确的用户名和密码规定为:zhangsan 和 123456
        //字符串.equals(变量) 这样的写法,可以用于处理 变量为 null的情况,如果用户名或着密码为空,也是登录失败的
        resp.setContentType("text/html;charset=utf8");
        if ("zhangsan".equals(username) && "123456".equals(password)){
            resp.getWriter().write("欢迎" + username + "登录使用!");
        }else{
            //登陆失败
            //给用户返回一个提示
            resp.getWriter().write("登陆失败:用户名或密码错误!");
            return;
        }
        //3.登录成功,会给用户创建一个会话
        // 可以给会话中保存一些自定义的数据,通过Attribute的方式来存储
        HttpSession session = req.getSession(true);//获取不到会自动创建 则如果“当前用户的会话对象”为空(第一次访问时)则创建一个新的会话对象返回
        //此处 Attribute 存储的一些程序员自定义的属性,以 键值对 方式存储
        //存储好了数据后,后续跳转到其他的页面,也随时可以把这个数据从会话中取出来
        session.setAttribute("username",username);
        session.setAttribute("loginTime",System.currentTimeMillis());//获取的是当前的时间戳

        //4.此时登录成功后的相关数据已经存储好,可以跳转到网站页面了
        resp.sendRedirect("index");//重定向到index页面上
    }
}

3)登录后的页面index 的逻辑

package LoginServlet;

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;
import java.util.Date;

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取到用户对应的会话对象,生成的页面要根据用户信息来构成的
        HttpSession session = req.getSession(false);//获取不到session不会自动创建
        if (session == null){
            //sessionId 不存在,或者 sessionid 没有在hash 表中查到
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("您当前尚未登录!");
            return;
        }
        //2.从会话中拿到之前存储的用户信息
        //getAttribute的返回值是一个Object对象,所以程序员需要手动 强制类型转换
        String username = (String)session.getAttribute("username");
        Long loginTime = (Long) session.getAttribute("loginTime");//时间戳 是一个很长的数 用 long长整型保存
        Date date = new Date(loginTime);//时间戳对于用户来说不容易理解,所以将时间戳转换为 具体的时间,更直观
        //3.生成一个页面,把上述数据显示到页面上
        resp.setContentType("text/html;charset=utf8");
        String respBody = "欢迎您" + username + "!上次登录时间为" + date;
        resp.getWriter().write(respBody);
    }
}

 4)抓包验证

三、整个代码逻辑 

 

 

四、优化 

将写死的用户名和密码,使用数据库存储

建表建库,并且插入了三个数据

使用JDBC

package LoginServlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import sun.security.jgss.HttpCaller;

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 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;
import java.util.function.LongToIntFunction;

class Login{
    String username;
    String password;
}
@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    private ObjectMapper objectMapper = new ObjectMapper();
    //1.创建数据库 数据源
    private DataSource  dataSource = new MysqlDataSource();

    @Override
    public void init() throws ServletException {
        //1.数据源 初始化
        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/login?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("123456");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取http请求(由于post请求是form表单格式,所以可以直接用getParameter获取里面的内容)
        //在读取请求的时候,最好设置字符编码集(否则,如果用户名是中文,那么读取的时候就是乱码)
        req.setCharacterEncoding("utf8");
        String username = req.getParameter("username");//获取用户名
        String password = req.getParameter("password");//获取密码
        //2.验证用户名和密码(一般来说是要从数据库中验证密码)
        //此时为了简单验证,把正确的用户名和密码规定为:zhangsan 和 123456
        //字符串.equals(变量) 这样的写法,可以用于处理 变量为 null的情况,如果用户名或着密码为空,也是登录失败的
        resp.setContentType("text/html;charset=utf8");
        //TODO 使用数据库
       if (!findLogin(username,password,resp)){
           resp.getWriter().write("登陆失败:用户名或密码错误!");
           return;
       }

//        if ("zhangsan".equals(username) && "123456".equals(password)){
//            resp.getWriter().write("欢迎" + username + "登录使用!");
//        }else{
//            //登陆失败
//            //给用户返回一个提示
//            resp.getWriter().write("登陆失败:用户名或密码错误!");
//            return;
//        }

        //3.登录成功,会给用户创建一个会话
        // 可以给会话中保存一些自定义的数据,通过Attribute的方式来存储
        HttpSession session = req.getSession(true);//获取不到会自动创建 则如果“当前用户的会话对象”为空(第一次访问时)则创建一个新的会话对象返回
        //此处 Attribute 存储的一些程序员自定义的属性,以 键值对 方式存储
        //存储好了数据后,后续跳转到其他的页面,也随时可以把这个数据从会话中取出来
        session.setAttribute("username",username);
        session.setAttribute("loginTime",System.currentTimeMillis());//获取的是当前的时间戳

        //4.此时登录成功后的相关数据已经存储好,可以跳转到网站页面了
        resp.sendRedirect("index");//重定向到index页面上
    }
    private boolean findLogin(String username,String password,HttpServletResponse resp) throws IOException {
        List<Login> loginList = new ArrayList<>();
        try {
            loginList = load();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        for(Login x:loginList){
            if (x.username.equals(username) && x.password.equals(password)){
                resp.getWriter().write("欢迎" + username + "登录使用!");
               return true;
            }
        }
        //登陆失败
//            //给用户返回一个提示

        return false;
    }
    private List<Login> load() throws SQLException {
        //1.创建数据库 数据源(前面写了初始化数据源的方法)
        //2.建立连接(connection是java.sql里的对象)
        Connection connection = dataSource.getConnection();
        //3.构造sql请求
        String sql = "select * from login";
        PreparedStatement statement = connection.prepareStatement(sql);
        //4.执行sql语句
        ResultSet resultSet = statement.executeQuery();
        //5.遍历集合结果
        List<Login> loginList = new ArrayList<>();
        while (resultSet.next()){
            Login login = new Login();
            login.username = resultSet.getString("username");
            login.password = resultSet.getString("password");
            loginList.add(login);
        }
        //6.回收资源
        connection.close();
        statement.close();
        resultSet.close();
        //7.返回loginList
        return loginList;
    }
}

 验证

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

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

相关文章

ai写作强大,ai写作哪个软件最好用?

在当今数字化时代&#xff0c;ai技术的发展正以惊人的速度改变着我们的生活和工作方式。其中&#xff0c;ai写作作为一项令人瞩目的创新&#xff0c;展示了强大的文本生成能力。然而&#xff0c;随着各种ai写作软件的涌现&#xff0c;人们不禁困惑&#xff1a;哪个软件才是最好…

【网络设备巡检命令】--思科、华为、H3C、锐捷

【网络设备巡检命令】--思科、华为、H3C、锐捷 一、思科二、华为三、H3C四、锐捷 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 一、思科 1、查看系统信息&#xff1a; show version2、查看时间&#xff1a; show clock3、查看序列号&a…

Zed 捕获图像+测距

Zed 捕获图像测距 1. 导入相关库2. 相机初始化设置3. 获取中心点深度数据4. 计算中心点深度值5. 完整代码5. 实验效果 此代码基于官方代码基础上进行改写&#xff0c;主要是获取zed相机深度画面中心点的深度值&#xff0c;为yolo测距打基础。 1. 导入相关库 import pyzed.sl …

C语言 ─── 操作符详解

目录 1. 算术操作符 2. 移位操作符 2.1 左移操作符 2.2 右移操作符 3. 位操作符 4. 复合赋值符 5. 单目操作符 6. 逗号表达式 7. 隐式类型转换 7.1 整型提升的意义&#xff1a; 7.2 如何进行整体提升呢&#xff1f; 8. 算术转换 ★★★数组名 1. 算术操作符 -…

redis与etcd的对比

1.redis是一种高级的key&#xff1a;value存储系统&#xff0c;其中value支持五种数据类型&#xff1a; 1.1 字符串&#xff08;strings&#xff09; 1.2 字符串列表&#xff08;lists&#xff09; 1.3 字符串集合&#xff08;sets&#xff09; 1.4 有序字符串集合&#xff08;…

管理 nodejs 版本工具 nvm

nvm 方便切换不同版本的 node 及 对应的 npm 版本 一、安装nvm nvm官网 &#xff08;内含下载的文件&#xff0c;点击进去下载&#xff0c;并按照 网站文档步骤 操作即可&#xff09; 二、nvm 基础命令 nvm arch&#xff1a;显示node是运行在32位还是64位。nvm install <…

centos修改启动项加载不同内核

一.背景&#xff1a; 虚拟机中有时需要编译好几个内核版本&#xff0c;make install后系统存在几个内核版本。需要再哪个内核上开发调试就启动特定的内核版本。这就需要修改启动时的内核版本&#xff0c;再物理机或虚拟机启动时可以上下键选择。但有时是docket云环境中或远程时…

CANoe中LIN工程主节点的配置(如何切换调度表)

1&#xff1a;前置条件 1&#xff09;工程已经建立&#xff0c;simulation窗口已经配置好&#xff08;包括且不限于通道mappin好&#xff0c;数据库文件已经添加&#xff09; 2&#xff09;我已系统自带sampleCfg工程&#xff0c;作为例子。如下图 2 &#xff1a;主节点的配置…

前端css中table表格的属性使用

前端css中table表格的属性使用 一、前言二、常见的表格属性1.边框的样式2.布局和对齐3.间距和填充4.背景和颜色5.字体的样式6.边框的圆角 三、简单的表格&#xff0c;例子11.源码12.源码1效果截图 四、给表格添加动画效果&#xff0c;例子21.源码22.源码2的运行效果 五、结语六…

【热门话题】探索与心得:深入体验Microsoft Edge浏览器

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 探索与心得&#xff1a;深入体验Microsoft Edge浏览器一、Edge浏览器概述1.1 发…

通快霍廷格TruPlasma MF中频电源培训PPT课件内容下图

通快霍廷格TruPlasma MF中频电源培训PPT课件内容下图

美业连锁门店收银系统源码-如何查看收款门店对应的加盟商?

美业管理系统源码 博弈美业SaaS系统 连锁多门店美业收银系统源码 多门店管理 / 会员管理 / 预约管理 / 排班管理 / 商品管理 / 促销活动 PC管理后台、手机APP、iPad APP、微信小程序 第一步&#xff1a; 登录pc管理后端 第二步&#xff1a; 进入企业组织管理-门店管理&a…

【Linux】认识文件(一):文件标识符

【Linux】认识文件&#xff08;一&#xff09;&#xff1a;文件标识符 一.什么是文件&#xff1f;1.文件的本质2.文件的分类 二.访问文件操作1.C语言中的访问文件接口i.fopenii.fcloseiii.fwrite 2.系统访问文件接口i.openii.closeiii.write 三.文件管理1.对所有打开文件的管理…

Linux入门学习 之 基础操作指令讲解(小白必看)

股票的规律找到了&#xff0c;不是涨就是跌 一、Linux下基本指令 1.ls 指令 2.pwd 命令 3.cd 指令 4.touch 指令 5.mkdir 指令 6.rmdir指令 && rm 指令 7.man 指令 8.cp 指令 9.mv指令 10.cat 11.more 指令 12.less 指令 13.head 指令 14.tail 指令 15…

SQLite作为应用程序文件格式(二十八)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite数据库中JSON 函数和运算符(二十七) 下一篇&#xff1a;SQLite—系列文章目录 摘要 具有定义架构的 SQLite 数据库文件 通常是一种出色的应用程序文件格式。 以下是十几个原因&#xff1a; 简化的应用程序开发单文…

BUUCTF-MISC01金胖

题目&#xff1a;动图使用Stegsolve软件进行逐帧查看 下载文件后&#xff0c;图片隐写之gif多帧隐藏&#xff0c;这类题比较简单&#xff0c;只需要将图片使用Stegsolve软件进行逐帧查看就行了.file-open打开添加文件 将文件添加进来&#xff0c;而后点击Analyse-Frame Browse…

windows和linux服务器等保测评加固方法

服务器加固是通过各种方法增强服务器安全性的过程。保护操作系统免受黑客、破解者和攻击者的侵害。网络安全防护的目标是保密性、完整性、可用性、可控制性、不可否认性。 一、window服务器等保加固 以win2012和win2008 为例&#xff1a; &#xff08;win2008&#xff09; …

畅游网络:构建C++网络爬虫的指南

概述 随着信息时代的来临&#xff0c;网络爬虫技术成为数据采集和网络分析的重要工具。本文旨在探讨如何运用C语言及其强大的cpprestsdk库构建一个高效的网络爬虫&#xff0c;以便捕捉知乎等热点信息。为了应对IP限制的挑战&#xff0c;我们将引入亿牛云爬虫代理服务&#xff…

Spring 事务失效总结

前言 在使用spring过程中事务是被经常用的&#xff0c;如果不小心或者认识不做&#xff0c;事务可能会失效。下面列举几条 业务代码没有被Spring 容器管理 看下面图片类没有Componet 或者Service 注解。 方法不是public的 Transactional 注解只能用户public上&#xff0c…

使用Python+opencv实现自动扫雷

大家好&#xff0c;相信许多人很早就知道有扫雷这么一款经典的游戏&#xff0c;更是有不少人曾听说过中国雷圣&#xff0c;也是中国扫雷第一、世界综合排名第二的郭蔚嘉的顶顶大名。扫雷作为一款在Windows9x时代就已经诞生的经典游戏&#xff0c;从过去到现在依然都有着它独特的…