零基础学JavaWeb开发(十二)之 cookie

导读:本篇文章讲解 零基础学JavaWeb开发(十二)之 cookie,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

学习cookie,首先我们得先来了解一下什么是会话技术~

什么是会话技术

1.用户打开同一个浏览器,访问到我们的web服务器的资源建立会话,对方断开连接该会话才会结束,在一次会话中可以包含多次请求和响应。通俗易懂的理解:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于用一个浏览器,以便于在同一次会话的多次请求间共享数据。

2.这是因为http协议是无状态的,每次浏览器向服务器请求时,没有绑定会话信息服务器都会认为该请求是为新请求,没有任何记忆功能,所以我们需要会话跟踪技术实现会话内数据共享。

会话技术实现方式

实现方式:      

1.客户端会话跟踪技术:Cookie      

2.服务端会话跟踪技术:Session

3.token或者jwt—-新的

十六、cookie

1、什么是Cookie

Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问

Cookie 数据存放在浏览器端(客户端)

2、创建Cookie

1.创建Cookie

Cookie cookie = new Cookie(“key”,”value”);

2.使用response响应Cookie给客户端(浏览器)

response.addCookie(cookie);

3.使用response响应Cookie给客户端(浏览器)

Cookie[] cookies = request.getCookies();
cookie.getName();
cookie.getValue();

3、获取Cookie

获取客户端携带的所有Cookie,使用request对象

Cookie[] cookies = request.getCookies();
cookie.getName();
cookie.getValue();
package com.mayikt.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/addCookieServlet")
public class AddCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("mayikt", "yushengjun");
        resp.addCookie(cookie);
    }
}

package com.mayikt.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/getCookieServlet")
public class GetCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (int i = 0; i < cookies.length; i++) {
            Cookie cookie = cookies[i];
            System.out.println("key:" + cookie.getName() + "," +cookie.getValue());
        }
    }
}

在没有清理浏览器缓存的情况下?请问重启tomcat服务器?cookie数据会丢失吗?

不会的

4、Cookie的原理解析

基本实现原理

Cookie实现是基于HTTP协议的

1.响应头:set—cookie

客户端(浏览器端)发送请求达到服务器端,服务器端会创建cookie,会将该cookie数据

返回给客户端,在响应头中设置 set—cookie value cookie数据。

零基础学JavaWeb开发(十二)之 cookie

2.请求头:cookie

同一个浏览器发送请求时,在请求中设置该cookie数据 存放在请求头中。

cookie value

Cookie过期时间

setMaxAge(int seconds):设置Cookie存活时间

1.正数:将Cookie写入浏览器所在的电脑硬盘,持久化存储,到期自动删除 

2.负数:默认值,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁。

3.零:删除对应Cookie

5、session使用

1.服务器端会话跟踪技术:将数据保存在服务器端

底层基于cookie实现封装的

2.常用的API:

2.1 void session.setAttribute(k,v) session存入值 key=name,value ‘yushengjun’

2.2 Object session.getAttribute(k) 获取到session中的值

2.3 void removeAttribute(k) 删除我们的session

6、session原理

1.当我们客户端发送请求达到服务器端时创建session,会得到一个sessionid,在将该

sessionid 响应在响应头<sessionid >

2.客户端(浏览器)接受响应头中的sessionid ,会将该sessionid的值 存放在浏览器中。

session本质上就是基于cookie实现封装的。

3.使用同一个浏览器发送请求时,访问通一个服务器端,会在请求头中设定该sessionid 的值,服务器端就会从请求头中获取到该sessionid 查找对应session。

session 数据存放在服务器端 cookie将数据存放在本地。

零基础学JavaWeb开发(十二)之 cookie

7、session细节

1.当客户端关闭后,服务器不关闭的话,获取到的session是否是同一个。因为客户端关闭后,cookie对象被销毁,客户端请求服务器会创建新的session。如果需要相同,可以设置cookie的最大存活时间,让cookie持久化保存两次获取Session是否为同一个

2.在默认情况下,不是同一个。如果需要两个Session相同,则可以创建一个Cookie对象,key为:JSESSIONID,设置一下最大存活时间,让Cookie持久化保存Session的ID,就可以实现客户端关闭,两次获取Session就是同一个。

