1. 程式人生 > >servlet+jsp+mysql+資料庫連線池實現註冊登陸驗證碼功能

servlet+jsp+mysql+資料庫連線池實現註冊登陸驗證碼功能

首先專案的結構及所用到的jar包如圖:

主要用到jdbc和jstl的jar包,大家可自行去相應網站下載

一、資料庫和資料表的建立

1.建庫語句:

create database test;

2.建表語句:

CREATE TABLE `t_users` (   `user_name` varchar(20) COLLATE utf8_unicode_ci NOT NULL,   `password_md5` varchar(50) COLLATE utf8_unicode_ci NOT NULL,   `email` varchar(30) COLLATE utf8_unicode_ci NOT NULL,   PRIMARY KEY (`user_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

二、eclipse配置資料庫連線池

首先建立一個動態web專案

1.把jdbc所用到的jar包複製到/web-inf/lib目錄下,如圖:

2.在meta-inf下建立一個context.xml檔案,並輸入以下程式碼:

<?xml version="1.0" encoding="UTF-8"?> <Context path="/test" reloadable="true">     <!-- 配置資料來源 -->     <Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="100"     maxldle="30" maxWait="10000" name="jdbc/test" password="root" type="javax.sql.DataSource"     url="jdbc:mysql://localhost:3306/test?autoReconnect=true" username="root">     </Resource> </Context>

<Resource屬性說明>

1)name:指定Resource的JNDI名字。

2)auth:指定管理Resource的Manager,它有兩個可選值:Container和Application。Container表示由容器來建立和管理Resource,Application表示由web應用來建立和管理Resource。

3)type: 指定Resource的Java類名。

4)username:指定連線資料庫的使用者名稱。

5)password:指定連線資料庫的口令。

6)driverClassName:指定連線資料庫的JDBC驅動器中的Driver實現類的名字。

7)url:指定連線資料庫的URL,127.0.0.1是要連線的資料庫伺服器的ip,3306是資料庫伺服器埠,BookDB是資料庫名稱。

8)maxActive:指定資料庫連線池中處於活動狀態的資料庫連線的最大數目,取值為0,表示不受限制。

9)maxIdle:指定資料庫連線池中處於空閒狀態的資料庫連線的最大數目,取值為0,表示不受限制。

10)maxWait:指定資料庫連線池中的資料庫連線處於空閒狀態的最長時間(以毫秒為單位),超過這一時間,將會丟擲異常。取值為-1,表示可以無限期等待。

3.配置web.xml

在<web-app></web-app>之間加入如下程式碼:

  <resource-ref>     <description>MySQL DBCP</description>     <res-ref-name>jdbc/test</res-ref-name>     <res-type>javax.sql.DataSource</res-type>     <res-auth>Container</res-auth>   </resource-ref>

<resource-ref>屬性說明:

1)description:對所引用的資源的說明。

2)res-ref-name:指定所引用資源的JNDI名字,與<Resource>元素中的name屬性對應。

3)res-type:指定所引用資源的類名,與<Resource>元素中的type屬性對應。

4)res-auth:指定管理所引用資源的Manager,與<Resource>元素中的auth屬性對應。

4.配置server.xml檔案

在tomcat\conf下找到server.xml檔案,在<GlobalNamingResources></GlobalNamingResources>之間加入如下內容:

<Resource name="jdbc/test" auth="Container"               type="javax.sql.DataSource"               driverClassName="com.mysql.jdbc.Driver"               url="jdbc:mysql://localhost:3306/test?characterEncodering=utf-8"               username="root"               password="root"               maxActive="200"               maxIdle="50"               maxWait="3000"/>

在<Host></Host>之間加入如下內容:

 <Context docBase="D:\eclipse-workspace\loginRegister\WebContent"          path="/LoginRegister" reloadable="true" source="org.eclipse.jst.j2ee.server:test">          <ResourceLink global="jdbc/test" name="jdbc/test" type="javax.sql.DataSource"/>         </Context>

<Context>屬性說明:

1)docBase:指定Web應用的檔案路徑,可以給定絕對路徑,也可以給定相對於<Host>的appBase屬性的相對路徑。如果Web應用採用開放目錄結構,則指定Web應用的根目錄;如果Web應用是個WAR檔案,則指定WAR檔案的路徑。

2)path:指定訪問該Web應用的URL入口。

3)reloadable:如果這個屬性為true,Tomcat伺服器會在執行狀態下監視classes下檔案的改動和WEB-INF/web.xml檔案的改動,監測到檔案被改動,伺服器會自動重新載入Web應用。

4)source:

<ResourceLink>屬性說明:

1)global:被連線的連線全域性資源的名稱。

2)name:建立的資源連線的名稱,相對於java:comp/env context。

3)type:當web應用在該資源連線上進行查詢時,返回的Java類名的全稱。

至此資料庫連線池配置完

三、實現訪問資料庫的DBServlet類

實現程式碼如下:

import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet;

import javax.naming.Context; import javax.naming.InitialContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource;

/**  * Servlet implementation class DBServlet  */ @WebServlet("/DBServlet") public class DBServlet extends HttpServlet {     private static final long serialVersionUID = 1L;     //用於連線資料庫的Connection物件     protected Connection conn=null;     protected ResultSet execSQL(String sql,Object... args) throws Exception{         //建立Preparedment物件         PreparedStatement pStmt=conn.prepareStatement(sql);         //為pStmt物件設定SQL引數值         for(int i=0;i<args.length;i++) {             pStmt.setObject(i+1,args[i]);  //設定SQL引數值         }         pStmt.execute();  //執行SQL語句         //返回結果集,如果執行的SQL語句不返回結果集,則返回null         return pStmt.getResultSet();     }     //核對使用者輸入的驗證碼是否合法     protected boolean checkValidationCode(HttpServletRequest request,             String validationCode) {         //從httpSession中獲得系統隨機生成的驗證碼         String validationCodeSession=(String)request.getSession()                 .getAttribute("validation_code");         //如果獲得的驗證碼為null,說明驗證碼過期,使用者必須重新整理客戶端頁面,以獲得新的驗證碼         if(validationCodeSession==null) {             //設定result.jsp需要的結果資訊             request.setAttribute("info","驗證碼過期");             //設定login.jsp需要的錯誤資訊             request.setAttribute("codeError","驗證碼過期");             return false;         }         //將使用者輸入的驗證碼和系統隨機生成的驗證碼進行比較         if(!validationCode.equalsIgnoreCase(validationCodeSession)) {             request.setAttribute("info","驗證碼不正確");             request.setAttribute("codeError","驗證碼不正確");             return false;         }         return true;     }          /**      * @see HttpServlet#HttpServlet()      */     public DBServlet() {         super();         // TODO Auto-generated constructor stub     }

    /**      * @see Servlet#destroy()      */     public void destroy() {         // TODO Auto-generated method stub         try {             //如果資料庫連線正常開啟則關閉             if(conn!=null)                 conn.close();         }catch(Exception e) {                      }     }

    /**      * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)      */     protected void service(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         // TODO Auto-generated method stub         try {             //如果conn為null,開啟資料庫連線             if(conn==null) {                 //建立上下文物件ctx                 Context ctx=new InitialContext();                 //TODO                 //獲取資料來源                 DataSource ds=(DataSource)ctx.lookup("java:/comp/env/jdbc/test");                 conn=ds.getConnection();  //為Connection物件賦值             }         }catch(Exception e) {                      }     } }  

四、實現圖形驗證碼

程式碼如下:

import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Random;

import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.*;

public class ValidationCode extends HttpServlet {     //圖形驗證碼的字元集合,系統將隨機從這個字串中選擇一些字元作為驗證碼     private static String codeChars=             "@#$%^&*123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";     //返回一個隨機顏色(Color物件)     private static Color getRandomColor(int minColor,int maxColor) {         Random random=new Random();         //儲存minColor最大不會超過255         if(minColor>255)             minColor=255;         //儲存maxColor最大不會超過255         if(maxColor>255)             maxColor=255;         //獲得hong、綠、藍三種顏色的隨機顏色值         int red=minColor+random.nextInt(maxColor-minColor);         int green=minColor+random.nextInt(maxColor-minColor);         int blue=minColor+random.nextInt(maxColor-minColor);         return new Color(red,green,blue);     }     @Override     protected void service(HttpServletRequest request, HttpServletResponse response)              throws ServletException, IOException {         // TODO Auto-generated method stub         //獲取驗證碼集合的長度         int charsLength=codeChars.length();         //關閉客戶端瀏覽器的緩衝區         response.setHeader("ragma","No-cache");         response.setHeader("Cache-Control","no-cache");         response.setDateHeader("Expires",0);         //設定圖形驗證碼的長和寬         int width=90,height=20;         BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);         //獲得用於輸出文字的Graphics物件         Graphics g=image.getGraphics();         Random random=new Random();         g.setColor(getRandomColor(180,250));  //隨機設定要填充的顏色         g.fillRect(0,0, width, height);  //填充圖形背景         //設定初始字型         g.setFont(new Font("Times New Roman",Font.ITALIC,height));         g.setColor(getRandomColor(120,180));  //隨機設定字型顏色         //用於儲存最後隨機生成的驗證碼         StringBuilder validationCode=new StringBuilder();         //驗證碼的隨機字型         String[] fontNames= {"Times New Roman","Book antiqua","Arial"};         for(int i=0;i<3+random.nextInt(3);i++) {  //隨機生成3-5個驗證碼             //隨機設定當前驗證碼的字元的字型             g.setFont(new Font(fontNames[random.nextInt(3)],Font.ITALIC,height));             //隨機獲得當前驗證碼的字元             char codeChar=codeChars.charAt(random.nextInt(charsLength));             validationCode.append(codeChar);             //隨機設定當前驗證碼字元的顏色             g.setColor(getRandomColor(10,100));             //在圖形上輸出驗證碼字元,x和y都是隨機生成的             g.drawString(String.valueOf(codeChar),                     16*i+random.nextInt(7),height-random.nextInt(6));         }         //獲得HttpSession物件         HttpSession session=request.getSession();         //設定5分鐘失效         session.setMaxInactiveInterval(5*60);         //將驗證碼儲存在session物件中         session.setAttribute("validation_code",validationCode.toString());         g.dispose();  //關閉Graphics物件         OutputStream os=response.getOutputStream();         //以jpeg格式向客戶端傳送圖形驗證碼         ImageIO.write(image,"JPEG",os);     } }  

五、實現註冊系統

1.實現註冊Servlet類

Register.java程式碼如下:

import java.io.IOException;

import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

public class Register extends DBServlet{

    @Override     protected void service(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         // TODO Auto-generated method stub         String userName=null;         if(request.getParameter("login")!=null) {             response.sendRedirect("login.jsp");             return;         }try {             super.service(request, response);             userName=request.getParameter("username");             String password=request.getParameter("password");             String email=request.getParameter("email");             String validationCode=request.getParameter("validation_code");             if(userName==null||password==null||validationCode==null)                 return;             if(userName.equals("")||password.equals("")||validationCode.equals(""))                 return;             userName=new String(userName.getBytes("ISO-8859-1"),"UTF-8");             request.setAttribute("page","register.jsp");             if(!checkValidationCode(request,validationCode))                 return;             email=(email==null)?"":email;             String _password=password;             String sql="insert into t_users(user_name,password_md5,email) values(?,?,?)";             execSQL(sql,userName,_password,email);             request.setAttribute("info","使用者註冊成功!");         }catch(Exception e) {             System.out.println(e.getMessage());             e.printStackTrace();             request.setAttribute("info",userName+"已經被使用!");         }finally {             RequestDispatcher rd=request.getRequestDispatcher("result.jsp");             rd.forward(request,response);         }

    }      }

2.實現這測系統主介面

register.jsp程式碼如下:

<%@ page language="java" contentType="text/html; charset=utf-8"     pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <script type="text/javascript"> function checkRegister(){     var username=document.getElementById("username");     if(username.value==""){         alert("使用者名稱不能為空!");         username.focus();         return;     }     var password=document.getElementById("password");     if(password.value==""){         alert("必須輸入密碼!");         password.focus();         return;     }     var repassword=document.getElementById("repassword");     if(repassword.value!=password.value){         alert("兩次輸入的密碼不一致!");         repassword.focus();         return;     }     var email=document.getElementById("email");     if(email.value!==""){         if(!checkEmail(email))             return;     }     var validation_code=document.getElementById("validation_code");     if(validation_code.value==""){         alert("驗證碼b不能為空");         validation_code.focus();         return;     }     register_form.submit(); } function checkEmail(email){     var email=email.value;     var pattern =/^([a-zA-Z0-9._-])[email protected]([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;     flag=pattern.test(email);     if(!flag){         alert("email格式不正確");         email.focus();         return false;     }     return true; } function refresh(){     var img=document.getElementById("img_validation_code")     img.src="validation_code?"+Math.random(); } </script> <meta charset="utf-8"> <title>註冊頁面</title> </head> <body> <form name="register_form" action="register" method="post"> <span class="require">*</span>使用者名稱: <input type="text" id="username"  name="username" size="30" maxLength="30"/><br/> <span class="require">*</span>密碼: <input type="password" id="password" name="password" size="30" maxLength="30"/><br/> <span class="require">*</span>請再次輸入密碼: <input type="password" id="repassword" name="repassword" size="30" maxLength="30"/><br/> 郵箱地址: <input type="text" id="email" name="email" size="30" maxLength="30"/><br/> <span class="require">*</span>驗證碼: <input type="text" id="validation_code" name="validation_code"  style="width:60px;margin-top:2px" size="30" maxLength="30"/> <img id="img_validation_code" src="validation_code"/> <input type="button" value="重新整理"  onclick="refresh()"/><br/> <input type="button" value="註冊"  onclick="checkRegister()"/> <input type="submit" value="登陸"  name="login"/> </form> </body> </html>

3.實現結果jsp頁面

result.jsp程式碼如下:

<%@ page language="java" contentType="text/html; charset=utf-8"     pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>結果頁</title> </head> <body> <form name="form" action="${requestScope.page}" method="post"/> <script type="text/javascript">   <c:if test="${requestScope.info!=null}">     alert('${requestScope.info}');     form.submit();   </c:if> </script> </body> </html>

六、實現登陸系統

1.實現登陸servlet

Login.java程式碼如下:

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

import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

public class Login extends DBServlet{

    @Override     protected void service(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         // TODO Auto-generated method stub         if(request.getParameter("register")!=null) {             response.sendRedirect("register.jsp");             return;         }         String page="login.jsp";         String userName="";         try {             super.service(request, response);             userName=request.getParameter("username");             String password=request.getParameter("password");             String validationCode=request.getParameter("validation_code");             if(userName==null||password==null||validationCode==null)                 return;             if(userName.equals("")||password.equals("")||validationCode.equals(""))                 return;             userName=new String(userName.getBytes("ISO-8859-1"),"UTF-8");             if(!checkValidationCode(request,validationCode))                 return;             String sql="select user_name,password_md5 from t_users where user_name=?";             ResultSet rs=execSQL(sql,new Object[]{userName});             if(rs.next()==false) {                 request.setAttribute("userError",userName+"不存在");             }else {                 if(!rs.getString("password_md5").equals(password))                     request.setAttribute("passwordError","密碼不正確");                 else page="WEB-INF/main.jsp";                 //TODO             }         }catch(Exception e) {         }finally {             request.setAttribute("username",userName);             RequestDispatcher rd=request.getRequestDispatcher(page);             rd.forward(request,response);         }     }      }

在web-inf下建立main.jsp

之所以把main.jsp放到web-inf目錄中,是因為這個目錄中的檔案在客戶端瀏覽器是無法直接訪問的,一般需要驗證才能訪問的頁面都應該放在該目錄或其子目錄中

main.jsp的程式碼如下:

<%@ page language="java" contentType="text/html; charset=utf-8"     pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>登陸成功</title> </head> <body> 登陸成功 </body> </html>

2.實現登陸系統主介面

login.jsp程式碼如下:

<%@ page language="java" contentType="text/html; charset=utf-8"     pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>登陸頁面</title> <script type="text/javascript"> function checkLogin(){     var username=document.getElementById("username");     if(username.value==""){         alert("使用者名稱不能為空!");         username.focus();         return;     }     var password=document.getElementById("password");     if(password.value==""){         alert("必須輸入密碼!");         password.focus();         return;     }     var validation_code=document.getElementById("validation_code");     if(validation_code.value==""){         alert("驗證碼不能為空");         validation_code.focus();         return;     }     login_form.submit(); } function refresh(){     var img=document.getElementById("img_validation_code")     img.src="validation_code?"+Math.random(); } </script> </head> <body> <form name="login_form" action="login" method="post">   賬號:   <input type="text" id="username" value="${requestScope.username}"   name="username" size="30" maxLength="30"/>   <font color="#FF0000">${requestScope.userError}</font><br/>   密碼:   <input type="password" id="password" name="password" size="30"/>   <font color="#FF0000">${requestScope.passwordError}</font><br/>   驗證碼:   <input type="text" id="validation_code" name="validation_code"    style="width:60ox;margin-top:2px;" size="30" maxLength="30"/>   <font color="#FF0000">${requestScope.codeError}</font>   <img id="img_validation_code" src="validation_code"/>   <input type="button" value="重新整理" onclick="refresh()"/><br/>   <input type="button" value="登陸" name="login" onclick="checkLogin()"/>   <input type="submit" value="註冊" name="register"/> </form> </body> </html>

最後elipse啟動tomcat即可執行