[Day 13] Filter 练习

前言

今天来练习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

   
      MyFilter
      com.web.Filter.MyFilter
    
  
   
    MyFilter
    /*
  

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

	

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()

  
    LoginServlet
    /
  

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

至于为什么要改成/LoginServlet ?
同理因为在JSP里设定了这个action为LoginServlet
还是需要透过servlet-mapping去执行doPost()

改过的web.xml片段
web.xml


    LoginServlet
    /LoginServlet
  

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 11 ] Filter 简介

前言

因自己觉得filter应该和昨天的Listener一起讨论才是
所以今天就来整理一下filter的部分
这个印象中以前还蛮常看到的
在此做点重点整理
为本书的ch13

Filter

Filterj是一种java元件
类似servlet,主要用在处理Servlet之前
先进行一些特定的处理
或是当Servlet完成后再去做特殊的处理
再回传给client
主要也是设定在DD(Web.xml)里

  • request的功能 => 即在执行Servlet前先做的处理
    执行安全性检查
    重新格式化request的head或body
    稽查或记录request

  • response的功能 => 即在执行Servlet后所做的处理
    压缩回应串流
    附加或修改回应串流
    建立全然不同的response

  • life cycle
    Filter的生命周期就如同Servlet
    主要有三个特性:

    • Filter拥有自己的API,可以存取servletcontext,以及连结其他的filter
    • Container管理filter的life cycle
    • web可拥有多的filter,一个request可以有多个filter,并设定在DD里

    所以Filter的life cycle可分为:

    • inin()
      由Container去instance,由filterConfig储存
     private FilterConfig f;
      public void init(FilterConfig fConfig) throws ServletException {
      	this.f= fConfig;
      }   
    
    • doFilter()
      由下列三个参数组成

      • ServlerRequest
      • ServlerResponse
      • FilterChain
    • destroy()
      类似Servlet的destory
      在filter被销毁前进行相关的清理工作
  • DD的宣告方式
    主要有三个步骤

    • 1.宣告filter
    
    	FilterNameRequest
    	com.Filter.MyFilter
    
    
    • 2.将filter和对应的Servlet去做设定
    
    	FilterNameRequest
    	LoginServlet
    
    
    • 3.将URL和filter name去做mapping
    
    	FilterNameRequest
    	*.do
    
    
    • 4.在Servlet2.4之后,dispatcher也可以使用在filter上
      主要为REQUEST(预设)、FORWARD 、INCLUDE 、ERROR
      为执行这些Servlet之前会先执行对应的filter
    
    	FilterNameRequest
    	*.do
    	REQUEST
    
    

    Container排序filter的规则:
    只要跟DD所设定的URL所有相符的filter都会被呼叫,由DD设定的顺序去执行

Wrpper class

定义:
因为filter在处里response时,FilterChain.doFilter(resquest,response)
已经将回应传回client了,这样并无法去实作response的状况
因此wrpper class提供了一种可以实作的HttpServletResponse interface

FilterChain.doFilter(resquest,wrpperObj);
//将本来的response传入一个wrpperObj,进行相关处理
//由wrpper决定response要回应的东西

今天也先概略的整理一下重点
接下来结合filter和Listener
去做一些小练习