cookie+session

news2025/1/16 1:00:18

文章目录

      • 0. 概念
      • 1.Cookie
        • 1.1 Cookie快速入门
        • 1.2 原理
        • 1.3 cookie的存活时间
        • 1.3 cookie的存储中文
      • 2.Session
        • 2.1 Session快速入门
        • 2.2 Session原理
        • 2.3 Session 存储时间
        • 2.4 Session销毁
      • 3. Cookie和Session小结
      • 4. 案例-登录注册记录密码
        • 4.1 登录功能
        • 4.2 记住我-设置cookie
        • 4.2 注册功能

0. 概念

会话跟踪技术

会话: 用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。

  • 在一次会话中可以包含多次请求和响应;
  • 从浏览器发出请求到服务端响应数据给前端之后,一次会话(在浏览器和服务器之间)就被建立了;
  • 会话被建立后,如果浏览器或服务端都没有被关闭,则会话就会持续建立着;

//比如在我们访问京东的时候,当打开浏览器进入京东首页后,浏览器和京东的服务器之间就建立了一次会话,后面的搜索商品,查看商品的详情,加入购物车等都是在这一次会话中完成。

会话跟踪: 一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据

  • 服务器需要用来识别请求是否来自同一个浏览器
  • 服务器用来识别浏览器的过程,这个过程就是会话跟踪
  • 服务器识别浏览器后就可以在同一个会话中多次请求之间来共享数据

会话跟踪的实现方式

  • 客户端会话跟踪技术:Cookie
  • 服务端会话跟踪技术:Session

这两个技术都可以实现会话跟踪,它们之间最大的区别:Cookie是存储在浏览器端而Session是存储在服务器端。

HTTP协议

浏览器使用HTTP协议或HTTPS协议与服务器建立连接。

HTTP(Hypertext Transfer Protocol) 是一种用于在Web上进行通信的协议。 它是一种无状态的、应用层的协议。

  • AIM: 用于在客户端和服务器之间传输超文本(例如HTML、CSS、JavaScript)和其他资源(例如图像、视频)。

HTTP请求的特点:

  1. 无状态性
    HTTP是一种无状态协议,即服务器不会保留先前请求的状态信息。每个请求都是独立的,服务器仅根据请求和响应之间的交互进行处理。

    • 这意味着服务器不能直接识别连续的请求是否来自同一个客户端。每个请求都必须包含足够的信息(如请求头、URL参数、Cookie等)来完整描述客户端的意图和操作;
    • 无状态性的优势:使得服务器可以更容易进行负载均衡和横向扩展,服务器可以将请求路由到任何可用的服务器,无需考虑之前的状态,更好的应对高并发和大规模请求;简化服务器设计,提高服务器可靠性和独立性;可缓存性:以根据请求的响应头中的缓存相关字段进行缓存控制,代理服务器可以有效地缓存响应,提高性能和减少网络流量。
  2. 基于请求-响应模型
    HTTP使用请求-响应模型。客户端发送HTTP请求到服务器,并等待服务器返回HTTP响应。请求包括请求方法(如GET、POST、PUT、DELETE等)、URL、请求头和请求体。响应包括状态码、响应头和响应体。

  3. URL和资源定位
    HTTP使用统一资源定位符(URL)来标识和定位网络上的资源。客户端通过指定URL来请求特定的资源

  4. 加密和安全
    HTTP可以通过使用SSL或TLS协议来加密通信,形成HTTPS,以提供安全的数据传输。

1.Cookie

概念

Cookie是一种用于在Web浏览器和服务器之间传递数据的机制。

  • 由服务器发送给客户端浏览器并存储在本地(客户端)的小型文本文件;
  • 浏览器在后续请求中会将该文本文件作为HTTP头信息的一部分发送回服务器;

//注意的是,Cookie是存储在用户本地的文本文件,因此用户可以查看和修改Cookie。为了保护敏感信息,可以使用安全标志(secure)和HttpOnly属性来限制Cookie的访问性

cookie的应用场景

