过滤器

来源:互联网 发布:mac outlook 默认字体 编辑:程序博客网 时间:2024/05/10 12:28

Servlet一共分为三种:

1.简单Servlet:是作为一种程序所必须的开发结构保存下来的。

2.过滤Servlet;

3.监听Servlet;

 

JSP能完成的功能,Servlet都能完成;Servlet能完成的功能,JSP都不能完成,因为它至少没法做“过滤”和“监听”。

 

既然是一个Servlet,之前是采用了继承HttpServlet类的形式完成的,但是在过滤器中使用的不再是类,而是接口。

 

如果要想完成一个过滤器开发的话,则首先必须让一个类实现Filter接口。此接口是javax.servlet包中的,那么根据此包的特点就可以发现,此接口的主要功能是完成公共协议操作的(而不是HTTP协议的)。

 

过滤器的基本概念

Filter是在Servlet2.3之后增加的新功能,当需要限制用户访问某些资源或者在处理请求时提前处理某些资源的时候,就可以使用过滤器完成。

过滤器是以一种组件的形式绑定到WEB应用程序当中的,与其他的WEB应用程序组件不同的是,过滤器是采用了“链”的方式进行处理的。


 

实现过滤器

在Servlet中,如果要定义一个过滤器,则直接让一个类实现javax.servlet.Filter接口即可,此接口定义了三个操作方法:

1.public void init(FilterConfig filterConfig)throws ServletException

2.Public void doFilter(ServletRequest request,ServletResponse response.FilterChain chain)throws IOException,ServletException

3.Public void destory();

 

 

回顾:如果现在是一个普通的Servlet,则在使用的时候必须手工的调用,例如在form表单的action之间编写路径。

但是过滤这种操作本身可是属于自动完成的。

 

package com.skewrain.demo4;

import java.io.*;

import javax.servlet.*;

 

public class SimpleFilter implements Filter {

public void init(FilterConfig config)throws ServletException{

        //接收初始化的参数

        String initParam = config.getInitParameter("ref");

System.out.println("*** 过滤器初始化,初始化参数=" + initParam);

}

public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{

        System.out.println("*** 执行doFilter方法! ***");

}

public void destroy(){

        System.out.println("*** 过滤器销毁!***");

}

}

 

过滤器完成之后肯定也要开始进行配置的操作,但是在配置之前,先将服务器启动一下,观察没有过滤器时的操作。

 

此时,可以正确的出现文件的列表,下面开始增加配置。

<filter>

      <filter-name>simple</filter-name>

  <filter-class>com.skewrain.demo4.SimpleFilter</filter-class>

  <init-param>

      <param-name>ref</param-name>

  <param-value>HELLO,SKEWRAIN!</param-value>

  </init-param>

</filter>

<filter-mapping>

      <filter-name>simple</filter-name>

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

</filter-mapping>此处配置的url-pattern表示的是一个过滤器的过滤路径,现在既然是”/”则表示的是对一个目录中的全部的内容进行过滤。

 

“Ctr+C”:表示的关闭服务器。

 

一个过滤器的基本生命周期与Servlet是非常相似的,但是现在为什么界面上什么都不显示了呢?

 

FilterChain

FilterChain接口的主要作用是将用户的请求向下传递给其他的过滤器或者是Servlet:

Public void doFilter(ServletRequest request,ServletResponse response)

              throws IOException,ServletException

在FilterChain接口中依然定义了一个同样的doFilter()方法,这是因为在一个过滤器后面可能存在着另外一个过滤器,也可能是请求的最终目标(Servlet),这样就通过FilterChain形成了一个“过滤链”的操作,所谓的过滤链就类似于生活中玩的“击鼓传花”游戏。

 

FilterChain表示把请求向下传递,如果后面还有过滤器,则继续过滤,如果没有则直接到目的地。

【SimpleFilter.java】

package com.skewrain.demo4;

import java.io.*;

import javax.servlet.*;

 

public class SimpleFilter implements Filter {

public void init(FilterConfig config)throws ServletException{

        //接收初始化的参数

        String initParam = config.getInitParameter("ref");

System.out.println("*** 过滤器初始化,初始化参数=" + initParam);

}

public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{

        System.out.println("*** 执行doFilter方法之前! ***");

chain.doFilter(request,response);

System.out.println("*** 执行doFilter方法之后! ***");

}

public void destroy(){

        System.out.println("*** 过滤器销毁!***");

try{

Thread.sleep(1000);

}catch(Exception e){}

}

}

 

