Servlet之Filter过滤器1

原创 2013年12月01日 22:48:45

Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、自动登录、压缩响应信息等一些高级功能。

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:

自定义filter

public class FilterDemo1 implements Filter{

       //销毁方法

       publicvoid destroy() {

              //TODO Auto-generated method stub

             

       }

       //执行方法

       publicvoid doFilter(ServletRequest request, ServletResponse response,

                     FilterChainchain) throws IOException, ServletException {

              //TODO Auto-generated method stub

              System.out.println("doFilter");           

       }

       //初始方法

       publicvoid init(FilterConfig arg0) throws ServletException {

              //TODO Auto-generated method stub

             

       }

 

}

ShowServlet

protectedvoid doGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {

       // TODO Auto-generatedmethod stub    

       //设置编码

       response.setContentType("text/html;charset=UTF-8");

       response.getWriter().write("欢迎学习servlet下篇!");

    }

在web.xml中配置filter

<!-- filter放在servlet的上面 -->

    <filter>

       <filter-name>FilterDemo1</filter-name>

       <filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>

    </filter>

    <filter-mapping>

       <filter-name>FilterDemo1</filter-name>

       <!-- /*表示拦截所有,/表示项目名称,*代表所有 -->

       <!-- 不是用户访问的,指的是filter拦截所有资源 -->

       <url-pattern>/*</url-pattern>

    </filter-mapping>

    <servlet>

       <servlet-name>ShowServlet</servlet-name>

       <servlet-class>cn.itcast.web.servlet.ShowServlet</servlet-class>

    </servlet>

    <servlet-mapping>

       <servlet-name>ShowServlet</servlet-name>

       <url-pattern>/ShowServlet</url-pattern>

    </servlet-mapping>

访问网站会先转到过滤器

过滤器工作原理:

放行请求:

    //放行请求

       chain.doFilter(request,response);

chain.doFilter(request,response)具有二义性:

       >>如果有下一个Filter时,将请求转发给下一个Filter

        >>如果无下一个Filter时,将请求转发给Web资源(serlvet/jsp/html)

filter执行顺序:

//执行方法

    publicvoid doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       // TODO Auto-generatedmethod stub

       System.out.println("A");

       //放行请求,类似于函数调用

       chain.doFilter(request, response);

       System.out.println("B");

    }

Filter2

    publicvoid doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       // TODO Auto-generatedmethod stub

       System.out.println("C");

       chain.doFilter(request, response);

       System.out.println("D");

    }

在web.xml中配置(filter配置应在sevlet配置的上面,配置在前面的filter会先执行)

    <filter-mapping>

       <filter-name>FilterDemo1</filter-name>

       <!-- /*表示拦截所有,/表示项目名称,*代表所有 -->

       <!-- 不是用户访问的,指的是filter拦截所有资源 -->

       <url-pattern>/*</url-pattern>

    </filter-mapping>

    <filter>

       <filter-name>FilterDemo2</filter-name>

       <filter-class>cn.itcast.web.filter.FilterDemo2</filter-class>

    </filter>

    <filter-mapping>

       <filter-name>FilterDemo2</filter-name>

       <!-- /*表示拦截所有,/表示项目名称,*代表所有 -->

       <!-- 不是用户访问的,指的是filter拦截所有资源 -->

       <url-pattern>/*</url-pattern>

    </filter-mapping>


filter提取公共代码:

publicvoid doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       // TODO Auto-generatedmethod stub

       chain.doFilter(request, response);

      

    }

filter2

publicvoid doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       // TODO Auto-generatedmethod stub

       //设置编码,公共代码

       response.setContentType("text/html;charset=UTF-8");

    }

ShowServlet,这里就不用再设置编码了,因为在过滤器中已经设置

protectedvoid doGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {

       // TODO Auto-generatedmethod stub    

       response.getWriter().write("欢迎学习servlet下篇!");

    }

showServlet不用再过滤中文乱码问题

2 过滤器简介(过滤器的配置要写在servlet的前面)

  a)FilterSUN公司提供的一个资源过滤器接口,不同的Web容器有着不同的实现

  b)Filter位于Web服务器和Web资源(Servlet/Jsp/Html)之间

  c)过滤请求和响应二者

  d)Filter可以进行简单判段,是否将请求放行给Web资源

  e)Filter的开发过程:

       >> implements javax.servlet.Filter接口

        >>web.xml文件配置Filter过滤器,告之Web服务器有过滤器的存在

              web.xml中的配置信息如下:

       <filter>

        <filter-name>FilterDemo1</filter-name>(过滤器,可以随意,但要和filter-mapping中的name一致)

        <filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>(过滤器全路径)

        </filter>

       <filter-mapping>

        <filter-name>FilterDemo1</filter-name>(过滤器名,同上)

        <url-pattern>/*</url-pattern>(过滤器能够过滤的资源路径,不是用户在URL中访问的路径)

       </filter-mapping>

 

3 过滤器链

  a)一个Web应用可以有0个或多个Filter,多个Filter的组合就是过滤器链

  b)多个Filter的执行先后顺序,与web.xml文件中配置的顺序有关

 c)chain.doFilter(request,response)具有二义性:

       >>如果有下一个Filter时,将请求转发给下一个Filter

        >>如果无下一个Filter时,将请求转发给Web资源(serlvet/jsp/html)

  d)可以将web资源中的一些公共代码,提取出来,放入Filter

 

4 过滤器生命周期

  空参构造() 1

  init() 1

  doFilter(请求,响应,过滤器链) N次,与请求次数有关

  destory() 1

  Filter是一个单例

//单例

publicclass FilterDemo3 implements Filter{

    private FilterConfig  filterConfig;

    //构造函数:执行一次

    public FilterDemo3() {

       System.out.println("构造:"+this.hashCode());

    }

    //销毁方法:执行一次

    publicvoid destroy() {

       // TODO Auto-generatedmethod stub

       System.out.println("destroy:"+this.hashCode());

    }

    //N次,与请求有关,web容器调用

    publicvoid doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       // TODO Auto-generatedmethod stub

       Enumeration<String>enums=filterConfig.getInitParameterNames();

       while(enums.hasMoreElements()){

           String key=enums.nextElement();       

           String value=filterConfig.getInitParameter(key);

           System.out.println(key+":"+value);

       }

       System.out.println("doFilter:"+this.hashCode());

       String encoding=filterConfig.getInitParameter("encoding");

       System.out.println(encoding);

       response.setContentType("text/html;charset="+encoding);

       chain.doFilter(request, response);

    }

    //初始化filter,执行一次

    publicvoid init(FilterConfig filterConfig) throws ServletException {

       // TODO Auto-generatedmethod stub

       System.out.println("init:"+this.hashCode());

       this.filterConfig=filterConfig;

      

    }

web.xml中配置


<filter>

       <filter-name>FilterDemo3</filter-name>

       <filter-class>cn.itcast.web.filter.FilterDemo3</filter-class>

       <init-param>

           <param-name>encoding</param-name>

           <param-value>UTF-8</param-value>

       </init-param>

       <init-param>

           <param-name>email</param-name>

           <param-value>jack@163.com</param-value>

       </init-param>

    </filter>

    <filter-mapping>

       <filter-name>FilterDemo3</filter-name>

       <!-- /*表示拦截所有/表示项目名称,*代表所有 -->

       <!-- 不是用户访问的,指的是filter拦截所有资源 -->

       <url-pattern>/*</url-pattern>

    </filter-mapping>

当访问一个web资源时,没有得到对应的结果,有可能是Filter没有放行资源

  b)静态资源和动态资源进行不同的缓存处理,代码如下:

              if(uri!=null&& uri.endsWith("jsp")){

                     //NO3如果是动态资源,设置三个响应头通知浏览器不缓存

                     response.setHeader("expires","-1");

                     response.setHeader("cache-control","no-cache");

                     response.setHeader("pragma","no-cache");

              }else if(uri!=null &&uri.endsWith("html")){

                     //NO4如果是静态资源,缓存一定的时间

                     StringstrHtml = filterConfig.getInitParameter("html");

                     longtime = System.currentTimeMillis()+Integer.parseInt(strHtml)*1000;

                     //time为毫秒值

                     response.setDateHeader("expires",time);

                     response.setHeader("cache-control",time/1000+"");

                     response.setHeader("pragma",time/1000+"");

              }

   c)总结:写Filter一定要知道该Filter过滤哪个或哪些资源,不是所有的Filter都过滤/*的资源。

动态资源缓存,静态资源缓存

静止缓存动态资源如jsp

//禁止浏览器缓存动态资源,例如JSP资源

public class FilterDemo5 implements Filter {

       privateFilterConfig filterConfig;

       public voidinit(FilterConfig filterConfig) throws ServletException {

              this.filterConfig= filterConfig;

       }

       public voiddoFilter(ServletRequest req, ServletResponse res,FilterChain chain) throwsIOException, ServletException {

 

              //NO将父子接口强转

              HttpServletRequestrequest = (HttpServletRequest) req;

              HttpServletResponseresponse = (HttpServletResponse) res;

             

              //NO1取得客户端访问的资源的URI,形式/day19/login.jsp

              Stringuri = request.getRequestURI();

             

              //NO2判段是否以jsp结尾,即动态资源

              if(uri!=null&& uri.endsWith("jsp")){

                     //NO3如果是动态资源,设置三个响应头通知浏览器不缓存

                     response.setHeader("expires","-1");

                     response.setHeader("cache-control","no-cache");

                     response.setHeader("pragma","no-cache");

              }elseif(uri!=null && uri.endsWith("html")){

                     //NO4如果是静态资源,缓存一定的时间,有助于减轻服务器压力

                     StringstrHtml = filterConfig.getInitParameter("html");

                     longtime = System.currentTimeMillis()+Integer.parseInt(strHtml)*1000;

                     //time为毫秒值

                     response.setDateHeader("expires",time);

                     response.setHeader("cache-control",time/1000+"");

                     response.setHeader("pragma",time/1000+"");

              }

             

              //NO5放行资源

              chain.doFilter(request,response);

       }

       public voiddestroy() {

       }

}

web.xml中配置

<filter>

       <filter-name>FilterDemo5</filter-name>

       <filter-class>cn.itcast.web.filter.FilterDemo5</filter-class>

       <init-param>

           <param-name>html</param-name>

           <param-value>86400</param-value>

       </init-param>

      

    </filter>

    <filter-mapping>

       <filter-name>FilterDemo5</filter-name>

       <!-- /*表示拦截所有,/表示项目名称,*代表所有 -->

       <!-- 不是用户访问的,指的是filter拦截所有资源 -->

       <url-pattern>/*</url-pattern>

    </filter-mapping>

 loign.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
     <form action="${pageContext.request.contextPath}/LoginServlet" method="post">
         <table border="1" align="center">
             <caption>用户登录</caption>
             <tr>
                 <th>用户名</th>
                 <td><input type="text" name="username"/></td>
             </tr>
             <tr>
                 <th>密码</th>
                 <td><input type="password" name="password"/></td>
             </tr>
             <tr>
                 <td colspan="2" align="center">
                     <input type="submit" value="提交"/>
                 </td>
             </tr>
         </table>
     </form>
  </body>
</html>

login.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
     <form action="/day19/LoginServlet" method="post">
         <table border="1" align="center">
             <caption><br>用户自动登录</caption>
             <tr>
                 <th>用户名</th>
                 <td><input type="text" name="username"/></td>
             </tr>
             <tr>
                 <th>密码</th>
                 <td><input type="password" name="password"/></td>
             </tr>
             <tr>
                 <th>时间</th>
                 <td>
                     <input checked name="time" type="radio" value="60"/>1分钟
                     <input name="time" type="radio" value="180"/>3分钟
                     <input name="time" type="radio" value="300"/>5分钟
                 </td>
             </tr>
             <tr>
                 <td colspan="2" align="center">
                     <input type="submit" value="提交"/>
                 </td>
             </tr>
         </table>
     </form>
  </body>
</html>


查看缓存:



Servlet_Filter(过滤器)及FilterChain的使用详解

一、Filter的介绍及使用 什么是过滤器? 与Servlet相似,过滤器是一些web应用程序组件,可以绑定到一个web应用程序中。但是与其他web应用程序组件不同的是,过滤器是"链"在容器的处理...

使用过滤器Filter解决JSP+Servlet页面编码乱码

最近又拿起jsp+servlet来做项目,遇到了乱码的问题。解决方案很多,这次决定用过滤器来解决传值过程中的乱码问题。当然前提是tomcat没修改过connector配置项中的uriencoding,...

Java学习笔记·Servlet&Filter过滤器配置实例(web.xml配置方法)

准备一个Servlet(Lesson2/lesson6_2.Sample7.java)package lesson6_2;import java.io.*; import java.util.*; i...

Servlet3.0-使用注解定义过滤器(Filter)

Servlet3.0提供@WebFilter将一个实现了javax.servlet.Filter接口的类定义为过滤器组件。 1 2 3 4 5 ...

Servlet过滤器(Filter)

servlet过滤器的概念 •Servlet过滤器是在Java Servlet规范2.3中定义的,它能够对Servlet容器的请求和响应对象进行检查和修改。 •Servlet过滤器本身并不...
  • kqygww
  • kqygww
  • 2013年01月12日 10:24
  • 754

Servlet初始化和filter过滤器映射的问题

1.web.xml部署有编译servlet吗?会的,在部署的时候会根据servlet-mapping映射里的找到进行对servlet类编译 2.编译有实例化对象吗??没有,因为以前我们有在实例化对象...
  • l_s_d
  • l_s_d
  • 2017年06月01日 16:03
  • 148

Servlet中的过滤器(拦截器)Filter与监听器Listener的作用和区别

Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要...

Servlet Filter 技术防止XSS攻击的过滤器例子

java servlet 的filter技术防止xss攻击的例子
  • nmgrd
  • nmgrd
  • 2017年03月01日 18:52
  • 329

Servlet中的过滤器Filter详解(http://blog.csdn.net/sd0902/article/details/8395641)

web.xml中元素执行的顺序listener->filter->struts拦截器->servlet。 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ,它不...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Servlet之Filter过滤器1
举报原因:
原因补充:

(最多只允许输入30个字)