iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 13
0

前言

今天來練習filter
先前將網頁URL只要讀取有斜線後的數字就會導到login.jsp
但此部分是設定在servlet裡面
今天要使用filter去做設定
在網頁一進來時,優先去執行filter
去將頁面導到login


1. 先增一支filter
和Listener一樣
點選專案右鍵,新增一支filter
http://ithelp.ithome.com.tw/upload/images/20161213/201034259wkDBG63GC.png

和新增Servlet很像
設定package的名稱以及name
http://ithelp.ithome.com.tw/upload/images/20161213/20103425CMHbVueCQs.png

這裡一樣可以使用@WebFilter替filter設定
但我自己是覺得設定在DD比較方便就是
http://ithelp.ithome.com.tw/upload/images/20161213/201034257AaVQvkXRF.png

此為default的Filter
而等等需要改寫的就是doFilter這個method
http://ithelp.ithome.com.tw/upload/images/20161213/20103425yJNKu06JzM.png

2.新增DD(web.xml)
在web.xml裡設定filter的名稱,對應的URL,以及要呼叫的filter class
其中要注意,filter也是屬於共用的
所以要寫在web-app裡面

web.xml

   <filter>
      <filter-name>MyFilter</filter-name>
      <filter-class>com.web.Filter.MyFilter</filter-class>
    </filter>
  
   <filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

3.改寫MyFilter

3.1新增部分
在MyFilter裡的doFilter加入我要的判斷
透過getRequestURI()取得cilent的URL
在判斷字串,如果不是我們先前在DD設定的LoginServlet
就直接丟到Login.jsp請cilent執行登入

至於為什麼是LoginServlet?
因為在JSP已經設定好action="LoginServlet"

如果符合我們設定的條件
就請filter執行本來應該要執行的servlet

chain.doFilter(request, response);

Login.jsp

	<form action="LoginServlet" method="post">

MyFilter.java

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest req = (HttpServletRequest) request;
		String uri = req.getRequestURI();
		
		if( !(uri.endsWith("jsp") || uri.endsWith("LoginServlet"))){
			request.getRequestDispatcher("Longin.jsp").forward(request, response);
		}else{
			// pass the request along the filter chain
			chain.doFilter(request, response);
		};
	}

3.2修改舊有的部分
因為已經設定好Filter
所以本來在Servlet有用到doGet()去執行登入
這段就可以拿掉

LoginServlet.java

//整個都可以拿掉,因為現在直接透過filter去呼叫Login.jsp
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

		request.getRequestDispatcher("Longin.jsp").forward(request, response);
	} 

再來是web.xml
因為當初要讓只要讀到斜線後的都會去執行LoginServlet
所以設定了servlet-mapping
但現在交給filter,所以要把本來的斜線改成我設定的/LoginServlet

old :
URL => 透過DD =>呼叫LoginServlet的doGet() => Login.jsp 用post呼叫LoginServlet的doPost()

  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

new :
URL => 透過Filter => Login.jsp 用post呼叫LoginServlet的doPost()

至於為什麼要改成/LoginServlet ?
同理因為在JSP裡設定了這個action為LoginServlet
還是需要透過servlet-mapping去執行doPost()

改過的web.xml片段
web.xml

<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>

4.demo
因為filter的設定
所以只要有斜線就會自動先啟動Filter
http://ithelp.ithome.com.tw/upload/images/20161213/20103425ci74ByhYVm.png

http://ithelp.ithome.com.tw/upload/images/20161213/201034251zXLnaRfCa.png

另外在這裡筆記一下
如果Filter的filter-mapping
url-pattern只有斜線的話後面再打其他字串會無法對應
需要加上星號
但根據之前的練習,在servlet-mapping裡面宣告url-pattern
只要斜線就可以了


小結

這裡練習了很簡單的例子
另外Filter還有其他很多的應用(編碼處裡,錯誤處理...)
之後有時間的話在整理進來
接下來應該會先進行JSP的部分


上一篇
[Day 12] Listener 練習 -1
下一篇
[Day 14] Session 機制 part1
系列文
30 days JSP & Servlet學習紀錄 30

尚未有邦友留言

立即登入留言