Cookie通常用于以下几个方面:

  • 会话管理:
    Cookie最常见的用途之一是管理用户的会话。服务器可以在用户登录后创建一个包含会话标识符的Cookie,并将其发送给浏览器浏览器随后会将该Cookie存储,并在后续的请求中将会话标识符作为Cookie头信息的一部分发送回服务器,以便服务器能够识别和跟踪用户的会话状态。

  • 用户识别:
    Cookie还可以用于识别和跟踪用户的身份。服务器可以在用户登录或进行其他身份验证操作后创建一个包含用户标识信息的Cookie,并将其发送给浏览器。浏览器随后会存储该Cookie,并在后续的请求中将用户标识信息作为Cookie头信息的一部分发送回服务器,以便服务器能够识别用户的身份。

  • 个性化体验:
    Cookie可用于存储用户的偏好设置和个性化信息。服务器可以将用户的偏好设置等数据存储在Cookie中,并在后续的请求中使用该Cookie提供个性化的体验。例如,保存用户的语言偏好、主题偏好或上次访问的页面等。

  • 跟踪和分析:
    Cookie可用于跟踪用户在网站上的活动和行为。服务器可以使用Cookie来记录用户的访问时间、页面浏览记录和点击行为等信息,从而进行用户行为分析和统计。

1.1 Cookie快速入门

步骤:

  1. 创建cookie对象,设置数据
    Cookie cookie = new Cookie(“username”, “zs”);
  2. 发送cookie到客户端:使用resp对象
    resp.addCookie(cookie);
  3. 获取客户端携带的cookie,使用req对象
    Cookie[] cookies = req.getCookies();
  4. 遍历数组,获取每一个cookie对象:for
  5. 使用cookie对象方法获取数据
//创建喝发送cookie
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 创建Cookie对象,写入数据
        Cookie cookie = new Cookie("username", "zs");

        //2.发送cookie。resp
        resp.addCookie(cookie);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

在这里插入图片描述

//获取cookie
@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取cookie数据数组
        Cookie[] cookies = req.getCookies();

        //2. 遍历数组
        for (Cookie cookie:cookies){

            //3.获取数据
            String name = cookie.getName();  //获取键
            String value = cookie.getValue();  //获取值
            System.out.println(name+":"+value);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

在浏览器先访问aServlet,再访问bServlet
在这里插入图片描述

1.2 原理

对于Cookie的实现原理是基于HTTP协议的,其中设计到HTTP协议中的两个请求头信息:

  • 响应头:set-cookie
  • 请求头: cookie
    在这里插入图片描述

案例分析

  1. AServlet给前端发送Cookie,BServlet从request中获取Cookie的功能;
  2. 对于AServlet响应数据的时候,Tomcat服务器都是基于HTTP协议来响应数据;
  3. 当Tomcat发现后端要返回的是一个Cookie对象之后,Tomcat就会在响应头中添加一行数据SetCookie:username=zs;
  4. 浏览器获取到响应结果后,从响应头中就可以获取到Set-Cookie对应值username=zs ,并将数据存储在浏览器的内存中;
  5. 浏览器再次发送请求给BServlet的时候,浏览器会自动在请求头中添加Cookie: username=zs发送给服务端BServlet;
  6. Request对象会把请求头中cookie对应的值封装成一个个Cookie对象,最终形成一个数组;
  7. BServlet通过Request对象获取到Cookie[]后,就可以从中获取自己需要的数据;

在这里插入图片描述
在这里插入图片描述

1.3 cookie的存活时间

cookie的存活时间

  • 默认情况下,cookie为会话Cookie,即仅在浏览器会话期间有效,在关闭浏览器后将被删除。
  • 设置最大存活时间 ,可以指定Cookie从当前时间开始的存活时长(以秒为单位)。
    cookie.setMaxAge(int time);
    • 正数:将cookie写到浏览器所在电脑的硬盘,持久化存储,到时间自动删除。
    • 负数:默认值,还是会话cookie,关闭浏览器,cookie消失。
    • 0:删除对应的cookie;

1.3 cookie的存储中文

Cookie在存储中文或其他非ASCII字符时,需要进行编码处理
实现思路为:

  1. 在AServlet中对中文进行URL编码,采用URLEncoder.encode(),将编码后的值存入Cookie中

  2. 在BServlet中获取Cookie中的值,获取的值为URL编码后的值

  3. 将获取的值在进行URL解码,采用URLDecoder.decode(),就可以获取到对应的中文值

@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //发送Cookie
        String value = "张三";
        //对中文进行URL编码
        value = URLEncoder.encode(value, "UTF-8");
        System.out.println("存储数据:"+value);
        //将编码后的值存入Cookie中
        Cookie cookie = new Cookie("username",value);
        //设置存活时间   ,1周 7天
        cookie.setMaxAge(60*60*24*7);
        //2. 发送Cookie,response
        response.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Cookie
        //1. 获取Cookie数组
        Cookie[] cookies = request.getCookies();
        //2. 遍历数组
        for (Cookie cookie : cookies) {
            //3. 获取数据
            String name = cookie.getName();
            if("username".equals(name)){
                String value = cookie.getValue();//获取的是URL编码后的值 %E5%BC%A0%E4%B8%89
                //URL解码
                value = URLDecoder.decode(value,"UTF-8");
                System.out.println(name+":"+value);//value解码后为 张三
                break;
            }
        }

    }

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

