【JavaWeb實現數據庫應用系統】2020年4月30日_驗證碼功能的添加

4月30日(今天有課,更新較晚)


  • 更新的功能:
  1. 驗證碼功能;
  2. 驗證碼可點擊圖片進行刷新操作;
  3. 驗證碼不區分大小寫(全部轉換爲小寫字母進行比較);
  4. 對於錯誤提示:
    (1)先對驗證碼進行判斷;
    (2)若驗證碼正確再去查詢數據庫中的用戶信息(效率較高一些);

  • 遇到的問題:
  1. 空指針異常一次:
    處理驗證碼過程中應該用用戶輸入的驗證碼和圖片上的驗證碼進行對比;
user_code.equals(system_code)
//若使用:
system_code.equals(user_code);
//報空指針異常(需要注意)
//因爲前面我們進行輸入驗證碼時候進行了判斷是否是空的處理,所以不用擔心出錯
  1. 生成驗證碼圖片的時候進行的處理(卡在這好長時間)
    (1)添加干擾線;
    (2)將驗證碼進行不同程度的旋轉;
    (3)生成圖片
    (4)刷新驗證碼(需要控制瀏覽器不要緩存);
    (5)爲了防止干擾,將數字0和大小寫字母O去掉;

  • 這次遇到了挺多問題,不管花費多長時間,最終解決了就好,這次用的是數字和英文字母結合的驗證碼,在原有的基礎上添加了進去,效果如下:
  1. 正常界面
    在這裏插入圖片描述
  2. 如果驗證碼輸入錯誤:
    在這裏插入圖片描述
  • 顯然驗證碼輸入爲空時,無法通過。
    在這裏插入圖片描述

  • 代碼如下(對於上次的更改)
  1. LoginServlet.java的更新
package Servlet;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.mysql.jdbc.Connection;

import db_connect.DBConnect;

public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
 
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		request.setCharacterEncoding("UTF-8");
		
		int success = 0;	//判斷是否登錄成功
		
		Connection connection = (Connection) DBConnect.getConnection();
		Statement statement = null;		
		ResultSet resultSet = null;
		
		String username = (String)request.getParameter("username");
		String password = (String)request.getParameter("password");
		String path = "";
		String msg = "";
		System.out.println("username" + username + "/n" + "password" + password);
		
		
		//接收客戶端瀏覽器提交上來的驗證碼
		
		String system_code = request.getParameter("validateCode");

		//從服務器端的session中取出驗證碼
		 String user_code = (String) request.getSession().getAttribute("checkcode");	
		 
		 //轉換成小寫進行比較
		 user_code = user_code.toLowerCase();
		 system_code = system_code.toLowerCase();
		if(user_code.equals(system_code)) {//判斷驗證碼是否正確
			try {
				statement = (Statement) connection.createStatement();
			}catch(SQLException e) {
				e.printStackTrace();
			}
			//查詢語句
			String sql = "select * from User";
			
			try {
				//將所有信息存入結果集
				resultSet = statement.executeQuery(sql);
			}catch(SQLException e) {
				e.printStackTrace();
			}
			
			try {
				
				while(resultSet.next()) {
					String user_name = resultSet.getString("user_name");
					String pass_word = resultSet.getString("pass_word");
					int is_admin = resultSet.getInt("is_admin");
					//判斷用戶信息正誤
					if(user_name.equals(username) && pass_word.equals(password)) {
						
						Cookie cookie = new Cookie("username" , username);
						//設置生存週期:
						cookie.setMaxAge(60*60*24*7);
						
						HttpSession session = request.getSession();
						session.setAttribute("user", username);
						
						response.addCookie(cookie);
						
						//判斷是否爲管理員
						
						if(is_admin == 1)	path = "admin.jsp";
						else path = "user.jsp";
						//找到了就應該退出循環:
						success = 1;
						break;
					}else {
						//登陸失敗,返回登陸頁面,併發出提示
						success = 0;
					}
				}
			
			} catch (SQLException e) {
				e.printStackTrace();
			}
			if(success == 0) {
				path = "login.jsp";
				msg = "Username or Password Error!";
			}
		}else {//驗證碼錯誤的時候
			msg = "驗證碼輸入錯誤!";
			path = "login.jsp";
		}
		 
		
		request.setAttribute("username", username);
		request.setAttribute("msg", msg);
		
		RequestDispatcher dispatcher = request.getRequestDispatcher(path);
		
		dispatcher.forward(request, response);
	}

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

}

  1. DrawImageServlet.java
package Servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
  生成隨機圖片,用來作爲驗證碼
 */
public class DrawImageServlet extends HttpServlet {
	 private static final long serialVersionUID = 3038623696184546092L;
	  
	 public static final int WIDTH = 120;//生成的圖片的寬度
	 public static final int HEIGHT = 30;//生成的圖片的高度
	 
	 public void doPost(HttpServletRequest request, HttpServletResponse response)
	  throws ServletException, IOException {
		 //1.在內存中創建一張圖片
		 BufferedImage picture = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
		 //2.得到圖片
		 Graphics g = picture.getGraphics();
		 //3.設置圖片的背影色
		 setBackGround(g);
		 //4.設置圖片的邊框
		 setBorder(g);
		 //5.在圖片上畫干擾線
		 drawRandomLine(g);
		 //6.寫在圖片上隨機數
		//生成數字和字母組合的驗證碼圖片
		 String random = drawRandomNum((Graphics2D) g,"nl");

		 request.getSession().setAttribute("checkcode", random);
		 //8.設置響應頭通知瀏覽器以圖片的形式打開
		 //也可以寫成response.setHeader("Content-Type", "image/jpeg");
		 response.setContentType("image/jpeg");
		 //9.設置響應頭控制瀏覽器不要緩存
		 response.setDateHeader("expries", -1);
		 response.setHeader("Cache-Control", "no-cache");
		 response.setHeader("Pragma", "no-cache");
		 //10.將圖片寫給瀏覽器
		 ImageIO.write(picture, "jpg", response.getOutputStream());
	 }
	 
	//驗證碼圖片的顏色
	 private void setBackGround(Graphics g) {
		 // 設置顏色
		 g.setColor(Color.WHITE);
		 // 填充區域
		 g.fillRect(0, 0, WIDTH, HEIGHT);
	 }
	 
	 //設置圖片的邊框
	 private void setBorder(Graphics g) {
		 // 設置邊框顏色
		 g.setColor(Color.BLUE);
		 // 邊框區域
		 g.drawRect(1, 1, WIDTH - 2, HEIGHT - 2);
	 }
	 
	//圖片上的隨機干擾線條
	 private void drawRandomLine(Graphics g) {
		 // 設置顏色
		 g.setColor(Color.GREEN);
		 // 設置線條個數並畫線
		 for (int i = 0; i < 5; i++) {
		  int x1 = new Random().nextInt(WIDTH);
		  int y1 = new Random().nextInt(HEIGHT);
		  int x2 = new Random().nextInt(WIDTH);
		  int y2 = new Random().nextInt(HEIGHT);
		  g.drawLine(x1, y1, x2, y2);
		 }
	 }
	 
	//隨機字符的添加
	 private String drawRandomNum(Graphics2D g,String... createTypeFlag) {
	 // 設置顏色
	 g.setColor(Color.RED);
	 // 設置字體
	 g.setFont(new Font("宋體", Font.BOLD, 20));
	 //數字和字母的組合,去除字母O和數字0
	 String baseNumLetter = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz";
	 //createTypeFlag[0]==null表示沒有傳遞參數
	 if (createTypeFlag.length > 0 && null != createTypeFlag[0]) {
		  return createRandomChar(g, baseNumLetter);
	 }
	 	return "";
	 }
	 
