Servlet過濾器
由Servlet容器管理的對象,過濾器的功能是在原數據和目的數據之間起過濾作用的中間組件。
簡單實例實現:
過濾器功能:在訪問指定資源之前,打印一條日誌,訪問指定資源之後,打印一條日誌
package com.jike.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.annotation.WebFilter; /** * Servlet Filter implementation class FilterOne */ public class FilterOne implements Filter { /** * Default constructor. */ public FilterOne() { System.out.println("=======構造函數=========="); } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { //Servlet啓動時執行init方法, // 這點和Servlet是有區別的 // servlet在第一次被訪問是執行init方法,過濾器在容器啓動時執行init方法 System.out.println("=======初始化========="); String initParam = fConfig.getInitParameter("param"); System.out.println("param=" + initParam); } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("=======開始doFilter========="); chain.doFilter(request, response); System.out.println("=======結束doFilter========="); } /** * @see Filter#destroy() */ public void destroy() { System.out.println("======銷燬========="); } }
在web.xml中添加:
<filter> <filter-name>FilterOne</filter-name> <filter-class>com.jike.filter.FilterOne</filter-class> <init-param> <param-name>param</param-name> <param-value>thystar</param-value> </init-param> </filter> <filter-mapping> <filter-name>FilterOne</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
訪問:http://localhost:8080/JSPStudy/Hello
過濾器的應用範圍:
權限控制
日誌記錄
圖像轉換
數據壓縮
過濾器鏈:
過濾器鏈的執行順序根據部署描述符中的順序。
在上個程序的基礎上再添加一個FilterTwo,代碼相同。配置web.xml ,在控制欄查看運行結果。
使用過濾器進行權限校驗:
處理流程:
首先,建立jsp文件:
index爲首頁,在index.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>Insert title here</title> </head> <body> <a href="<%= request.getContextPath() %>/11/Hello.jsp" >Hello.jsp</a> <% //用於根據當前用戶不同的登陸狀態顯示連接 String flag = ""; Object obj = session.getAttribute("flag");// 獲取登陸狀態 if(obj != null){ flag = obj.toString(); } if(flag.equals("login_success")){// 如果登陸 %> <a href="<%= request.getContextPath()%>/LogoutServlet">退出</a> <%}else{ // 如果未登錄 %> <a href="<%= request.getContextPath()%>/11/login.jsp">登陸</a> <% } %> </body> </html>
在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"> <!-- 使用css美化當前頁面 --> <style type="text/css"> body{ color: #000; font-size: 14px; margin: 20px auto; } </style> <script type="text/javascript"> function check(form){ if(document.forms.loginForm.uname.value==""){ alert("請輸入用戶名"); document.forms.loginForm.uname.focus(); return false; } if(document.forms.loginForm.upwd.value==""){ alert("請輸入密碼"); document.forms.loginForm.upwd.focus(); return false; } } </script> <title>Insert title here</title> </head> <body> <form action="<%= request.getContextPath() %>/LoginServlet11" name="loginForm"> <%if(request.getAttribute("return_uri") != null){ %> <input type="hidden" name="return_uri" value="<%= request.getAttribute("return_uri") %>"> <%} %> <table border="1" cellspacing="0" cellpadding="5" bordercolor="silver" align="center"> <tr> <!-- 提示信息 --> <td colspan="2" align="center" bgcolor="#E8E8E8">用戶登陸</td> </tr> <tr> <td>用戶名:</td> <td><input type="text" name="uname" /></td> </tr> <tr> <td>密碼:</td> <td><input type="password" name="upwd" /></td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" name="submit" onclick="return check(this);"/> <input type="reset" name="reset"/> </td> </tr> </table> </form> </body> </html>
在Hello.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>Insert title here</title> </head> <body> <%! String str = "Hello world"; %> <% out.println(str); %> <br/> <a href="<%= request.getContextPath() %>/11/index.jsp">index.jsp</a> </body> </html>
此時,jsp頁面設計完成。
接下來,完成登陸和退出Servlet的編寫
新建Servlet:
在LoginServlet11中,
package com.jike.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet11 extends HttpServlet { public LoginServlet11() { super(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 獲取用戶提交的表單數據 String uname = request.getParameter("uname"); String passwd = request.getParameter("upwd"); // returnUri用戶訪問登陸頁之前訪問的頁面,通過這個值,登陸成功後的用戶和以重新返回登陸前的頁面 String returnUri = request.getParameter("return_uri"); // 輸出這三個值 System.out.println("username:" + uname); System.out.println("password:" + passwd); System.out.println("return_uri:" + returnUri); RequestDispatcher rd = null; // 非空校驗 if (uname == null || passwd == null) { request.setAttribute("msg", "用戶名或密碼爲空"); rd = request.getRequestDispatcher("/11/login.jsp"); rd.forward(request, response); } else {// 否則執行登陸邏輯 if (uname.equals("star") && passwd.equals("123")) {// 如果登陸成功 // 則在當前用戶的session對象中保存一個key爲flag,值爲login_success的字符串 // 用於表面當前用戶處於登陸狀態 request.getSession().setAttribute("flag", "login_success"); // 接下來根據returnUri的值進行跳轉 if (returnUri != null) { rd = request.getRequestDispatcher(returnUri); rd.forward(request, response); } else { rd = request.getRequestDispatcher("/11/index.jsp");// 跳轉回首頁 rd.forward(request, response); } } else {// 用戶登陸失敗 // 在當前用戶session對象中保存一個key爲flag,值爲login_error的字符串 // 用於表面當前用戶登陸失敗 request.getSession().setAttribute("flag", "login_error"); request.setAttribute("msg", "用戶名或密碼錯誤"); rd = request.getRequestDispatcher("/11/login.jsp"); rd.forward(request, response); } } } }
用於退出的LogoutServlet
package com.jike.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; // 用於 退出的邏輯 public class LogoutServlet extends HttpServlet { public LogoutServlet() { super(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 直接刪除session對象,跳轉回首頁 request.getSession().invalidate(); response.sendRedirect(request.getContextPath() + "/11/index.jsp"); } }
在web.xml中添加配置:
<servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>LoginServlet11</servlet-name> <servlet-class>com.jike.servlet.LoginServlet11</servlet-class> </servlet> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>LogoutServlet</servlet-name> <servlet-class>com.jike.servlet.LogoutServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet11</servlet-name> <url-pattern>/LoginServlet11</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LogoutServlet</servlet-name> <url-pattern>/LogoutServlet</url-pattern> </servlet-mapping>
myeclipse會自動生成這個配置
接下來,添加權限過濾器,只有登陸的客戶才能訪問Hello.jsp
新建過濾器:
package com.jike.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class PermissionFilter implements Filter { public PermissionFilter() { // TODO Auto-generated constructor stub } public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 強制類型轉換 HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; // 獲取請求中的ServletPath String servletPath = req.getServletPath(); // 獲取session對象 HttpSession session = req.getSession(); // 獲取session對象的flag的值,強制轉換爲String類型 String flag = (String) session.getAttribute("flag"); // 如果用戶訪問的是首頁,或login.jsp或者執行登陸操作 if (servletPath != null && (servletPath.equals("/11/login.jsp") || (servletPath.equals("/11/index.jsp")) || (servletPath .equals("/LoginServlet11")))) { chain.doFilter(request, response);// 將請求轉發給下一個組件處理 } else {// 對於請求的其他的url都會進行權限校驗 // 如果用戶處於登陸狀態,可以直接訪問 if (flag != null && flag.equals("login_success")) { chain.doFilter(request, response); } else if (flag != null && flag.equals("login_error")) {// 如果登陸失敗 req.setAttribute("msg", "登陸失敗, 請重新登陸"); // 把用戶訪問的url保存到request對象中 req.setAttribute("return_uri", servletPath); RequestDispatcher rd = req .getRequestDispatcher("/11/login.jsp"); rd.forward(req, resp); } else {// 如果沒有登陸 req.setAttribute("msg", "尚未登錄"); req.setAttribute("return_uri", servletPath);// 保存url RequestDispatcher rd = req .getRequestDispatcher("/11/login.jsp"); rd.forward(req, resp); } } } public void destroy() { // TODO Auto-generated method stub } }
在web.xml中添加配置:
<filter> <filter-name>PermissionFilter</filter-name> <filter-class>com.jike.filter.PermissionFilter</filter-class> </filter> <filter-mapping> <filter-name>PermissionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
訪問 :http://localhost:8080/JSPStudy/index.jsp
測試
極客學院:http://www.jikexueyuan.com/course/644.html