2.Session

概念

Session是指在客户端与服务器之间建立的一个临时交互期间。在Web开发中,会话是一种用于跟踪用户状态和存储用户数据的机制。

  • 服务端会话跟踪技术:将数据保存到服务端(相比于cookie可以保证数据的一个安全)。

2.1 Session快速入门

Session的工作流程

  • 在服务端的AServlet获取一个Session对象,把数据存入其中
  • 在服务端的BServlet获取到相同的Session对象,从中取出数据
  • 就可以实现一次会话中多次请求之间的数据共享
    在这里插入图片描述

相关代码

1. 获取Session对象,使用的是request对象;
HttpSession session = request.getSession();

2. Session对象提供的功能

  * 存储数据到 session 域中

    ```
    void setAttribute(String name, Object o)
    ```

  * 根据 key,获取值

    ```
    Object getAttribute(String name)
    ```

  * 根据 key,删除该键值对

    ```
    void removeAttribute(String name)
    ```

Session快速入门步骤

需求: 在一个Servlet中往Session中存入数据,在另一个Servlet中获取Session中存入的数据

  1. 创建名为SessionDemo1的Servlet类

  2. 创建名为SessionDemo2的Servlet类

  3. 在SessionDemo1的方法中:获取Session对象、存储数据

  4. 在SessionDemo2的方法中:获取Session对象、获取数据

  5. 启动测试


@WebServlet("/sessionDemo1")
public class SessionDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 创建Session对象
        HttpSession session = req.getSession();

        //2.存储数据
        session.setAttribute("username", "ls");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
package com.itheima.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/sessionDemo2")
public class SessionDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取数据,从session中
        //1. 获取Session对象
        HttpSession session = req.getSession();

        //2. 获取数据
        Object username = session.getAttribute("username");
        System.out.println(username);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

在这里插入图片描述

2.2 Session原理

前提条件

Session要想实现一次会话多次请求之间的数据共享,就必须要保证多次请求获取Session的对象是同一个。
在这里插入图片描述

一个浏览器在会话期间,请求的session是同一个
在这里插入图片描述
Session是基于Cookie实现的

具体来说,当用户第一次访问网站时,服务器会为该用户创建一个唯一的会话标识符(Session ID)。为了在用户的后续请求中跟踪会话,服务器会将这个会话标识符发送给客户端,并存储在Cookie中。

  • 尽管会话数据存储在服务器端,但由于会话标识符存储在Cookie中,因此客户端(浏览器)会在每次请求中将会话标识符发送给服务器,以便进行会话跟踪。这样,服务器就能够将每个请求与正确的会话相关联,实现了会话机制的跨请求和跨页面的状态保持。
  • 会话数据本身并不存储在Cookie中。Cookie只是用于存储会话标识符,而实际的会话数据存储在服务器端的会话数据存储区域(如内存、数据库等)中。这样做既保护了会话数据的安全性,又提供了更大的存储空间和灵活性

