Java EE Web部分--06.Filter過濾器
一、概述
濾器(filter):本質是Java中預先定義好了不同的介面,可以過濾不同的內容,在專案中,我們對訪問某些資源的請求需要進條件的篩選、過濾時、就需要使用者定義一個實現類,然後實現介面中的過濾方法,在方法中書寫過濾的條件。filter是對客戶端訪問資源的過濾,符合條件放行,不符合條件不放行。
應用:1、過濾論動中的非法字元
2、登入許可權檢查
API:
void init(FilterConfig filterConfig); //過濾器物件建立的時候呼叫的方法 void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);//執行過濾的方法 void destory();//過濾器銷燬的時候呼叫的方法
開發步驟:
步驟一:新建一個java類、實現Filter介面
步驟二:重寫Filter介面的3個方法
步驟三:類上面配置註解
@WebFilter 配置Filter的註解
filterName;設定過濾器的名稱
urlPatterns 配置這個過濾器要攔截的資源的路徑
步驟四:在doFilter()方法中、書寫過濾的業務邏輯
chain.doFilter()方法放行
演示:
Servlet程式碼、LoginServlet.java
package com.mvcCase.Test; 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 java.io.IOException; @WebServlet(name = "LoginServlet", urlPatterns = "/login") public class LoginServlet extends HttpServlet { @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //重定向到首頁 response.sendRedirect("index.jsp"); } }
MyFilter.java
package com.mvcCase.Test; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @WebFilter(filterName = "MyFilter", urlPatterns = {"/login","/index.jsp"}) public class MyFilter implements Filter { public void init(FilterConfig config) throws ServletException { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //執行過濾的方法 //將ServletRequest物件強轉成HttpServletRequest物件 HttpServletRequest request = (HttpServletRequest) req; //獲取請求路徑 StringBuffer url = request.getRequestURL(); System.out.println("攔截了請求:"+url); //放行 chain.doFilter(request,resp); } public void destroy() { } }
二、過濾器的執行流程
過濾器的doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)方法中的request物件和response物件並不是過濾器自己建立的。而是,從被過濾的資源中傳遞過來的。過濾器的執行流程如下:
1. 客戶端(瀏覽器)的HttpRequest到達Servlet之前,被Filter的doFilter()方法攔截;
2. 根據需要,我們可以獲取或者修改HttpRequest物件中的資料;
3. 在這個請求響應給瀏覽器之前,Filter攔截了HttpResponse物件;
4. 根據需要,我們可以獲取或者修改HttpReponse物件中的資料;
5. 最後,由doFilter中的chain決定是否讓這個請求通過;
三、Filter生生命週期
1、Filter類的物件是在伺服器啟動的時候建立的;
2、Filter類物件建立完成後會呼叫init()方法;
3、只要一個請求符合Filter攔截路徑、瀏覽器請求一次、就會被doFilter方法攔截、
4、伺服器停止、呼叫destory方法
演示:
package com.mvcCase.Test;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(filterName = "LifeFilter",urlPatterns = "/login")
public class LifeFilter implements Filter {
/**
* 顯示建立這個類的無參構造方法
*/
public LifeFilter() {
System.out.println("LifecycleFilter物件被建立了.................");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("LifecycleFilter的init方法被執行了.......................");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("LifecycleFilter的doFilter方法執行了..............");
}
@Override
public void destroy() {
System.out.println("LifecycleFilter的destory方法執行了.......................");
}
}
doFilter()方法
doFilter()方法是攔截請求的方法,只要一個請求符合Filter攔截路徑,都會被doFilter()方法攔截。doFilter()方法有3個引數,這3個引數的作用分別如下:
引數 | 說明 |
---|---|
ServletRequest req | ServletRequest是HttpServletRequest類的父類,其中包含了被攔截的請求的資訊 |
ServletResponse resp | ServletResponse是HttpServletResponse類的父類,其中包含了被攔截的響應的資訊 |
FilterChain chain | FilterChain給Filter提供了放行的方法。chain.doFilter(); |
四、Filter對映路徑
1、精確匹配
精確匹配,要求訪問的資源路徑必須與Filter的urlPatterns中的配置一致。如下:
精確匹配 | 說明 |
---|---|
urlPatterns = "/index.jsp" | 攔截對index.jsp頁面的請求 |
urlPatterns = "/loginServlet" | 攔截對loginServlet的請求 |
urlPatterns = "/a.jpg" | 攔截對a.jsp的請求 |
Filter的urlPatterns引數中也可以一次性配置多個路徑,如下:
精確匹配 | 說明 |
---|---|
urlPatterns = {"/login.jsp","/descServlet"} | 既能攔截login.jsp又攔截descServlet的請求 |
2、模糊匹配
模糊匹配主要有以下3種寫法:
模糊匹配 | 使用示例 | 說明 |
---|---|---|
urlPatterns = "/*" | urlPatterns = "/*" | 對所有的請求都進行攔截 |
urlPatterns = "/xxx/*" | urlPatterns = "/user/*" | 對對映路徑中/user下的所有資源進行攔截 |
urlPatterns = "*.xxx" | urlPatterns = "*.jsp" | 對指定字尾的請求進行攔截 |
五、Filter應用案例
1、Filter統一解決post請求亂碼問題
8.0版本以上的tomcat為我們解決了get請求的亂碼問題。我們需要自己處理post請求的亂碼問題,因為我們的一個專案中可能有很多的請求。這時就可以用Filter來處理了。
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "AEncodeFilter",urlPatterns = "/demoServlet")
public class AEncodeFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//響應的亂碼的處理
HttpServletResponse response = (HttpServletResponse)resp;
response.setContentType("text/html;charset=utf-8");
//post請求的亂碼處理
HttpServletRequest request = (HttpServletRequest)req;
String method = request.getMethod();
if("POST".equals(method)){
req.setCharacterEncoding("utf-8");
}
//放行
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
2、非法字元過濾器
說明:
1.建立一個表單用於發表言論。
2.建立一個txt檔案,其中存入非法字元。
3.建立一個Filter,攔截請求。在init方法中將txt檔案中的非法字元讀取到記憶體中。
4.獲取請求中的引數,對請求的引數進行非法字元的校驗。
5.如果言論中不含有非法字元,就放行。
6.如果言論中含有非法字元,就攔截,並且提示使用者非法言論
form.jsp表單
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/wordsServlet" method="post">
使用者名稱:<input type="text" name="username"><br>
評論:<textarea name="desc"></textarea><br>
<input type="submit" value="提交">
</form>
</body>
</html>
WordsServlet.java
package com.filter.errorwords;
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 java.io.IOException;
@WebServlet("/wordsServlet")
public class wordsServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
//
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;character=utf-8");
String str = request.getParameter("username");
String str1 = request.getParameter("desc");
response.getWriter().print("context is true ="+str+str1);
}
}
WordsFilter.java 過濾器
package com.filter.errorwords;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
@WebFilter(filterName = "WordsFilter",urlPatterns = {"/wordsServlet"})
public class WordsFilter implements Filter {
StringBuffer sb = new StringBuffer();
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
request.setCharacterEncoding("utf-8");
// HttpServletResponse response = (HttpServletResponse) resp;
// response.setContentType("text/html;character=utf-8");
String desc = request.getParameter("desc");
// System.out.println("desc = " + desc);
if (sb.toString().contains(desc)){
System.out.println("內容敏感,重新提交");
resp.getWriter().print("內容敏感、重新提交");
return;
}
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
String realPath = config.getServletContext().getRealPath("disu.txt");
String line = null;
try {
InputStreamReader isr = new InputStreamReader(new FileInputStream(realPath),"utf-8");
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null){
sb.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("sb"+sb.toString());
}
}