		//創建隨機字符
	 private String createRandomChar(Graphics2D g,String baseChar) {
			 StringBuffer sb = new StringBuffer();
			 int x = 5;
			 String ch ="";
			 // 驗證碼長度爲4
			 for (int i = 0; i < 4; i++) {
			  // 設置字體旋轉角度
			  int degree = new Random().nextInt() % 30;
			  ch = baseChar.charAt(new Random().nextInt(baseChar.length())) + "";
			  sb.append(ch);
			  // 正向角度
			  g.rotate(degree * Math.PI / 180, x, 20);
			  g.drawString(ch, x, 20);
			  // 反向角度
			  g.rotate(-degree * Math.PI / 180, x, 20);
			  x += 30;
		 }
		 return sb.toString();
	 }
	 
	 public void doGet(HttpServletRequest request, HttpServletResponse response)
	  throws ServletException, IOException {
		 this.doPost(request, response);
	 }
}

  1. login.jsp的更新
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="util.CookieUtil" %>
<%@ page import = "java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
 <script type="text/javascript">
 //刷新驗證碼
	 function changeImg(){
	 
	 	document.getElementById("validateCodeImg").src="DrawImageServlet?"+Math.random();
	 	
	 }
 </script>

</head>
<body background="pic\login.jpg" style=" 
		background-repeat:no-repeat ;
		background-size:100% 100%;
		background-attachment: fixed;">
	<br><br><br><br><br> 
	<div class = "div0">
	<%	
		String username = CookieUtil.getCookie("username",request);
		String user = (String)request.getAttribute("msg");
		if(user != null){
			out.println(user);
		}
	%>
	<br><br>
		<center><span style="color:red">歡迎使用數據庫管理系統</span></center><br>
		<center><span style="color:red">請先登錄</span></center><br>
	
	</div>
	  <div class = "div1">
        <form action="LoginServlet" method="post">  
            <input type="text" required="required" placeholder="用戶名" name="username"></input>  <br>
            <input type="password" required="required" placeholder="密碼" name="password"></input>  <br>
            <input type="text" required="required" placeholder="驗證碼" name="validateCode" class = "checkcode"></input>
            <img alt="驗證碼看不清,換一張" src="DrawImageServlet" id="validateCodeImg" onclick="changeImg(this,'nl')"><br>
            <button class="but" type="submit">登錄</button>  
        </form>  
 
    </div>
    <style>
    .checkcode{
    	width: 139px;   
	    height: 18px;   
	    margin-bottom: 10px;   
	    outline: none;   
	    padding: 10px;   
	    font-size: 16px;   
	    color: blue;   
	    text-shadow:1px 1px 1px;   
	    border-top: 1px solid #312E3D;   
	    border-left: 1px solid #312E3D;   
	    border-right: 1px solid #312E3D;   
	    border-bottom: 1px solid #56536A;   
	    border-radius: 4px;   
    }
    
    img{
    	width: 110px;   
	    height: 40px;  
	    margin-bottom:-23px;
	    padding: 10px;   
	    color: blue;   
	    text-shadow:1px 1px 1px;   
    }
    .div0{
    	color:red;
    	text-align:center;
    	margin:0 auto;
    	font-size: 20px;
    	text-shadow:1px 1px 1px; 
    }
    
    .div1{
    		text-align:center;
  			margin:0 auto;
		    width: 300px;   
		    height: 300px;  
    }
    
    
    .but{   
	    width: 300px;   
	    min-height: 20px;   
	    display: block;   
	    background-color: #4a77d4;   
	    border: 1px solid #3762bc;   
	    color: #fff;   
	    padding: 9px 14px;   
	    font-size: 15px;   
	    line-height: normal;   
	    border-radius: 5px;   
	    margin: 0;   
	}  
	
	
	
	input{   
	    width: 278px;   
	    height: 18px;   
	    margin-bottom: 10px;   
	    outline: none;   
	    padding: 10px;   
	    font-size: 16px;   
	    color: blue;   
	    text-shadow:1px 1px 1px;   
	    border-top: 1px solid #312E3D;   
	    border-left: 1px solid #312E3D;   
	    border-right: 1px solid #312E3D;   
	    border-bottom: 1px solid #56536A;   
	    border-radius: 4px;   
	}   
	    
    </style>

</body>
</html>

今天有課程,並且驗證碼剛剛學會,更新較少,明天更新主界面吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章