• 6.后台验证码-session作用域


    首先要有生成验证码图片和验证码文字的逻辑

    package cn.bingou.util;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.util.Random;
    import javax.imageio.ImageIO;
    /**
     * 动态生成图片
     */
    public class VerifyCode {
        // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
        private static String[] fontNames = { "宋体", "华文楷体", "黑体", "微软雅黑",  "楷体_GB2312" };
        // 可选字符
        //"23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
        private static String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
        // 背景色
        private Color bgColor = new Color(255, 255, 255);
        // 基数(一个文字所占的空间大小)
        private int base = 30;
        // 图像宽度
        private int width = base * 4;
        // 图像高度
        private int height = base;
        // 文字个数
        private int len = 4;
        // 设置字体大小
        private int fontSize = 22;
        // 验证码上的文本
        private String text;
    
        private BufferedImage img = null;
        private Graphics2D g2 = null;
    
        /**
         * 生成验证码图片
         */
        public void drawImage(OutputStream outputStream) {
            // 1.创建图片缓冲区对象, 并设置宽高和图像类型
            img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            // 2.得到绘制环境
            g2 = (Graphics2D) img.getGraphics();
            // 3.开始画图
            // 设置背景色
            g2.setColor(bgColor);
            g2.fillRect(0, 0, width, height);
    
            StringBuffer sb = new StringBuffer();// 用来装载验证码上的文本
    
            for (int i = 0; i < len; i++) {
                // 设置画笔颜色 -- 随机
                // g2.setColor(new Color(255, 0, 0));
                g2.setColor(new Color(getRandom(0, 150), getRandom(0, 150),getRandom(0, 150)));
    
                // 设置字体
                g2.setFont(new Font(fontNames[getRandom(0, fontNames.length)], Font.BOLD, fontSize));
    
                // 旋转文字(-45~+45)
                int theta = getRandom(-45, 45);
                g2.rotate(theta * Math.PI / 180, 7 + i * base, height - 8);
    
                // 写字
                String code = codes.charAt(getRandom(0, codes.length())) + "";
                g2.drawString(code, 7 + i * base, height - 8);
                sb.append(code);
                g2.rotate(-theta * Math.PI / 180, 7 + i * base, height - 8);
            }
    
            this.text = sb.toString();
    
            // 画干扰线
            for (int i = 0; i < len + 2; i++) {
                // 设置画笔颜色 -- 随机
                // g2.setColor(new Color(255, 0, 0));
                g2.setColor(new Color(getRandom(0, 150), getRandom(0, 150),
                        getRandom(0, 150)));
                g2.drawLine(getRandom(0, 120), getRandom(0, 30), getRandom(0, 120),
                        getRandom(0, 30));
            }
            /**
             * 绘制边框
             */
            // 设置边框的颜色
            g2.setColor(Color.GRAY);
            // 绘制边框
            g2.drawRect(0, 0, width-1, height-1);
            
            // 4.保存图片到指定的输出流
            try {
                 ImageIO.write(this.img, "JPEG", outputStream);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }finally{
                // 5.释放资源
                g2.dispose();
            }
        }
        
        /**
         * 获取验证码字符串
         * @return
         */
        public String getCode() {
            return this.text;
        }
    
        /*
         * 生成随机数的方法
         */
        private static int getRandom(int start, int end) {
            Random random = new Random();
            return random.nextInt(end - start) + start;
        }
        
        public static void main(String[] args) throws Exception {
            VerifyCode vc = new VerifyCode();
            vc.drawImage(new FileOutputStream("d:/vc.jpg"));
            System.out.println("执行成功~!");
        }
    }
    VerifyCode

    在前台添加一个验证码的点击事件,当用户点击验证码时自动切换验证码

        // 为img标签添加一个点击事件
        $("#valiImage").click(function(){
            // 每次点击修改src属性的值,在后面拼接一个不同的参数
            // 获取当前时间的毫秒值表示
            var timeStr=new Date().getTime();
            // 将毫秒之直接拼接在url后面,保证每次点击url的值不同
            var url="/ValiImageServlet?time="+timeStr;
            // 使用生成的url给img标签的src属性赋值
            $("#valiImage").attr("src",url);
        });    

    此时会请求后台处理逻辑 ValiImageServlet

    package cn.bingou.web;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import cn.bingou.util.VerifyCode;
    
    public class ValiImageServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            // 1.接收请求
            
            // 2.调用工具类,生成验证码图片
            VerifyCode vc=new VerifyCode();
            // 3.将生成的验证码图片存入response实体中
            vc.drawImage(resp.getOutputStream());
            // 4.控制浏览器不要缓存验证码
            // 获取验证码字符串
            String text=vc.getCode();
            // 将生成的验证码文本输出到控制台
            System.out.println("text="+text);
            // 获取用户的Session对象
            HttpSession session=req.getSession();
            // 将正确的验证码文本传入Session作用域
            session.setAttribute("text", text);
            // 不要缓存验证码
            resp.setHeader("Pragma", "no-cache");
            resp.setHeader("Cache-Control", "no-cache");
            
        }
    
        public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            doGet(req, resp);
        }
    
    }

    后台ValiImageServlet将从VerifyCode得到的验证码图片和文字传输到前台,通过session作用域传递

    前台点击提交表单按钮,表单信息将会传输到RegistServlet进行验证

    package cn.bingou.web;
    
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    
    import cn.bingou.util.JDBCUtils;
    import cn.bingou.util.WebUtils;
    
    public class RegistServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
    
            // 1.请求乱码问题
                // 请求乱码-POST请求
            req.setCharacterEncoding("utf-8");
                // 应答乱码问题
            resp.setContentType("text/html;charset=utf-8");
            
            // 2.接收表单参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            String password2 = req.getParameter("password2");
            String nickname = req.getParameter("nickname");
            String email = req.getParameter("email");
            String valistr = req.getParameter("valistr");
            
            // 3.验证表单
                // 1)非空验证
                
            if(WebUtils.isEmpty(username)){ // 用户名为空验证
                // 向request作用域中添加错误提示信息
                req.setAttribute("errMsg", "用户名不能为空!");
                // 将请求转发给regist.jsp,forward():请求转发
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                // 如果用户输入为空,直接返回
                return;
            }
            if(WebUtils.isEmpty(password)){ // 密码为空验证
                req.setAttribute("errMsg", "密码不能为空!");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            if(WebUtils.isEmpty(nickname)){ // 昵称为空验证
                req.setAttribute("errMsg", "昵称不能为空!");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            if(WebUtils.isEmpty(email)){ // 邮箱为空验证
                req.setAttribute("errMsg", "邮箱不能为空!");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            
                // 2)密码一致验证
            if(!password.equals(password2)){
                // 如果密码与确认密码不一样,则输出错误
                req.setAttribute("errMsg", "密码不一致");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            
                // 3)邮箱格式验证
                // abc@123.163.com
            String reg="^\w+@\w+(\.\w+)+$"; 
            if(!email.matches(reg)){
                req.setAttribute("errMsg", "邮箱格式不符");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
                    
                // 4)用户名是否存在
            String sql1="select * from user where username=?";
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs=null;
            try {
                conn=JDBCUtils.getConnection();
                ps=conn.prepareStatement(sql1);
                ps.setString(1, username);
                rs=ps.executeQuery();
                while(rs.next()){ // 寻找用户名,直到找到为止
                    req.setAttribute("errMsg", "用户名已存在");
                    req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                    return;
                }
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("验证用户名时数据库出现异常:"+e.getMessage());
            } finally{
                JDBCUtils.close(conn, ps, rs);
            }
            
            
                // 5)验证码验证
            if(WebUtils.isEmpty(valistr)){ // 验证码为空验证
                req.setAttribute("errMsg", "验证码不能为空!");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            } else{
                // 验证码不为空,执行验证码内容验证
                // 获取保存在session中的正确验证码
                HttpSession session=req.getSession(false);// 如果当前Session没有就为null
                boolean flag=true; // 默认验证码没有问题
                if(session==null && session.getAttribute("text")==null){
                    // 没有session对象,或者session中没有正确的验证码文本
                    flag=false;
                }else{
                    String text=(String) session.getAttribute("text");
                    if(!valistr.equalsIgnoreCase(text)){
                        // 用户输入的文本和正确文本不一致
                        flag=false;
                    }
                }
                if(flag==false){
                    // 向request作用域中添加错误提示信息
                    req.setAttribute("errMsg", "验证码错误");
                    // 将请求转发给regist.jsp
                    req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                    return;
                }
            }
            
            
            // 4.数据存入数据库
            // 验证信息没有问题,将用户提交的注册信息提交到数据库
            String sql2="insert into user values(null,?,?,?,?)";
            Connection conn2=null;
            PreparedStatement ps2=null;
            try {
                conn2=JDBCUtils.getConnection();
                ps2=conn2.prepareStatement(sql2);
                ps2.setString(1, username);
                ps2.setString(2, password);
                ps2.setString(3, nickname);
                ps2.setString(4, email);
                ps2.executeUpdate();
                int i=ps2.executeUpdate();
                if(i>0){
                    // 保存成功-提示成功信息,定时刷新到首页
                    resp.getWriter().write("<h1 style='text-align:center;color:red'>恭喜您,注册成功!3秒后自动跳转首页</h1>");
                    // 实现定时刷新
                    resp.setHeader("refresh", "3;url="+req.getContextPath()+"/index.jsp");
                }else{
                    req.setAttribute("errMsg", "注册出现异常,请稍后重试...");
                    req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                    return;
                }
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("注册数据出现异常:"+e.getMessage());
            } finally{
                JDBCUtils.close(conn2, ps2, rs);
            }
        }
    
        public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            doGet(req, resp);
        }
    
    }
  • 相关阅读:
    Sqlite框架Delphi10.3(07)
    FastReport 6.8.11在Delphi10.3上的安装
    Delphi 中,InputQuery 函数的妙用
    Javaday25(sax解析xml,json,设计模式)
    并发学习第五篇——volatile关键字
    并发学习第四篇——synchronized关键字
    并发学习第二篇——Thread
    并发学习第一篇——Runnable
    git-仓库迁移并保留commit log
    并发编程理论基础二——画图理解
  • 原文地址:https://www.cnblogs.com/chuijingjing/p/9744587.html
Copyright © 2020-2023  润新知