Filter簡介
Filter也稱之為過濾器,WEB開發人員通過Filter技術,對web服務器管理的所有web資源:例如Jsp,Servlet,靜態圖片文件或靜態html文件等進行攔截,從而實現一些特殊的功能。
Servlet API中提供了一個Filter接口,開發web應用時,如果編寫的類實現了這個接口,則把這個java類稱之為過濾器Filter。通過Filter技術,開發人員可以實現用戶在訪問某個目標資源之前,對訪問的請求和響應進行攔截,如下所示:
Filter開發入門
Filter開發步驟
Filter開發分為二個步驟:
- 編寫java類實現Filter接口,并實現其doFilter方法。
- 在web.xml文件中使用
<filter>
和<filter-mapping>
元素對編寫的filter類進行注冊,并設置它所能攔截的資源。
過濾器范例:
@WebFilter(filterName = "TestFilter",urlPatterns = "/index.do")
public class TestFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("FilterTest1執行之前!!!");
// 攔截下目標資源,然后放行(目標資源也會執行)
chain.doFilter(req, resp); // 放行
System.out.println("FilterTest1執行之后!!!");
}
public void init(FilterConfig config) throws ServletException {
}
}
代表網站首頁的index.do的代碼:
@WebServlet(name = "IndexServlet",urlPatterns = "/index.do")
public class IndexServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("index!!!");
}
}
在瀏覽器輸入地址[http://localhost:8080/index.do],控制臺打印如下:
Filter是如何實現攔截的?
Filter接口中有一個doFilter方法,當我們編寫好Filter,并配置對哪個web資源進行攔截后,WEB服務器每次在調用web資源的service方法之前,都會先調用一下filter的doFilter方法,因此,在該方法內編寫代碼可達到如下目的:
調用目標資源之前,讓一段代碼執行。
是否調用目標資源(即是否讓用戶訪問web資源)
web服務器在調用doFilter方法時,會傳遞一個filterChain對象進來,filterChain對象是filter接口中最重要的一個對象,它也提供了一個doFilter方法,開發人員可以根據需求決定是否調用此方法,調用該方法,則web服務器就會調用web資源的service方法,即web資源就會被訪問,否則web資源不會被訪問。
調用目標資源之后,讓一段代碼執行。
過濾器的生命周期
Filter對象何時被創建?
服務器一啟動的時候,就會針對這個web應用將所有的Filter對象(攔截器)創建出來,并且以后訪問的時候,都是使用同一個攔截器進行攔截。也即一個攔截器會被所有的請求所共享,每一次請求來了之后,都會導致doFilter()方法被調用一次,Filter對象只有一個,而doFilter()方法會被多次調用。
問:Filter對象在內存里面有幾個?
答:一個。服務器并不會針對請求創建新的Filter對象(攔截器)。
Filter對象何時被摧毀?
移除掉web服務器里面這個web應用(或停掉服務器),就會摧毀這個web應用對應的攔截器。
過濾器應用之統一全站編碼
filter可以在放行之前,對request和response進行預處理,從而實現一些全局性的設置。如:
@WebFilter(filterName = "TestFilter",urlPatterns = "/index.do")
public class TestFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
System.out.println("FilterTest1執行之前!!!");
// 攔截下目標資源,然后放行(目標資源也會執行)
chain.doFilter(req, resp); // 放行
System.out.println("FilterTest1執行之后!!!");
}
public void init(FilterConfig config) throws ServletException {
}
}
過濾器應用之二
Java web過濾器驗證登錄(避免未經登錄進入管理后臺主頁)
舉例:admin.jsp 這個網頁是需要管理員通過登錄后才可以訪問的,現在有一個用戶沒有登錄,直接訪問admin.jsp成功了。那么,這樣的網站是不是覺得不安全呢?
過濾器實現登錄驗證
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<a href="index.admin">進入后臺</a>
<a href="login.jsp">去登錄</a>
</body>
</html>
AdminServlet.java
@WebServlet(name = "AdminServlet",urlPatterns = "/index.admin")
public class AdminServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/admin.jsp").forward(request,response);
}
}
admin.jsp要放在WEB-INF目錄下保護起來
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
我是管理后臺
</body>
</html>
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="login.do">
用戶名:<input type="text" name="user">
密碼:<input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>
LoginServlet.java
@WebServlet(name = "LoginServlet",urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user = request.getParameter("user");
String pwd = request.getParameter("pwd");
if(user.equals("zhangsan") && pwd.equals("123"))
{
request.getSession().setAttribute("username",user);
request.getRequestDispatcher("/WEB-INF/admin.jsp").forward(request,response);
}
else
{
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
AuthorFilter.java
@WebFilter(filterName = "AuthorFilter",urlPatterns = "*.admin")
public class AuthorFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest httpServletRequest = (HttpServletRequest)req;
String url = httpServletRequest.getServletPath();
if(url.contains("login.do"))
{
chain.doFilter(req, resp);
return;
}
String username = (String)httpServletRequest.getSession().getAttribute("username");
if(username != null)
{
chain.doFilter(req, resp);
return;
}
else
{
httpServletRequest.getRequestDispatcher("/login.jsp").forward(httpServletRequest,resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
}