在这里插入图片描述

(1)demo1在第一次获取session对象的时候,session对象会有一个唯一的标识,假如是`id:10`

(2)demo1在session中存入其他数据并处理完成所有业务后,需要通过Tomcat服务器响应结果给浏览器

(3)Tomcat服务器发现业务处理中使用了session对象,就会把session的唯一标识`id:10`当做一个cookie,添加`Set-Cookie:JESSIONID=10`到响应头中,并响应给浏览器

(4)浏览器接收到响应结果后,会把响应头中的coookie数据存储到浏览器的内存中

(5)浏览器在同一会话中访问demo2的时候,会把cookie中的数据按照`cookie: JESSIONID=10`的格式添加到请求头中并发送给服务器Tomcat

(6)demo2获取到请求后,从请求头中就读取cookie中的JSESSIONID值为10,然后就会到服务器内存中寻找`id:10`的session对象,如果找到了,就直接返回该对象,如果没有则新创建一个session对象

(7)关闭打开浏览器后,因为浏览器的cookie已被销毁,所以就没有JESSIONID的数据,服务端获取到的session就是一个全新的session对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 Session 存储时间

Q:服务器重启后,Session中的数据是否还在?
正常重启并不会;

R:Session的钝化和活化
钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中
活化:再次启动服务器后,从文件中加载数据到Session中

注意:

  • session数据存储在服务端,服务器重启后,session数据会被保存

  • 浏览器被关闭启动后,重新建立的连接就已经是一个全新的会话,获取的session数据也是一个新的对象

  • session的数据要想共享,浏览器不能关闭,所以session数据不能长期保存数据

  • cookie是存储在客户端,是可以长期保存

2.4 Session销毁

session的销毁会有两种方式:

  • 默认情况下,无操作,30分钟自动销毁
  • 调用Session对象的invalidate()进行销毁

失效时间,可以在web.xml文件里进行配置

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
               version="3.1">
      
          <session-config>
              <session-timeout>100</session-timeout>
          </session-config>
      </web-app>

调用Session对象的invalidate()进行销毁

  • 在SessionDemo2类中添加session销毁的方法

    @WebServlet("/demo2")
    public class SessionDemo2 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取数据,从session中
    
            //1. 获取Session对象
            HttpSession session = request.getSession();
            System.out.println(session);
    
            // 销毁
            session.invalidate();
            //2. 获取数据
            Object username = session.getAttribute("username");
            System.out.println(username);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

3. Cookie和Session小结

* 区别:
  * 存储位置:Cookie 是将数据存储在客户端,Session 将数据存储在服务端
  * 安全性:Cookie不安全,Session安全
  * 数据大小:Cookie最大3KB,Session无大小限制
  * 存储时间:Cookie可以通过setMaxAge()长期存储,Session默认30分钟
  * 服务器性能:Cookie不占服务器资源,Session占用服务器资源
 
* 应用场景
根据具体的应用需求和安全考虑来选择合适的机制。
Cookie通常用于在客户端存储少量的信息
而Session通常用于在服务器端存储更多的会话数据。
同时,Cookie的存储时间相对较长,而Session的存储时间通常与用户的活动相关。


* 结论
  * Cookie是用来保证用户在未登录情况下的身份识别
  * Session是用来保存用户登录后的数据

