6.後臺驗證碼-session做用域

首先要有生成驗證碼圖片和驗證碼文字的邏輯html

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

在前臺添加一個驗證碼的點擊事件,當用戶點擊驗證碼時自動切換驗證碼java

    // 爲img標籤添加一個點擊事件
    $("#valiImage").click(function(){
        // 每次點擊修改src屬性的值,在後面拼接一個不一樣的參數
        // 獲取當前時間的毫秒值表示
        var timeStr=new Date().getTime();
        // 將毫秒之直接拼接在url後面,保證每次點擊url的值不一樣
        var url="/ValiImageServlet?time="+timeStr;
        // 使用生成的url給img標籤的src屬性賦值
        $("#valiImage").attr("src",url);
    });    

此時會請求後臺處理邏輯 ValiImageServletweb

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做用域傳遞sql

前臺點擊提交表單按鈕,表單信息將會傳輸到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);
    }

}
相關文章
相關標籤/搜索