Cookie c = new Cookie("JSESSIONID",session.getId());
	    c.setMaxAge(60*60); //1个小时有效期
	    response.addCookie(c);

2.客户端不关闭,服务器关闭后的话,两次获取的Session是同一个吗?

不是同一个,但是为了确保数据不丢失,因为同样服务器关闭后session对象会被销毁 ,如果想确保数据不丢失,可以使session钝化,即在服务器正常关闭之前,将session对象序列化到硬盘上。下次在服务器启动后,将session文件反序列化转化为内存中的session对象即可。

0D202066E021E4F4FB978F1647C0D742

tomcat自动完成以下工作:

1.session的钝化:在服务器正常关闭之前,将session对象系列化到硬盘上。

2.session的活化: 在服务器启动后,将session文件转化为内存中的session对象即可。

3.session什么时候被销毁?

1.服务器关闭;

2.session对象调用invalidate() ;

3.session默认失效时间 30分钟。

token—

8、session与cookie区别

1.session用于存储一次会话的多次请求的数据,存在服务器端;

2.session可以存储任意类型,任意大小的数据。

session与Cookie的区别:

1.session存储数据在服务器端,Cookie在客户端;

2.session没有数据大小限制,Cookie有数据大小限制;

3.session数据安全,Cookie相对于不安全。

9、用户登录注册案例

9.1、用户登录

使用session保存用户会话信息。

数据库访问层

package com.mayikt.dao;

import com.mayikt.entity.MayiktUserEntity;
import com.mayikt.utils.MayiktJdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


public class MayikUsertDao {
    
    /**
    * 用户登录成功之后 该方法返回 用户登录成功之后对象
    */
    public MayiktUserEntity login(String userName, String userPwd) {
        try {
            Connection connection = MayiktJdbcUtils.getConnection();
            String loginSql = "select  * from  mayikt_users where userName=? and userPwd=?;";
            PreparedStatement preparedStatement = connection.prepareStatement(loginSql);
            preparedStatement.setString(1, userName);
            preparedStatement.setString(2, userPwd);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (!resultSet.next()) {  // 查询不到用户数据
                return null;
            }
            // 将db中数据 返回给客户端 查询到数据
            Integer id = resultSet.getInt(1);
            String dbUserName = resultSet.getString(2);
            String dbUserPwd = resultSet.getString(3);
            MayiktUserEntity mayiktUserEntity = new MayiktUserEntity(id, dbUserName, dbUserPwd);
            return mayiktUserEntity;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        
    }
}

业务逻辑层

package com.mayikt.service;

import com.mayikt.dao.MayikUsertDao;
import com.mayikt.entity.MayiktUserEntity;

public class MayikUsertService {
    private MayikUsertDao mayikUsertDao = new MayikUsertDao();

    public MayiktUserEntity login(String userName, String userPwd) {
        return mayikUsertDao.login(userName, userPwd);
    }
}

视图层

package com.mayikt.servlet;

import com.mayikt.entity.MayiktUserEntity;
import com.mayikt.service.MayikUsertService;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;


@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    private MayikUsertService mayikUsertService = new MayikUsertService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 转发login页面
        req.getRequestDispatcher("login.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 点击登录的时候 获取到用户的参数
        String userName = req.getParameter("userName");
        if (StringUtils.isEmpty(userName)) {
            //转发到错误页面
            req.setAttribute("errorMsg", "用户名称不能够是为空!");
            req.getRequestDispatcher("error.jsp").forward(req, resp);
            return;
        }
        String userPwd = req.getParameter("userPwd");
        // 参数验证
        if (StringUtils.isEmpty(userPwd)) {
            //转发到错误页面
            req.setAttribute("errorMsg", "userPwd不能够是为空!");
            req.getRequestDispatcher("error.jsp").forward(req, resp);
            return;
        }
        // 在调用业务逻辑层
        MayiktUserEntity mayiktUserEntity = mayikUsertService.login(userName, userPwd);
        if (mayiktUserEntity == null) {
            // 用户名称或者密码错误!
            req.setAttribute("errorMsg", "用户名称或者是密码错误!");
            req.getRequestDispatcher("login.jsp").forward(req, resp);
            return;
        }
        // 能够db中查询到对象 登录成功了  将用户数据存放在session中
        HttpSession session = req.getSession();
        session.setAttribute("user", mayiktUserEntity);
        // 在转发到首页(重定向到首页)
//        req.getRequestDispatcher("index.jsp").forward(req, resp);
        resp.sendRedirect("index.jsp");
    }
}