Cookie的应用场景:

  • 用户身份管理:
    Cookie常用于管理用户的登录状态。通过在用户登录时设置包含用户标识信息的Cookie,可以在用户的后续请求中通过Cookie来验证用户的身份,实现用户的持久登录状态

  • 个性化设置:
    网站可以使用Cookie来存储用户的个性化设置,例如用户的偏好、主题选择等。通过在Cookie中保存这些设置,可以在用户的每次访问中提供一致的用户体验。

  • 购物车和电子商务:
    Cookie可以用于存储用户的购物车信息,以便在用户浏览和购买商品时保持持久状态。通过在Cookie中保存购物车的内容,可以在用户访问网站的不同页面时保留购物车的信息。

  • 广告跟踪和定向广告:
    Cookie可以用于跟踪用户的浏览行为和兴趣,并提供定向广告。广告服务商可以通过在用户浏览网站时设置Cookie来收集用户数据,以便更好地了解用户的兴趣和行为,从而提供相关的广告。

Session的应用场景:

  • 用户登录和权限管理:
    Session通常用于管理用户的登录状态和权限。通过在用户登录后创建一个唯一的会话标识符(Session ID),可以将用户的身份和权限信息存储在服务器端的会话数据中,从而实现对用户的身份验证和访问控制。

  • 表单数据和用户输入:
    Session可以用于暂时存储用户提交的表单数据和用户输入。例如,在多步表单流程中,可以使用Session来存储用户在不同步骤中输入的数据,以便在最后一步提交时进行整体处理。

  • 应用程序状态管理:
    Session可以用于存储应用程序的状态和上下文信息。例如,在Web应用程序中,可以使用Session来存储用户的浏览历史、页面访问计数等信息,以便在用户的不同请求中保持应用程序的状态。

  • 购物和订单管理:
    Session可以用于管理用户的购物和订单信息。通过在Session中存储购物车的内容、订单状态和支付信息,可以实现在用户浏览和结算购物车时的持久状态。

4. 案例-登录注册记录密码

用户登录注册案例:https://blog.csdn.net/meini32/article/details/132305323

新添功能:

  1. 完成用户登录功能,如果用户勾选“记住用户” ,则下次访问登录页面自动填充用户名密码
  2. 完成注册功能,并实现验证码功能

4.1 登录功能

UserMapper

package com.mapper;

import com.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserMapper {

    //查全部
    @Select("SELECT * FROM tb_user")
    List<User> selectAll();

    //根据用户名查询
    @Select("SELECT * FROM tb_user where username=#{username}")
    User selectByUserName(String username);

    //根据用户名和密码查询
    @Select("select * from tb_user where username = #{username} and password = #{password}")
    User select(@Param("username") String username, @Param("password")  String password);

    /**
     * 添加用户
     * @param user
     */
    @Insert("insert into tb_user values(null,#{username},#{password})")
    void add(User user);
}

UserService

package com.service;

import com.mapper.UserMapper;
import com.pojo.User;
import com.util.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

public class UserService {
    SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();

    public User selectByUserName(String username){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.selectByUserName(username);
        sqlSession.close();
        return user;
    }

    public User login(String username,String password){
        //2. 获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3. 获取UserMapper
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //4. 调用方法
        User user = mapper.select(username, password);
        //释放资源
        sqlSession.close();

        return  user;
    }
}

登录Servlet

package com.web;

import com.pojo.User;
import com.service.UserService;

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("/loginServlet")
public class LoginServlet extends HttpServlet {
    private UserService service = new UserService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接受username
//        String username = "zhangsan";

        String username = req.getParameter("username");
        String password = req.getParameter("password");

        //2. 调用service查询
        User user = service.login(username, password);

        //3. 判断
        if(user != null){
            //登录成功,跳转到查询所有的BrandServlet

            //将登陆成功后的user对象,存储到session
            HttpSession session = req.getSession();
            session.setAttribute("user",user);

//            String contextPath = req.getContextPath();
//            resp.sendRedirect(contextPath+"/selectAllServlet");
            resp.sendRedirect("hello.jsp");
        }else {
            // 登录失败,
            // 存储错误信息到request
            req.setAttribute("login_msg","用户名或密码错误");
            // 跳转到login.jsp
            req.getRequestDispatcher("/login.jsp").forward(req,resp);

        }



