1. 程式人生 > >使用servlet來實現表單的登入機制並用filter來進行過濾操作

使用servlet來實現表單的登入機制並用filter來進行過濾操作

首先建立一個登入介面login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登入介面</title>
</head>
<body>
	<form action="login" method="post">
		<table  border="2">
			<tr>
				<td>使用者名稱:</td><td><input type="text" name="username"></td>
			</tr>
			<tr>
				<td>密 碼:</td><td><input type="password" name="password"></td>
			</tr>
			<tr>
				<td><input type="submit" value="提交"></td><td><input type="reset" value="取消"></td>
			</tr>
		</table>
	</form>
</body>
</html>
建立表單要提交的servlet物件loginServlet

在下面的servlet物件當中所實現的主要功能為:

1:對傳送過來的請求進行編碼操作

2:獲取表單當中的使用者名稱和密碼並提交到session物件當中

3:進行session物件的ID的輸出操作

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class loginServlet extends HttpServlet{
//建立一個servlet類物件用於對錶單物件所傳遞過來的資料資訊進行處理操作
private String username;
private String password;
private String charset=null;
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doGet(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding(charset);//獲取xml當中的引數變數將之作為編碼引數
		username=req.getParameter("username");
		password=req.getParameter("password");
//將從request物件當中所獲取到的使用者名稱和密碼都儲存到session會話物件當中去
		HttpSession session = req.getSession();
		session.setAttribute("username",username);
		session.setAttribute("password",password);
		System.out.println("Servlet:sessionID="+session.getId());
/*
 * 直接接收到的表單物件當中的資料資訊當中如果有漢字的化會產生亂碼的現象,所以要先對所接收到的request物件當中的內容進行編碼的
 * 設定操作
 */		
		System.out.println("charset="+charset);
		System.out.println("Servlet:username="+username);
		System.out.println("Servlet:password="+password);
/*當用戶名和密碼相匹配時,進行登入操作	*/
		if(username.equals("清之羽") && password.equals("password"))
/*
 * req.getRequestDispatcher("success.jsp").forward(req, resp);此處如果使用伺服器端的轉發的話在URL位址列當中所顯示的地址將不
 * 是success.jsp頁面資源的地址值,這樣將不會觸發successFilter過濾器物件,因為當前過濾器物件只會對來自客戶端的請求資料資訊進行
 * 過濾操作,對來自伺服器的請求物件不會進行過濾操作的,所以要採用客戶端的跳轉方式來對success介面進行訪問以此來對successFilter進
 * 行觸發。
 */
			resp.sendRedirect("success.jsp");
		else
			/*resp.sendError(404);直接給客戶端返回一個404響應*/
			resp.sendRedirect("fail.jsp");
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		this.charset=config.getInitParameter("charset");//獲取初始化的配置資訊
	}
	
}
建立一個過濾器物件用於實現對登入成功介面當中的資料進行過濾操作

過濾器物件主要實現的功能:

1:對訪問success.jsp頁面的資源資訊進行攔截操作

2:通過reqeust物件獲取來獲取session物件,並將session物件當中所存放的使用者名稱和密碼進行獲取並輸出

3:進行sessionID的輸出操作

package com.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.websocket.Session;