<%--
  Created by IntelliJ IDEA.
  User: mayikt
  Date: 2022/6/6
  Time: 17:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>登录测试页面</title>
    <form action="/mayikt_session_war_exploded/login" method="post">
        <label>用户名: </label><input type="text" name="userName"/><br>
        <label>密&nbsp码&nbsp: </label><input type="password" name="userPwd"/><br>
        ${errorMsg}
        <input type="submit" value="登录 "/>
    </form>

</head>
</html>

相关配置文件

driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mayikt?serverTimezone=GMT%2B8
user=root
password=root

9.2、记住密码

思路:

用户登录成功之后,会将用户的名称和密码 写入在cookie中,

当我们用户下次登录时,会直接从cookie中获取到数据 回显到

login.jsp中 这样的话就不需要用户重复的数据用户名称和密码。

零基础学JavaWeb开发(十二)之 cookie

改造servlet

package com.mayikt.servlet;

import com.mayikt.entity.MayiktUserEntity;
import com.mayikt.service.MayikUsertService;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;


@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    private MayikUsertService mayikUsertService = new MayikUsertService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 转发login页面
        req.getRequestDispatcher("login.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 点击登录的时候 获取到用户的参数
        String userName = req.getParameter("userName");
        if (StringUtils.isEmpty(userName)) {
            //转发到错误页面
            req.setAttribute("errorMsg", "用户名称不能够是为空!");
            req.getRequestDispatcher("error.jsp").forward(req, resp);
            return;
        }
        String userPwd = req.getParameter("userPwd");
        // 参数验证
        if (StringUtils.isEmpty(userPwd)) {
            //转发到错误页面
            req.setAttribute("errorMsg", "userPwd不能够是为空!");
            req.getRequestDispatcher("error.jsp").forward(req, resp);
            return;
        }
        // 在调用业务逻辑层
        MayiktUserEntity mayiktUserEntity = mayikUsertService.login(userName, userPwd);
        if (mayiktUserEntity == null) {
            // 用户名称或者密码错误!
            req.setAttribute("errorMsg", "用户名称或者是密码错误!");
            req.getRequestDispatcher("login.jsp").forward(req, resp);
            return;
        }
        // 判断用户是否记住密码
        String rememberPassword = req.getParameter("rememberPassword");
        if ("on".equals(rememberPassword)) {
            // 如果有记住密码则 将密码保存在cookie中
            Cookie userNameCookie = new Cookie("userName", userName);
            Cookie userPwdCookie = new Cookie("userPwd", userPwd);
            resp.addCookie(userNameCookie);
            resp.addCookie(userPwdCookie);
        }
        // 能够db中查询到对象 登录成功了  将用户数据存放在session中
        HttpSession session = req.getSession();
        session.setAttribute("user", mayiktUserEntity);
        // 在转发到首页(重定向到首页)
//        req.getRequestDispatcher("index.jsp").forward(req, resp);
        resp.sendRedirect("index.jsp");
    }
}

改造jsp

<%--
  Created by IntelliJ IDEA.
  User: mayikt
  Date: 2022/6/6
  Time: 17:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>登录测试页面</title>
    <form action="/mayikt_session_war_exploded/login" method="post">
        <label>用户名: </label><input type="text" name="userName" value="${cookie.userName.value}"/><br>
        <label>密&nbsp码&nbsp: </label><input type="password" name="userPwd" value="${cookie.userPwd.value}"/><br>
        <label>记住密码: </label><input type="checkbox" name="rememberPassword"/><br>
        ${errorMsg}
        <input type="submit" value="登录 "/>
    </form>

</head>
</html>

9.3、用户注册

数据库访问层

package com.mayikt.dao;

