首先要有生成驗證碼圖片和驗證碼文字的邏輯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("執行成功~!"); } }
在前臺添加一個驗證碼的點擊事件,當用戶點擊驗證碼時自動切換驗證碼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); } }