Servlet實現帶驗證碼登陸功能Demo
“紙上得來終覺淺”,動手比看書印象更深,學到的更多。下面用Servlet實現簡單的登陸功能,來鞏固對Servlet的學習。
1、在WEB-INF下新建一個名為index.html作為登陸介面。
index.html程式碼如下:
2、在src目錄下,新建名為Login的Servlet<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form method='post' action='login.do'> <input type='text' name='username'><br/> <input type='password' name='password'><br/> <input type="submit" value="Login"> </form> </body> </html>
Login.java程式碼如下:
注:在驗證使用者名稱和密碼後,主要用到了RequestDispatcher調派請求。package com.demo; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class LoginServlet */ @WebServlet("/login.do") public class Login extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public Login() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if( loginCheck(username, password)){ //呼叫HttpServletRequest的getRequestDispatcher方法獲得RequestDispatcher介面的物件例項 //呼叫時指定轉發或包含的相對URL網址 //success.view 會依URL模式獲取對應的Servlet //forward()方法:將請求轉發給別的Servlet處理,相應的還有include()方法 request.getRequestDispatcher("success.view").forward(request, response); } else { //sendRedirect()方法要求瀏覽器重新請求另一個URL——重定向 //登入失敗,則重定向到首頁 response.sendRedirect("index.html"); } } private boolean loginCheck(String username, String password){ if( username!=null && password != null){ //這裡還沒有連線資料庫,只是簡單判斷一下 if( username.equals("admin") && password.equals("123456")){ return true; } } return false; } }
include() 方法可以將其他Servlet流程包括到當前Servlet流程中。
forward() 方法將請求處理轉發給別的Servlet。
在調派請求的過程中,如果有需要共享的物件,需要用到下面幾個方法。
setAttribute() 方法設定共享物件。
getAttribute() 方法取得屬性。
getAttributeName() 方法取得所有屬性名稱
removeAttribute() 方法指定名稱移除屬性。
3、在src下新建名為Success的Servlet,用來響應登陸成功的轉發請求。
Success.java程式碼如下:
package com.demo;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class Success
*/
@WebServlet("/success.view")
public class Success extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Success() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("</head>");
out.println("<body>");
out.println("<h2>"+ request.getParameter("username")+" 登陸成功!</h2>");
out.println("<script> document.write('update time:'+document.lastModified) </script>");
out.println("</body>");
out.println("</html>");
out.flush();
out.close();
}
}
4、專案執行效果
登陸介面:
登陸成功:
注:請求轉發是在容器中進行,所以可以取得WEB-INF中的資源,而瀏覽器不知道請求被轉發了,位址列不變。
用sendRedict()則要求瀏覽器重新請求另一個URL,位址列會變更。
大部分情況下,使用HttpServletResponse的getWriter()來去的PrintWriter物件,使用println()等方法輸出響應。
有時候,也可以直接對瀏覽器輸出位元組資料。需要使用getOutputStream()來取得ServletOutputStream例項。可以用來輸出圖片驗證碼。
下面就在登陸介面增加驗證碼功能。
5、新建名為SafeCode的Servlet用來生成驗證碼圖片。
SafeCode.java 程式碼如下:
package com.demo;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SafeCode extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1626673439350527994L;
public SafeCode() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//設定輸出型別和瀏覽器不儲存快取
response.setContentType("image/jpeg") ;
response.setHeader("Cache-Control", "no-cache") ;
//建立圖片物件
int width = 60,height = 20 ;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB) ;
Graphics g = image.getGraphics() ;
//生成隨機數
Random random = new Random() ;
String s = "" ;
for(int i=0;i<4;i++){
s += random.nextInt(10) ;
}
//把隨機數存到Session裡面,便於等下比較
HttpSession session = request.getSession() ;
session.setAttribute("code",s) ;
//隨機生成顏色 Color color = new Color(255,255,255) ; random.nextInt(256)的值範圍是0~255
Color color = new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256)) ;
//把隨機數寫到圖片上
String a = null ;
Font font = new Font(a,Font.ITALIC,18) ;
g.setColor(color) ;
g.setFont(font);
g.drawString(s,10,height-5) ;
g.dispose() ; //關閉畫筆
//把圖片送到客戶端
ServletOutputStream output = response.getOutputStream() ;
ImageIO.write(image,"JPEG",output) ;
output.flush(); //關閉輸出流
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request,response) ;
}
public void init() throws ServletException {
}
}
注:Servlet能輸出各種格式的資料,用Context-Type屬性進行設定。
6、在web.xml中新增如下配置
<servlet>
<servlet-name>safeCode</servlet-name>
<servlet-class>com.demo.SafeCode</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>safeCode</servlet-name>
<url-pattern>/safecode</url-pattern>
</servlet-mapping>
7、在index.html中新增顯示驗證碼的圖片標籤,和更新驗證碼的js指令碼。注意:給圖片設定src路徑時,前面沒有“/”,加了之後反而沒法獲取圖片了。
<script>
function reloadImage(){
document.getElementById('imgCode').src="safecode";
//alert("run");
}
</script>
......
<img id="imgCode" src="safecode"/>
<input type="button" value="看不清" id="btn" onclick="reloadImage()">
8、這樣再次執行專案時,就會有驗證碼了,效果如下:
至於驗證碼的驗證,前臺後臺都行,把輸入的驗證碼跟HttpSession存的驗證碼做比較即可。這裡就不再詳細說明了。
綜上:我們就實現了一個帶驗證碼的簡單登陸介面。對Servlet的請求、響應、轉發與輸出等知識點也有了一定的瞭解。
JavaWeb的核心構建在Servlet之上,對Servlet比較熟悉後,學習SSH等Web框架更能事半功倍。