import com.mayikt.entity.MayiktUserEntity;
import com.mayikt.utils.MayiktJdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


public class MayikUsertDao {
    
    /**
    * 用户登录成功之后 该方法返回 用户登录成功之后对象
    */
    public MayiktUserEntity login(String userName, String userPwd) {
        ResultSet resultSet = null;
        PreparedStatement preparedStatement = null;
        Connection connection = null;
        try {
            connection = MayiktJdbcUtils.getConnection();
            String loginSql = "select  * from  mayikt_users where userName=? and userPwd=?;";
            preparedStatement = connection.prepareStatement(loginSql);
            preparedStatement.setString(1, userName);
            preparedStatement.setString(2, userPwd);
            resultSet = preparedStatement.executeQuery();
            if (!resultSet.next()) {  // 查询不到用户数据
                return null;
            }
            // 将db中数据 返回给客户端 查询到数据
            Integer id = resultSet.getInt(1);
            String dbUserName = resultSet.getString(2);
            String dbUserPwd = resultSet.getString(3);
            MayiktUserEntity mayiktUserEntity = new MayiktUserEntity(id, dbUserName, dbUserPwd);
            return mayiktUserEntity;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            MayiktJdbcUtils.closeConnection(resultSet, preparedStatement, connection);
        }
    }
    
    public MayiktUserEntity findByUserName(String userName) {
        ResultSet resultSet = null;
        PreparedStatement preparedStatement = null;
        Connection connection = null;
        try {
            connection = MayiktJdbcUtils.getConnection();
            String loginSql = "select  * from  mayikt_users where userName=?";
            preparedStatement = connection.prepareStatement(loginSql);
            preparedStatement.setString(1, userName);
            resultSet = preparedStatement.executeQuery();
            if (!resultSet.next()) {  // 查询不到用户数据
                return null;
            }
            // 将db中数据 返回给客户端 查询到数据
            Integer id = resultSet.getInt(1);
            String dbUserName = resultSet.getString(2);
            String dbUserPwd = resultSet.getString(3);
            MayiktUserEntity mayiktUserEntity = new MayiktUserEntity(id, dbUserName, dbUserPwd);
            return mayiktUserEntity;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            MayiktJdbcUtils.closeConnection(resultSet, preparedStatement, connection);
        }
    }
    
    public int register(String userName, String userPwd) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = MayiktJdbcUtils.getConnection();
            // sql语句写的操作 ----加上事务
            MayiktJdbcUtils.beginTransaction(connection); // 开启事务
            String insertSql = "INSERT INTO `mayikt`.`mayikt_users` (`id`, `userName`, `userPwd`) VALUES (null, ?, ?);";
            preparedStatement = connection.prepareStatement(insertSql);
            preparedStatement.setString(1, userName);
            preparedStatement.setString(2, userPwd);
            int result = preparedStatement.executeUpdate();
            // 代码执行没有问题的情况下 则会提交数据
            MayiktJdbcUtils.commitTransaction(connection); // 提交事务
            return result;
        } catch (Exception e) {
            // 程序代码报错之后 是需要回滚事务
            e.printStackTrace();
            MayiktJdbcUtils.rollBackTransaction(connection);// 回滚事务
            return 0;
        } finally {
            MayiktJdbcUtils.closeConnection(preparedStatement, connection);
        }
        
    }
}

业务逻辑层

    public int register(String userName, String userPwd) {
        return mayikUsertDao.register(userName, userPwd);
    }

    public MayiktUserEntity findByUserName(String userName) {
        return mayikUsertDao.findByUserName(userName);
    }

视图层

package com.mayikt.servlet;

import com.mayikt.entity.MayiktUserEntity;
import com.mayikt.service.MayikUsertService;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;


