其實實現代碼的邏輯很是簡單,真的超級超級簡單。java
一、在登陸頁面上login.jsp將驗證碼圖片使用標籤<img src="xxx">將繪製驗證碼圖片的url給它瀏覽器
二、在服務器端就兩個servlet,一個就是用來繪製驗證碼圖片的VerifyCodeServlet,另外一個就是登陸時驗證驗證碼是否點寫正確或是否重複提交的LoginServlet緩存
三、在VerifyCodeServlet中,將驗證碼的四個字母存入session中,而後在LoginServlet中,將請求中提交過來的驗證碼與session中的進行對比,若是正確,則驗證成功,而且將session中的驗證碼刪除,爲何要刪除?保證session中的數據只能被用一次,防止重複提交數據,若是不正確,就使用request,將錯誤信息保存,而後請求轉發到登陸頁面顯示錯誤信息,若是發現session中的數據爲null,說明重複提交了數據,也將錯誤信息用一樣的方法返回到登陸頁面。服務器
難點就在於:VerifyCodeServlet的代碼實現.對繪圖的代碼不是很熟悉。session
login.jspapp
<body> <% String msg = (String)request.getAttribute("msg"); if(msg != null){ out.print(msg); } %> <form action="/test01/LoginServlet" method="post"> 用戶名:<input type="text" name="username" /> <br/> 驗證碼:<input type="text" name="verifyCode" size="5" /> <img src="/test01/VerifyCodeServlet" /> <br/> <input type="submit" value="提交"/> </form> </body>
VerifyCodeServlet.javadom
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //聲明驗證碼 int width = 60; int height = 30; String data = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghijklmnpqrstuvwxyz"; //隨機字符字典,其中0,o,1,I 等難辨別的字符最好不要 Random random = new Random();//隨機類 //1 建立圖片數據緩存區域(核心類) BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//建立一個彩色的圖片 //2 得到畫板(圖片,ps圖層),繪畫對象。 Graphics g = image.getGraphics(); //3 選擇顏色,畫矩形3,4步是畫一個有內外邊框的效果 g.setColor(Color.BLACK); g.fillRect(0, 0, width, height); //4白色矩形 g.setColor(Color.WHITE); g.fillRect(1, 1, width-2, height-2); /**1 提供緩存區域,爲了存放4個隨機字符,以便存入session */ StringBuilder builder = new StringBuilder(); //5 隨機生成4個字符 //設置字體顏色 g.setFont(new Font("宋體", Font.BOLD&Font.ITALIC, 20)); for(int i = 0 ; i < 4 ;i ++){ //隨機顏色 g.setColor(new Color(random.nextInt(255),random.nextInt(255), random.nextInt(255))); //隨機字符 int index = random.nextInt(data.length()); String str = data.substring(index, index + 1); /**2 緩存*/ builder.append(str); //寫入 g.drawString(str, (width / 6) * (i + 1) , 20); } //給圖中繪製噪音點,讓圖片不那麼好辨別 for(int j=0,n=random.nextInt(100);j<n;j++){ g.setColor(Color.RED); g.fillRect(random.nextInt(width),random.nextInt(height),1,1);//隨機噪音點 } /**3 得到隨機數據,並保存session*/ String tempStr = builder.toString(); request.getSession().setAttribute("sessionCacheData",tempStr); //.. 生成圖片發送到瀏覽器 --至關於下載 ImageIO.write(image, "jpg", response.getOutputStream()); }
LoginServlet.javajsp
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1 得到用戶輸入的驗證碼 String verifyCode = request.getParameter("verifyCode"); //2 得到服務器session 存放數據 ,若是沒有返回null String sessionCacheData = (String) request.getSession().getAttribute("sessionCacheData"); // *將服務器緩存session數據移除 request.getSession().removeAttribute("sessionCacheData"); // ** 判斷服務器是否存在 if(sessionCacheData == null){ request.setAttribute("msg", "請不要重複提交"); request.getRequestDispatcher("/login.jsp").forward(request, response); return; } //3 比較 if(! sessionCacheData.equalsIgnoreCase(verifyCode)){ //用戶輸入錯誤 // * 存放request做用域 request.setAttribute("msg", "驗證碼輸入錯誤"); // * 請求轉發 request.getRequestDispatcher("/login.jsp").forward(request, response); return; } //...... 登陸操做 } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
效果圖:ide
驗證碼錯誤時:post
注意:
若是要拷貝代碼的話,須要改就應該就是那幾處url,你的確定跟個人不同,而且有些人設置的servlet的訪問路徑也不同,因此拷貝的話只須要拷貝關鍵代碼便可。