Web階段:第十八章:Filter過濾器
Filter,什么是過濾器?
1.Filter過濾器是javaWeb的三大組件之一,
2.三大組件分別是:Servlet程序,F(xiàn)ilter過濾器,Listener監(jiān)聽器。
3.Filter是接口。
4.Filter的作用是:攔截請(qǐng)求,過濾響應(yīng)。
Filter的初體驗(yàn)
需求:在webContent目錄下有一個(gè)admin目錄。然后在這個(gè)目錄下有html頁面,jsp頁面,jpg圖片。
要求這個(gè)目錄下所有的資源都必須登錄之后才能訪問。
我們可以在jsp頁面中,通過判斷,Session域中是否包含用戶登錄的信息。
如果Session有用戶登錄的信息,說明已經(jīng)登錄,允許訪問。返回,則讓頁面跳轉(zhuǎn)到登錄頁面。
- <%
- Object user = session.getAttribute("user");
- // 用戶沒登錄
- if (user == null) {
- request.getRequestDispatcher("/login.jsp").forward(request, response);
- return;
- }
- %>
如何使用Filter來保持Admin下的資源,在登錄之后才允許訪問。
Filter的使用步驟:
1、編寫一個(gè)類去實(shí)現(xiàn)Filter接口
2、實(shí)現(xiàn)doFilter攔截的方法。
3、到web.xml中去配置攔截的資源地址
AdminFilter的代碼:
public class AdminFilter implements Filter {
/**
* doFilter方法在每次攔截到請(qǐng)求之后就會(huì)調(diào)用
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
//做攔截檢查的工作
Object user = httpRequest.getSession().getAttribute("user");
// 用戶沒登錄
if (user == null) {
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
} else {
// 已經(jīng)登錄
chain.doFilter(request, response);
}
}
}
web.xml中的配置:
- <!-- Filter標(biāo)簽 配置Filter過濾器 -->
- <filter>
- <filter-name>AdminFilter</filter-name>
- <filter-class>com.atguigu.filter.AdminFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>AdminFilter</filter-name>
- <!--
- /admin/* 表示 http://ip:port/工程名/admin/* 全部資源
- -->
- <url-pattern>/admin/*</url-pattern>
- </filter-mapping>
login.jsp頁面
- <body>
- <form action="${ pageContext.request.contextPath }/loginServlet" method="post">
- 用戶名:<input type="text" name="username" /><br/>
- 密碼:<input type="password" name="password"/><br/>
- <input type="submit" />
- </form>
- </body>
LoginServlet程序
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if ("wzg168".equals(username) && "123456".equals(password)) {
request.getSession().setAttribute("user", username);
System.out.println("登錄成功!");
} else {
System.out.println("登錄失敗!");
}
}
}
Filter的生命周期
1、Filter的構(gòu)造器方法
2、執(zhí)行init初始化操作
3、執(zhí)行doFilter過濾方法 每次攔截都會(huì)執(zhí)行
4、執(zhí)行destroy銷毀方法
FilterConfig 類
FilterConfig類封裝了Filter過濾器的配置信息。
作用:
1、獲取filter-name的值 過濾器的別名
2、獲取init-param初始化參數(shù)
3、獲取ServletContext對(duì)象
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
// System.out.println("2、init");
// 作用:
// 1、獲取filter-name的值 過濾器的別名
System.out.println("Filter的名稱:" + filterConfig.getFilterName());
// 2、獲取init-param初始化參數(shù)
System.out.println("Filter的初始化參數(shù)url值是:"
+ filterConfig.getInitParameter("url"));
// 3、獲取ServletContext對(duì)象
System.out.println( filterConfig.getServletContext() );
}
web.xml中的配置信息:
- <filter>
- <filter-name>AdminFilter</filter-name>
- <filter-class>com.atguigu.filter.AdminFilter</filter-class>
- <init-param>
- <param-name>url</param-name>
- <param-value>jdbc:mysql://localhost:3306/test</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>AdminFilter</filter-name>
- <url-pattern>/admin/*</url-pattern>
- </filter-mapping>
FilterChain 過濾器鏈
Filter 過濾器
Chain 鏈條
FilterChain 過濾器鏈
Filter1
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Filter1 前置代碼");
System.out.println("Filter1中獲取請(qǐng)求參數(shù):" + request.getParameter("username"));
System.out.println("Filter1 當(dāng)前線程 ==>> " + Thread.currentThread().getName() );
chain.doFilter(request, response);
System.out.println("Filter1 后置代碼");
}
Filter2
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Filter2 前置代碼");
System.out.println("Filter2中獲取請(qǐng)求參數(shù):" + request.getParameter("username"));
System.out.println("Filter2 當(dāng)前線程 ==>> " + Thread.currentThread().getName() );
chain.doFilter(request, response);
System.out.println("Filter2 后置代碼");
}
target.jsp頁面
- <body>
- <%
- System.out.println("target.jsp執(zhí)行……");
- System.out.println("target.jsp頁面中獲取請(qǐng)求參數(shù):" + request.getParameter("username"));
- System.out.println("target.jsp 當(dāng)前線程 ==>> " + Thread.currentThread().getName() );
- %>
- </body>
Filter的攔截路徑
--精確匹配
<url-pattern>/target.jsp</url-pattern>
以上的攔截地址,只有當(dāng)用戶請(qǐng)求地址為:http://ip:port/工程名/target.jsp的時(shí)候,F(xiàn)ilter就會(huì)執(zhí)行。
--目錄匹配
<url-pattern>/admin/*</url-pattern>
以上的攔截地址,只有當(dāng)用戶請(qǐng)求地址為:http://ip:port/工程名/admin/下所有資源,的時(shí)候就會(huì)執(zhí)行Filter
–后綴名匹配
<url-pattern>*.jsp</url-pattern>
以上的攔截地址。表示只要用戶訪問的地址是以.jsp結(jié)尾,就會(huì)攔截。
<url-pattern>*.html</url-pattern>
以上的攔截地址。表示只要用戶訪問的地址是以.html結(jié)尾,就會(huì)攔截。
<url-pattern>*.do</url-pattern>
以上的攔截地址。表示只要用戶訪問的地址是以.do結(jié)尾,就會(huì)攔截。
<url-pattern>*.action</url-pattern>
以上的攔截地址。表示只要用戶訪問的地址是以.action結(jié)尾,就會(huì)攔截。
對(duì)于Filter過濾器來說,只要請(qǐng)求的地址匹配上。就會(huì)執(zhí)行Filter過濾器。
它不關(guān)心請(qǐng)求的資源是否存在!