过滤器实际上是执行两次的。

与Servlet一样,过滤器本身也可以对多个路径进行过滤,例如:

<filter-mapping>

      <filter-name>simple</filter-name>

  <url-pattern>/jsp/admin/*</url-pattern>

</filter-mapping>

<filter-mapping>

      <filter-name>simple</filter-name>

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

</filter-mapping>

 

实际上过滤器的基本概念比较简单,而且也比较好理解。但是该怎么使用呢?从实际上来讲过滤器在开发中使用最频繁的两种操作:编码过滤,登录验证。

 

对于编码,肯定是所有页面都要使用的,而且只要是页面都要编写:requestSetCharacterEncoding()方法进行编码的设置。

【EncodingFilter.java】

package com.skewrain.demo4;

import java.io.*;

import javax.servlet.*;

 

public class EncodingFilter implements Filter {

private String charSet;

public void init(FilterConfig config)throws ServletException{

        //接收初始化的参数

        this.charSet = config.getInitParameter("charset");

System.out.println("*** 过滤器初始化,初始化参数!");

}

public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{

        System.out.println("*** 执行doFilter方法之前! ***");

request.setCharacterEncoding(this.charSet);

chain.doFilter(request,response);

System.out.println("*** 执行doFilter方法之后! ***");

}

public void destroy(){

        System.out.println("*** 过滤器销毁!***");

}

}

 

编码过滤完成之后下面就需要对此过滤器进行配置。

<filter>

      <filter-name>encoding</filter-name>

  <filter-class>com.skewrain.demo4.EncodingFilter</filter-class>

  <init-param>

      <param-name>charset</param-name>

  <param-value>GBK</param-value>

  </init-param>

</filter>

<filter-mapping>

      <filter-name>encoding</filter-name>

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

</filter-mapping>

 

至于登录验证也是一个很重要的内容,因为在很多情况都需要通过session完成登录验证的操作,但是如果每个页面都编写重复的session属性的判断,那么就变得相当的复杂,而且维护也不方便,所以对一些需要限制的地方采用登录的验证操作。

 

先完成登录验证的过滤器。【LoginFilter.java】

package com.skewrain.demo4;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class LoginFilter implements Filter {

private String charSet;

public void init(FilterConfig config)throws ServletException{

        //接收初始化的参数

        this.charSet = config.getInitParameter("charset");

System.out.println("*** 过滤器初始化,初始化参数!");

}

public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{

//session属于http协议的范畴

HttpServletRequest req = (HttpServletRequest)request;

HttpSession ses = req.getSession();

        if(ses.getAttribute("userid") != null){

//已经登录过了,则可以访问。

chain.doFilter(request,response);

}else{

request.getRequestDispatcher("login.jsp").forward(request,response);

}

        System.out.println("*** 执行doFilter方法之前! ***");

request.setCharacterEncoding(this.charSet);

chain.doFilter(request,response);

System.out.println("*** 执行doFilter方法之后! ***");

}

public void destroy(){

        System.out.println("*** 过滤器销毁!***");

try{

Thread.sleep(1000);

}catch(Exception e){}

}

}

 

<filter>

      <filter-name>login</filter-name>

  <filter-class>com.skewrain.demo4.LoginFilter</filter-class>

</filter>

<filter-mapping>

      <filter-name>login</filter-name>

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

</filter-mapping>

 

现在,我们在浏览器中输入:http://localhost:8888/skewrain/filterdemo,回车,

将会进入如下界面:


我们输入正确的用户名:skewrain和密码:skewrain,登录后的界面如下:


此时,我们打开一个新的浏览器,并且在浏览器地址栏中输入:http://localhost:8888/skewrain/welcome.jsp,回车,结果如下:


可见,Filter会自动帮我们完成登录验证的功能。

 

过滤器可以完成的功能都是自动完成的。当然,对于登录验证的过滤器,现在只需要先掌握基本的形式,实际上还是围绕session对象的使用展开的。对于在实际开发中,最麻烦的还在于路径的处理问题上。

 

小结:

1.过滤器属于自动执行的一种Servlet;

2.过滤器依然需要在web.xml文件中进行配置,配置的顺序为:先写过滤器,再写简单Servlet;

3.过滤器的常见功能是可以完成编码过滤以及登陆验证。

0 0
原创粉丝点击