        //输出
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

登录和跳转页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page isELIgnored="false" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>login</title>
    <link href="css/login.css" rel="stylesheet">
</head>

<body>
<div id="loginDiv" style="height: 350px">
    <form action="/loginServlet" method="post" id="form">
        <h1 id="loginMsg">LOGIN IN</h1>
<%--        <div id="errorMsg">用户名或密码不正确</div>--%>
        <div id="errorMsg">${login_msg}</div>
        <p>Username:<input id="username" name="username" type="text"></p>
        <p>Password:<input id="password" name="password" type="password"></p>
        <p>Remember:<input id="remember" name="remember" type="checkbox"></p>
        <div id="subDiv">
            <input type="submit" class="button" value="login up">
            <input type="reset" class="button" value="reset">&nbsp;&nbsp;&nbsp;
            <a href="register.html">没有账号?</a>
        </div>
    </form>
</div>
</body>
</html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page isELIgnored="false" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>${user.username},欢迎您</h1>
</body>
</html>

测试
输入正确的用户名或密码
在这里插入图片描述
在这里插入图片描述
输入错误的
在这里插入图片描述

4.2 记住我-设置cookie

如果用户勾选“记住用户” ,则下次访问登陆页面自动填充用户名密码。这样可以提升用户的体验。

(1)在login.jsp为复选框设置值
在这里插入图片描述
(2)在LoginServlet获取复选框的值并在登录成功后进行设置Cookie

package com.web;

import com.pojo.User;
import com.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    private UserService service = new UserService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接受username
//        String username = "zhangsan";

        String username = req.getParameter("username");
        String password = req.getParameter("password");

        //获取复选框数据
        String remember = req.getParameter("remember");

        //2. 调用service查询
        User user = service.login(username, password);

        //3. 判断
        if(user != null){

            //判断用户是否勾选记住我,字符串写前面是为了避免出现空指针异常
            if("1".equals(remember)){
                //勾选了,发送Cookie
                //1. 创建Cookie对象
                Cookie c_username = new Cookie("username",username);
                Cookie c_password = new Cookie("password",password);
                // 设置Cookie的存活时间
                c_username.setMaxAge( 60 * 60 * 24 * 7);
                c_password.setMaxAge( 60 * 60 * 24 * 7);
                //2. 发送
                resp.addCookie(c_username);
                resp.addCookie(c_password);
            }

            //将登陆成功后的user对象,存储到session
            HttpSession session = req.getSession();
            session.setAttribute("user",user);

            resp.sendRedirect("hello.jsp");
        }else {
            // 登录失败,
            // 存储错误信息到request
            req.setAttribute("login_msg","用户名或密码错误");
            // 跳转到login.jsp
            req.getRequestDispatcher("/login.jsp").forward(req,resp);

        }



        //输出
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

(1)在login.jsp用户名的表单输入框使用value值给表单元素添加默认值,value可以使用${cookie.username.value}

(2)在login.jsp密码的表单输入框使用value值给表单元素添加默认值,value可以使用${cookie.password.value}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>login</title>
    <link href="css/login.css" rel="stylesheet">
</head>

<body>
<div id="loginDiv" style="height: 350px">
    <form action="/brand-demo/loginServlet" method="post" id="form">
        <h1 id="loginMsg">LOGIN IN</h1>
        <div id="errorMsg">${login_msg}</div>
        <p>Username:<input id="username" name="username" value="${cookie.username.value}" type="text"></p>

        <p>Password:<input id="password" name="password" value="${cookie.password.value}" type="password"></p>
        <p>Remember:<input id="remember" name="remember" value="1" type="checkbox"></p>
        <div id="subDiv">
            <input type="submit" class="button" value="login up">
            <input type="reset" class="button" value="reset">&nbsp;&nbsp;&nbsp;
            <a href="register.html">没有账号?</a>
        </div>
    </form>
</div>
</body>
</html>

测试
在这里插入图片描述
在这里插入图片描述

4.2 注册功能