@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
    private MayikUsertService mayikUsertService = new MayikUsertService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 转发到register.jsp
        req.getRequestDispatcher("register.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 转发到注册插入数据
        // 点击注册的时候 获取到用户的参数
        String userName = req.getParameter("userName");
        if (StringUtils.isEmpty(userName)) {
            //转发到错误页面
            req.setAttribute("errorMsg", "用户名称不能够是为空!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        String userPwd = req.getParameter("userPwd");
        // 参数验证
        if (StringUtils.isEmpty(userPwd)) {
            //转发到错误页面
            req.setAttribute("errorMsg", "userPwd不能够是为空!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        // 用户注册之前根据用户名称查询该用户是否存在如果不存在的情况下才可以注册 如果存在的话就无法注册
        MayiktUserEntity dbMayiktUserEntity = mayikUsertService.findByUserName(userName);
        if (dbMayiktUserEntity != null) {
            req.setAttribute("errorMsg", "该用户" + userName + ",在数据库中存在无法重复注册!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        //用户数据注册
        int register = mayikUsertService.register(userName, userPwd);
        if (register <= 0) {
            // 注册失败了   //转发到错误页面
            req.setAttribute("errorMsg", "注册失败!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        // 注册成功之后就直接重定向到登录请求
        resp.sendRedirect("login");
    }
}
<%--
  Created by IntelliJ IDEA.
  User: mayikt
  Date: 2022/6/6
  Time: 17:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>注册页面</title>
    <form action="/mayikt_session_war_exploded/register" method="post">
        <label>用户名: </label><input type="text" name="userName"/><br>
        <label>密&nbsp&nbsp&nbsp码: </label><input type="password" name="userPwd"/><br>
        <span style="color: red">${errorMsg}</span>
        <input type="submit" value="注册"/>
    </form>

</head>
</html>

9.4、图形验证码

图形底层实现原理

java支持根据内容生成图片

abcd 企业实际开发中图形验证码工具类 底层细节我们自己去开发的

1.生成图形验证码内容 abch

2.调用java的api 将我们的该内容 生成一张图片abch

3.将该形验证码内容 abch 存放在session中

用户点击注册时:获取用户输入的图形验证码和session中验证码比对 如果一致的情况下

则开始做注册流程。

零基础学JavaWeb开发(十二)之 cookie

图形验证码工具类

package com.mayikt.utils;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.imageio.ImageIO;

/**
 * 工具类,生成随机验证码
 */
public class RandomValidateCode {
    public static final String MAYIKT_RANDOMVALIDATECODE = "RandomValidateCode";// 放到session中的key
    private Random random = new Random();
    private String randString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生的字符串
    private int width = 100;// 图片宽度
    private int height = 26;// 图片高度
    private int lineSize = 40;// 干扰线数量
    private int stringNum = 4;// 随机产生的字符数量

    /*
     * 获得字体
     */
    private Font getFont() {
        return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
    }

    /*
     * 获得颜色
     */
    private Color getRandColor(int fc, int bc) {
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc - fc - 16);
        int g = fc + random.nextInt(bc - fc - 14);
        int b = fc + random.nextInt(bc - fc - 18);
        return new Color(r, g, b);
    }

    /**
     * 生成随机图片
     */
    public void getRandcode(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,该对象可以在图像上进行各种绘制操作
        g.fillRect(0, 0, width, height);
        g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
        g.setColor(getRandColor(110, 133));
        // 绘制干扰线
        for (int i = 0; i <= lineSize; i++) {
            drowLine(g);
        }
        // 绘制随机字符
        String randomString = "";
        for (int i = 1; i <= stringNum; i++) {
            randomString = drowString(g, randomString, i);
        }
        session.removeAttribute(MAYIKT_RANDOMVALIDATECODE);
        session.setAttribute(MAYIKT_RANDOMVALIDATECODE, randomString);
        g.dispose();
        try {
            ImageIO.write(image, "JPEG", response.getOutputStream());// 将内存中的图片通过流动形式输出到客户端
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 绘制字符串
     */
    private String drowString(Graphics g, String randomString, int i) {
        g.setFont(getFont());
        g.setColor(new Color(random.nextInt(101), random.nextInt(111), random.nextInt(121)));
        String rand = getRandomString(random.nextInt(randString.length()));
        randomString += rand;
        g.translate(random.nextInt(3), random.nextInt(3));
        g.drawString(rand, 13 * i, 16);
        return randomString;
    }

    /*
     * 绘制干扰线
     */
    private void drowLine(Graphics g) {
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        g.drawLine(x, y, x + xl, y + yl);
    }

    /*
     * 获取随机的字符
     */
    public String getRandomString(int num) {
        return String.valueOf(randString.charAt(num));
    }
}

package com.mayikt.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * 前台验证码处点击刷新,发送到该servlet的请求,
 * 该servlet调用生成验证码的工具类返回一个图像验证码
 */
@WebServlet(name = "VerifycodeServlet", urlPatterns = "/VerifycodeServlet")
public class VerifycodeServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
        response.setHeader("Pragma", "No-cache");//设置响应头信息,告诉浏览器不要缓存此内容
        //做浏览器兼容
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);
        RandomValidateCode randomValidateCode = new RandomValidateCode();
        try {
            randomValidateCode.getRandcode(request, response);//输出图片方法
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

注册jsp加上图形验证码

<%--
  Created by IntelliJ IDEA.
  User: mayikt
  Date: 2022/6/6
  Time: 17:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>注册页面</title>
    <form action="/mayikt_session_war_exploded/register" method="post">
        <label>用户名: </label><input type="text" name="userName"/><br>
        <label>密&nbsp&nbsp&nbsp码: </label><input type="password" name="userPwd"/><br>
        <label>验证码: </label><input type="text" name="code"/><img id="exchangecode" src="VerifycodeServlet">
        <a id="ecode" href="#">看不清?换一张图片</a><br>
        <span style="color: red">${errorMsg}</span>
        <input type="submit" value="注册"/>
    </form>
    <script type="text/javascript">
        window.onload = function () {
            //获取img标签的对象
            img = document.getElementById("exchangecode");
            img.onclick = function () {
                //加时间戳,避免浏览器缓存
                var date = new Date().getTime()
                img.src = "VerifycodeServlet?" + date;
            }
            //获取a标签的对象
            ec = document.getElementById("ecode");
            ec.onclick = function () {
                //加时间戳
                var date = new Date().getTime()
                img.src = "VerifycodeServlet?" + date;
            }
        }

    </script>
</head>
</html>

注册验证图形验证码

package com.mayikt.servlet;

import com.mayikt.entity.MayiktUserEntity;
import com.mayikt.service.MayikUsertService;
import com.mayikt.utils.RandomValidateCode;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;


@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
    private MayikUsertService mayikUsertService = new MayikUsertService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 转发到register.jsp
        req.getRequestDispatcher("register.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 转发到注册插入数据
        // 点击注册的时候 获取到用户的参数
        String userName = req.getParameter("userName");
        if (StringUtils.isEmpty(userName)) {
            //转发到错误页面
            req.setAttribute("errorMsg", "用户名称不能够是为空!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        String userPwd = req.getParameter("userPwd");
        // 参数验证
        if (StringUtils.isEmpty(userPwd)) {
            //转发到错误页面
            req.setAttribute("errorMsg", "userPwd不能够是为空!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        // 图形验证码  比较 是在 注册之前
        // 比较图形验证码
        String userCode = req.getParameter("code"); // 用户输入的图形验证码
        // 从session中获取图形验证码
        HttpSession session = req.getSession();
        String sessionCode = (String) session.getAttribute(RandomValidateCode.MAYIKT_RANDOMVALIDATECODE);
        if (!sessionCode.equalsIgnoreCase(userCode)) {
            req.setAttribute("errorMsg", "图形验证码不正确,请重新输入!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        // 用户注册之前根据用户名称查询该用户是否存在如果不存在的情况下才可以注册 如果存在的话就无法注册
        MayiktUserEntity dbMayiktUserEntity = mayikUsertService.findByUserName(userName);
        if (dbMayiktUserEntity != null) {
            req.setAttribute("errorMsg", "该用户" + userName + ",在数据库中存在无法重复注册!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        //用户数据注册
        int register = mayikUsertService.register(userName, userPwd);
        if (register <= 0) {
            // 注册失败了   //转发到错误页面
            req.setAttribute("errorMsg", "注册失败!");
            req.getRequestDispatcher("register.jsp").forward(req, resp);
            return;
        }
        // 注册成功之后就直接重定向到登录请求
        resp.sendRedirect("login");
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/81325.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!