public class successFilter implements Filter{
//建立一個過濾器物件用於實現對success.jsp頁面當中的請求資訊進行過濾操作
	@Override
	public void destroy() {
		System.out.println("進行過濾器物件的銷燬操作");
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("執行過濾操作");
		HttpServletRequest request=(HttpServletRequest)req;//進行request物件的強制轉化
		HttpSession session=request.getSession();//通過Httprequest物件來進行session物件的獲取操作
		System.out.println("Filter:session="+session.getId());
		System.out.println("過濾器物件當中:username="+session.getAttribute("username"));
	/*	if(session.getAttribute("username")==null || !session.getAttribute("username").equals("青之羽"))
噹噹前的使用者名稱為空或使用者名稱錯誤時,將不再進行請求物件控制權的轉交操作。伺服器將直接將請求物件進行轉發到登入介面當中讓使用者重新
 * 進行登入操作
 * 	
		{
			System.out.println("對不起您所輸入的使用者名稱錯誤或為空,請重新進行輸入操作");
			req.getRequestDispatcher("login.jsp").forward(req, res);
		}*/
		System.out.println("過濾許可權轉交之前");
		chain.doFilter(req, res);//進行控制權限的轉交操作
		System.out.println("過濾許可權轉交之後");
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		System.out.println("進行過濾器物件的初始化操作:");
	}
	
}
web.xml配置資訊
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>通過過濾器來實現登入驗證-servlet</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
  	<servlet-name>login</servlet-name>
  	<servlet-class>com.servlet.loginServlet</servlet-class>
  	<init-param>
  		<param-name>charset</param-name>
  		<param-value>UTF-8</param-value>
  	</init-param>
  </servlet>
  <servlet-mapping>
  	<servlet-name>login</servlet-name>
  	<url-pattern>/login</url-pattern>
  </servlet-mapping>
  <filter>
  	<filter-name>successFilter</filter-name>
  	<filter-class>com.filter.successFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>successFilter</filter-name>
  	<url-pattern>/success.jsp</url-pattern>
  </filter-mapping>
</web-app>
問題:將使用者名稱在servlet物件當通過session來進行儲存,然後在filter物件當中進行session物件的獲取操作,對使用者名稱進行讀取操作。在程式執行之後將會發現在filter物件當中獲取到的使用者名稱為空。

執行結果如下:


如上圖發現Servlet物件當中可以對使用者名稱進行輸出操作,但是在filter物件當中所輸出的使用者名稱則為空值,通過分析可看出servlet物件當中的session物件和filter物件當中的session物件ID並不相同表明二者並不是同一個session物件。

cookie機制

在程式的執行之中,會話的跟蹤是很重要的事情。一個使用者的所有的請求都應該屬於同一個會話物件,而另一個使用者的所有請求則屬於另一個會話物件。在web應用程式當中使用的是HTTP來進行資料的傳輸的,但是Http協議是一種無狀態的協議,即一旦資料提交完畢之後客戶端與伺服器之間的連線就會關閉,當再次進行資料的傳遞時,需要重新進行連線操作。這意味著伺服器無法從連線上來對會話進行跟蹤操作來識別具體的使用者。

在上面的程式當中在servlet當中將使用者名稱新增到了session物件當中然後返回一個響應物件來讓客戶端來重新對success.jsp頁面當中的資源進行訪問操作,此時伺服器通過過濾器來將請求進行攔截之後,進行session物件的獲取操作,由於Http協議的無狀態性使得當前web容器物件無法識別當前使用者物件是否是之前所訪問過的session物件,所以使用request.getSession將會獲取一個新的session物件來建立一個新的會話,所以在filter物件當中將無法從session物件當中獲取使用者名稱,因為此時的session已經是一個新建立的session物件了。

為解決因為Http的無狀態性而導致session丟失的這一問題,採用cookie物件機制。伺服器物件無法通過網路連線來識別使用者身份。所以伺服器物件就為客戶們頒發一個通行證,客戶物件在對伺服器進行訪問操作時,必須要攜帶上通行證,這樣伺服器物件就可以根據通行證來對每一個session使用者物件進行識別操作。這就是cookie的工作原理。

cookie物件實際上是一小段的文字資訊,客戶端在將請求傳送給伺服器之後,如果伺服器需要記錄當前使用者,就會在響應物件response當中頒發一個cookie。在cookie當中存放了當前會話物件的sessionID值。當客戶端再次對伺服器物件進行訪問操作時,瀏覽器將會將cookie物件當中的資料資訊同請求一起傳送給伺服器物件。伺服器物件通過對cookie物件當中的sessionID值進行檢驗來辨認當前使用者是否已經訪問過伺服器物件。

session機制:session機制是伺服器端使用的一種記錄客戶端狀態的機制,客戶端在對伺服器進行訪問操作時,伺服器會將客戶端的資訊儲存到伺服器上。這就是session機制,當伺服器端再次接收到相同的使用者訪問時,將會直接根據sessionID值來在伺服器中找到當前使用者所對應的session物件,然後進行資料的呼叫。