  • 注册功能:保存用户信息到数据库
  • 验证码功能
    • 展示验证码:展示验证码图片,并可以点击切换
    • 校验验证码:验证码填写不正确,则注册失败

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

概念解析 | 稀疏正则化

稀疏正则化&#xff1a;从理论到实践的简要解析 注1&#xff1a;本文系“概念解析”系列之一&#xff0c;致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是&#xff1a;稀疏正则化。 Group-sparsity regularization enforcement: (a) the columns of the… | Dow…

pytest之parametrize参数化

前言 我们都知道pytest和unittest是兼容的&#xff0c;但是它也有不兼容的地方&#xff0c;比如ddt数据驱动&#xff0c;测试夹具fixtures&#xff08;即setup、teardown&#xff09;这些功能在pytest中都不能使用了&#xff0c;因为pytest已经不再继承unittest了。 不使用dd…

【微服务】02-集成事件与MediatR

文章目录 1.集成事件1.1 定义1.2 集成事件工作原理1.3 总结 2.使用RabbitMQ来实现EventBus2.1 RabbitMQ安装2.2 CAP框架实现RabbitMQ2.2.1 CAP框架实现架构2.2.2 CAP框架实现原理 3.MediatR3.1 使用Mediator实现命令查询职责分离模式(CQRS)3.1.1 核心对象 3.2 处理领域事件3.2.…

Tomcat线程池梳理

Tomcat梳理 文章目录 Tomcat梳理1.问题2.监控tomcat线程池springboot1.xspringboot2.x转为json格式打印输出 3.SpringBoot内置线程解析测试controlleryaml配置可知ThreadPoolExecutor有如下五种线程池状态。线程池监控指标并发测试并发请求数 < Tomcat最大线程数20并发请求数…

AcWing算法基础课第四讲动态规划(2): 线性DP、区间DP

文章目录 &#xff08;1&#xff09;线性DP898. 数字三角形895. 最长上升子序列897. 最长公共子序列 &#xff08;2) 区间DP282. 石子合并区间 DP 常用模版 &#xff08;1&#xff09;线性DP 898. 数字三角形 题目链接 给定一个如下图所示的数字三角形&#xff0c;从顶部出发…

蒙蒂卡洛与圣杯:二次更快的模拟

一、说明 针对不确知的&#xff0c;或者是 混沌问题&#xff0c;如果存在解决&#xff0c;什么方法最有效&#xff1f;本文针对蒙特卡洛法展开讨论。 你有没有试过把一个糟糕的糖果包装纸扔进垃圾桶&#xff0c;即使你把它正好放在垃圾箱上方&#xff0c;皱巴巴的塑料也很可能会…

【AIGC】AI工具合集人脸动漫化,老照片修复和视频补帧工具

Paper2GUI: 一款面向普通人的 AI 桌面 APP 工具箱&#xff0c;免安装即开即用&#xff0c;已支持 40AI 模型&#xff0c;内容涵盖 AI 绘画、语音合成、视频补帧、视频超分、目标检测、图片风格化、OCR 识别等领域。支持 Windows、Mac、Linux 系统。 小白兔AI 3.0版起永久免费A…

【Git Bash】简明从零教学

目录 Git 的作用官网介绍简明概要 Git 下载链接Git 的初始配置配置用户初始化本地库 Git 状态查询Git 工作机制本地工作机制远端工作机制 Git 的本地管理操作add 将修改添加至暂存区commit 将暂存区提交至本地仓库日志查询版本穿梭 Git 分支查看分支创建与切换分支跨分支修改与…

变压器绝缘油介质损耗因素测试

试验目的 变压器油又称绝缘油&#xff0c;是一种电介质&#xff0c;是能够耐受电应力的绝缘体。当对介质油施加交流电压时&#xff0c;所通过的电流与其两端的电压相位差并不是90度角&#xff0c;而是比90度角要小一个δ角的&#xff0c;此δ角称为油的介质损耗角。变压器油的…

微服务集成spring cloud sentinel

目录 1. sentinel使用场景 2. sentinel组成 3. sentinel dashboard搭建 4. sentinel客户端详细使用 4.1 引入依赖 4.2 application.properties增加dashboard注册地址 4.3 手动增加限流配置类 4.4 rest接口及service类 4.5 通过dashboard动态配置限流规则 1. sentinel使…

Linux 系统下 GDB 调试器的使用

文章目录 简介GDB 的介绍GDB 的使用 GDB 常用命令及示例查看相关操作断点相关操作运行相关操作变量相关操作分隔窗口操作 简介 GDB 的介绍 GDB 是 GNU 调试程序&#xff0c;是用来调试 C 和 C 程序的调试器。它可以让程序开发者在程序运行时观察程序的内部结构和内存的使用情况…

大数据时代,个人信息数据库保护的挑战及其对策

挑战&#xff1a; 数据泄露&#xff1a;大数据时代&#xff0c;个人信息数据库面临被黑客攻击、内部员工滥用权限等风险&#xff0c;导致个人信息泄露的风险增加。 隐私保护&#xff1a;随着大数据的快速发展&#xff0c;个人信息的采集和分析变得更加广泛和深入。但是&#xf…

初级工程师职称评定条件及流程是什么呢?初级作用是什么?

现在全国统一的助理&#xff08;初级&#xff09;工程师是由人社部颁发的初级工程师证也就是大家说的初级职称。人社部备案&#xff0c;正规可靠&#xff0c;国家认可&#xff0c;评审表、红头文件齐全&#xff0c;可以用于应聘、在职、上岗、加薪、评级、评职称或者企业升资质…

indexDB入门到精通

前言 由于开发3D可视化项目经常用到模型&#xff0c;而一个模型通常是几m甚至是几十m的大小对于一般的服务器来讲加载速度真的十分的慢&#xff0c;为了解决这个加载速度的问题&#xff0c;我想到了几个本地存储的。 首先是cookie,cookie肯定是不行的&#xff0c;因为最多以只…

MPP 还是主流架构吗

MPP 架构&#xff1a; MPP 架构的产品&#xff1a; Impala ClickHouse Druid Doris 很多 OLAP 引擎都采用了 MPP 架构 批处理系统 - 使用场景分钟级、小时级以上的任务&#xff0c;目前很多大型互联网公司都大规模运行这样的系统&#xff0c;稳定可靠&#xff0c;低成本。…

9.1 功率放大电路概述

在实用电路中&#xff0c;往往要求放大电路的末级&#xff08;即输出级&#xff09;输出一定的功率&#xff0c;以驱动负载。能够向负载提供足够信号功率的放大电路称为功率放大电路&#xff0c;简称功放。从能量控制和转换的角度看&#xff0c;功率放大电路与其它放大电路在本…

c++ qt--信号与槽(二) (第四部分)

c qt–信号与槽(二) &#xff08;第四部分&#xff09; 一.信号与槽的关系 1.一对一 2.一对多 3.多对一 4.多对多 还可以进行传递 信号->信号->槽 一个信号控制多个槽的例子&#xff08;通过水平滑块控制两个组件&#xff09; 1.应用的组件 注意这里最下面的组件…

MongoDB快速上手

MongoDB快速上手 MongoDB用起来-快速上手&集群和安全系列 课程目标&#xff1a; 理解MongoDB的业务场景、熟悉MongoDB的简介、特点和体系结构、数据类型等能够在windows和linux下安装和启动MongoDB、图形化管理界面Compass的安装使用掌握MongoDB基本常用命令实现数据的C…

mysql 、sql server 临时表、表变量、

sql server 临时表 、表变量 mysql 临时表 创建临时表 create temporary table 表名 select 字段 [&#xff0c;字段2…&#xff0c;字段n] from 表

项目解决问题

红外 没接收到红外信号时&#xff0c; 会有杂波干扰 STC单片机 STC的串口要用一个定时器作为波特率发生器 开定时器2需要 开定时器0 1 要ET0 1 ET11打开 串口有时候和定时器有冲突 串口发送函数放定时器中断函数中&#xff0c;时间太少可能会导致一直卡在定时器中AUXR | 0x…