學習目标
開發一個web項目,沒有人一個一個地給Sevlet的請求與響應設計編碼,而是通過過濾器解決全局亂碼
1.能夠說出過濾器的作用
2.能夠編寫過濾器
3.能夠說出過濾器生命周期相關方法
4.能夠根據過濾路徑判斷指定的過濾器是否起作用
5.能夠說出什麼是過濾器鍊
6.能夠編寫過濾器解決全局亂碼
filter-概述
-
(1)Filter是什麼?
Java Web開發有三大元件:Servlet Filter Listener
-
(2)Filter有什麼作用?
過濾器實際上就是對web資源進行攔截,做一些處理後再交給下一個過濾器或servlet處理
-
(3)有什麼特點
通常都是用來攔截request進行處理的
也可以對傳回的response進行攔截處理
filter-過濾器的建立***
- (1)Idea 建立 Filter
- (2)類比 Servlet
@WebServlet
extends HttpServlet
doGet/doPost方法
@WebFilter
implements Filter
doFilter方法
-
(3)過濾的正确了解
如果過濾位址是s1,那麼隻有位址是s1的請求才能被過濾,你通路a.jpg
,s2等等,過濾器都不過濾,不會執行doFilter方法。
\src\com.wzx.pack01_filter\Demo1Servlet.java
@WebServlet("/s1")
public class Demo1Servlet 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 {
System.out.println("doGet方法執行了啦");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
src\com.wzx.pack01_filter\Demo1Filter.java
//我要過濾請求資源路徑是s1,如果你通路的是 s1,我就過濾
@WebFilter("/s1")
public class Demo1Filter implements Filter {
public void destroy() {
}
/*
1:這個方法是你通路我要過濾的資源時,自動執行
2: FilterChain被稱為過濾器鍊
3: chain.doFilter(req, resp);放行
如果調用:請求放行
如果不調用,請求不放行
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("過濾器doFilter方法執行了");
chain.doFilter(req, resp);
System.out.println("過濾器響應了");
}
public void init(FilterConfig config) throws ServletException {
}
}
filter-過濾器的執行流程
- (1)一個同學進校園,先會遇到保安,如果該同學出校園,也會碰到保安
-
(2)過濾器的執行流程
1>tomcat引擎将http請求轉成request對象,http響應轉response對象
2>位址符合條件,則将request,resposne傳給doFilter方法
3>再傳給chain.doFilter(request,response)方法
4>再傳給doGet或者doPost方法,當servlet完成三件事之後
5>doFilter再執行剩餘代碼之後,reponse再傳回浏覽器
-
(3)設定編碼的代碼位置
doFilter之前設定請求編碼,之前設定響應編碼
filter-過濾器的執行順序***
-
(1)如果有兩個Filter都過濾請求,那麼執行順序是如何的?
先Filter1,再Filter2,最後Servlet,響應傳回時相反
-
(2)什麼設定決定Filter器的執行順序?
1:注解配置
當有多個過濾器時,是按照過濾器類的首字母的先後順序執行
2:web.xml配置
當有多個過濾器時,是按照web.xml中
配置的先後先後順序執行的<filter-mapping></filter-mapping>
src\com.wzx.pack02_filter\AFilter.java
@WebFilter("/s2")
public class AFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("第1個過濾器收到請求");
chain.doFilter(req, resp);
System.out.println("第1個過濾器收到響應");
}
public void init(FilterConfig config) throws ServletException {
}
}
src\com.wzx.pack02_filter\BFilter.java
@WebFilter("/s2")
public class BFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("第2個過濾器收到請求");
chain.doFilter(req, resp);
System.out.println("第2個過濾器收到響應");
}
public void init(FilterConfig config) throws ServletException {
}
}
src\com.wzx.pack02_filter\Demo2Servlet.java
@WebServlet("/s2")
public class Demo2Servlet 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("servlet執行了");
}
}
注釋@WebFilter,改成xml配置
<!--配置Servlet-->
<servlet>
<servlet-name>Demo3Servlet</servlet-name>
<servlet-class>com.wzx.pack03_filter.Demo3Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo3Servlet</servlet-name>
<url-pattern>/s3</url-pattern>
</servlet-mapping>
<!--配置TwoFilter-->
<filter>
<filter-name>TwoFilter</filter-name>
<filter-class>com.wzx.pack03_filter.TwoFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TwoFilter</filter-name>
<url-pattern>/s3</url-pattern>
</filter-mapping>
<!--配置OneFilter-->
<filter>
<filter-name>ZneFilter</filter-name>
<filter-class>com.wzx.pack03_filter.ZneFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ZneFilter</filter-name>
<url-pattern>/s3</url-pattern>
</filter-mapping>
filter-過濾器的生命周期(了解)
-
(1)過濾器有3個方法
init方法:伺服器啟動時就建立該filter對象
doFilter方法:每當一個請求的路徑是滿足過濾器的配置路徑,那麼就會執行一次過濾器的doFilter方法
destory方法:伺服器關閉時filter銷毀
src\com.wzx.pack04_life_cycle\Demo3Filter.java
@WebFilter("/*")
public class Demo3Filter implements Filter {
/*
當你關閉伺服器時執行,一般釋放資源
*/
public void destroy() {
System.out.println("destroy執行啦888888888888888888888888888888888888");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);
}
//當你把項目部署到伺服器上的時候,或者啟動伺服器,該方法就執行
public void init(FilterConfig config) throws ServletException {
System.out.println("init方法執行了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
}
filter-過濾器的url-pattern配置
- (1)Filter的url-pattern配置有3種,類比Servlet
1:完全路徑比對
@WebFilter("/s1")
@WebFilter("/abc/s1")
2:目錄比對
@WebFilter("/*")
@WebFilter("/abc/*")
3:擴充名比對
@WebFilter("*.do")
@WebFilter("*.jsp")
src\com.wzx.pack04_life_cycle\Demo4Filter.java
@WebFilter("/abc/xxx/*")
public class Demo4Filter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("doFilter方法執行了");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
filter-過濾器的攔截方式設定
- (1)過濾器可以區分不同的通路資源的方式,有不同的攔截方式。
-
(2)dispatcher:通路的方式
REQUEST:預設值,代表直接通路某個資源時執行filter
FORWARD:轉發時才執行filter
-
(3)如何設定
預設情況下,過濾器隻能攔截直接通路的資源,不能攔截轉發通路的資源
如果想讓過濾器不管是直接通路,還是轉發通路,都能攔截,則需要設定 @WebFilter屬性
@WebFilter(value = "/index.jsp",dispatcherTypes={DispatcherType.REQUEST,DispatcherType.FORWARD})
src\pack05_filter\DispaterServlet.java
@WebServlet("/dispater")
public class DispaterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
}
src\pack05_filter\AccessFilter.java
@WebFilter(value = "/index.jsp",dispatcherTypes={DispatcherType.REQUEST,DispatcherType.FORWARD})
public class AccessFilter implements Filter {
public void destroy() {
}
/*
1:FilterChain内部了解成一個集合,這個集合中維持一個過濾器鍊條
2:這個過濾器鍊中的過濾器必須按順序依次執行
3:過濾器鍊中必須全部通過,才能通過,隻要有一個不通過,則無法通路對應的資源
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("過濾器執行了");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
filter-過濾器鍊
-
(1)什麼是過濾器鍊
1:FilterChain内部了解成一個集合,這個集合中維持一個過濾器鍊條
-
(2)有什麼特點?
》1 這個過濾器鍊中的過濾器必須按順序依次執行
》2 過濾器鍊中必須全部通過,才能通過,隻要有一個不通過,則無法通路對應的資源
filter-全局亂碼解決
- (1)在擷取參數之前設定請求編碼
-
(2)在響應浏覽器之前設定響應編碼
web\index.jsp
<form action="${pageContext.request.contextPath}/get_form" method="post">
使用者名:<input type="text" name="username"/>
<input type="submit" value="送出"/>
</form>
src\com.wzx.pack05_filter\GetFormServlet.java
@WebServlet("/get_form")
public class GetFormServlet 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");
//1:擷取表單資料
String username = request.getParameter("username");
System.out.println("username:"+username);
//2:響應
// response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("收到資料啦!");
}
}
src\com.wzx.pack05_filter\CharSetFilter.java
- 此處是關鍵,隻要符合條件的請求會被過濾器攔截,多個Servlet的請求,被攔截下來之後先設定好編碼,再交給Servlet
@WebFilter("/*")
public class CharSetFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//1:解決請求參數亂碼
HttpServletRequest request = (HttpServletRequest)req;
String method = request.getMethod();
if(method.equals("POST")) {
req.setCharacterEncoding("UTF-8");
}
resp.setContentType("text/html;charset=UTF-8");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}