欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java servlet过滤器使用示例

程序员文章站 2023-01-03 22:52:25
servlet过滤器简介      servlet过滤器实际上就是一个标准的java类,这个类通过实现filter接口获得...

servlet过滤器简介     
servlet过滤器实际上就是一个标准的java类,这个类通过实现filter接口获得过滤器的功能。它在jsp容器启动的时候通过web.xml配置文件被系统加载。
servlet过滤器在接收到用户请求的时候被调用,当服务器接收到用户的请求的时候,依次调用配置好的过滤器,完成后将执行请求所要求的servlet,而servlet执行后的响应,则先通过配置好的过滤器后再发送给用户。

过滤器的用途:
1、用户认证和授权管理。
2、统计web应用的访问量和访问命中率,生成访问报告。
3、实现web应用的日志处理功能。
4、实现数据压缩功能。
5、对传输的数据进行加密。
6、实现xml文件的xslt的转换。
一个servlet过滤器其实是一个java类,它的实现需要分为两个部分,java类自身以及在web.xml文件中的xml描述。对于filter接口,该接口由一对描述的生命周期的方法init(),destroy(),init方法在服务器初始化过滤器的时候会调用,而destory方法在服务器关闭的时候会调用,还有一个行为方法dofilter方法会在执行过滤操作的时候调用.

servlet过滤器的配置
servet过滤器需要通过web应用程序部署描述符文件web.xml来部署到应用中。配置如下

复制代码 代码如下:

< filter>
    <filter-name>filtername</filter-name>

    <filter-class>com.filter.filter/class</filter-class>

       <init-param>
   <param-name>file</param-name>
   <param-value>filename</param-value>
       </init-param>
    </filter>

    <filter-mapping>
 <filter-name>filtername</filter-name>
<url-pattern>/*</url-pattern>
   </filter-mapping>

下面是示例:

使用过滤器解决中文编码问题:
由于java的默认编码方式是iso-8859-1,而通常编写中文应用程序的时候都是使用gb2312或gbk编码方式。在这种情况下,应在页面的首部通过<%@ page contenttype="text/html;charset=gbk"%>命令来指定页面的编码方式。这样中文页面就可以正常地显示了。但是如果页面中村中表单。如一个input输入框,如果访问者在其中输入中文,又提交到某个servlet进行处理的话,java会首先按iso-5589-1的默认方式对这段文本进行编码,然后交给servet处理,处理后的文本将还是以iso-5589-1编码方式村中,如果这个时候这个文本返回一个按gbk编码来显示的页面,由于编码格式的不同,很显然得不到正确的显示结果。
对于编码方式的解决方法有很多种,这里主要介绍用过滤器来解决中文编码问题:

复制代码 代码如下:

public class characterencodingfilter implements filter {
private filterconfig config;
private string encoding = "iso8859_1";
public void destroy() {

  config = null;

}

public void dofilter(servletrequest request, servletresponse response ,

   filterchain chain) throws ioexception, servletexception {

  request.setcharacterencoding(encoding);

  chain.dofilter(request, response);

}

public void init(filterconfig config) throws servletexception {

  this.config  = config;

  string s = config.getinitparameter("encoding");

  if(s!=null){

   encoding = s;

  }

}

}

 然后在是xml的配置:

 

复制代码 代码如下:

 <filter>

    <filter-name>encodingfilter</filter-name>

    <filter-class>com.filter.characterencodingfilter</filter-class>

    <init-param>

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

      <param-value>utf-8</param-value>

    </init-param>

  </filter>

  <filter-mapping>

    <filter-name>encodingfilter</filter-name>

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

  </filter-mapping>
 

 最后是encoding.jsp的编写?

 

复制代码 代码如下:

 用户名:<c:out value="${param.username}" default="none"></c:out><br>

      密码:<c:out value="${param.userpassword}" default="none"></c:out><br>

      <form action="myjsp.jsp" method="post">

        用户名:<input type="test" name="username"> <br>

        密码:<input type="password" name="userpassword"><br>

        <input type="submit" value="提交">

      </form>
 

启动tomcat,访问encoding.jsp,输入“张山”就可以看到,经过过滤器后,页面可以正常显示服务器传出的信息。。。

使用过滤器记录用户访问日志
对于有些项目,它对于用户的每次访问都要有详细的记录。那么这是使用记录日志是一个非常好的解决方法,使用过滤器就可以很轻松地对每次用户的访问进行记录。但是由于同一个访问者在同一个时段访问站点不同的页面时,不能重复记录日志,否则日志将会在很短的时间内塞满服务器的硬盘空间。于是这里可以利用session对象来判断用户的每次会话,在一次会话中,过滤器只会记录一次。
下面编写logfilter类,这个过滤器主要负责记录用户的访问记录:

复制代码 代码如下:

package com.filter;

import java.io.file;
import java.io.ioexception;
import java.io.randomaccessfile;

import java.text.simpledateformat;
import java.util.date;
import javax.servlet.filter;
import javax.servlet.filterchain;
import javax.servlet.filterconfig;
import javax.servlet.servletexception;
import javax.servlet.servletrequest;
import javax.servlet.servletresponse;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpsession;

import com.sun.org.apache.bcel.internal.generic.new;

public class loginfilter implements filter{

  private filterconfig config =null;
  private string filename = null;
  private string filtername = null;
  public void destroy() {
    this.config = null;
    this.filename = null;
    this.filtername = null;
  }

  public void dofilter(servletrequest request , servletresponse response,
      filterchain chain ) throws ioexception, servletexception {
    httpservletrequest hrequest = (httpservletrequest) request;
    // 获取session对象
    httpsession session = hrequest.getsession();
    // 先判断session中的logged是否有值,如没有则说明是新的请求
    if(null==session.getattribute("logged")){
      session.setattribute("logged", "yes");    // 设置logged的值为yes,防止同一会话重复记录
      file file = new file(this.filename);
      if(!file.exists())
        file.createnewfile();        // 判断文件是否存在,如果不存在,就建立一个新的

      /*
       * 创建日志记录内容logcontent包括访问者的ip, 访问的页面url和访问的时间以及日志过滤器的名字
       */
      string logcontent = hrequest.getremotehost()+"->"+hrequest.getrequesturi()+" logged "+gettime()+" by s"+this.filtername+"\r\n";
      randomaccessfile rf = new randomaccessfile(this.filename,"rw");   // 建立一个随机文件操作对象
      rf.seek(rf.length());   // 将写入指针指向文件的尾部,rf.length()获得文件的长度,seek文件长度这么长得距离正好是文件的尾部
      rf.writebytes(logcontent);   // 将日志写入到文件中去
      rf.close();   // 关闭文件
    }
    chain.dofilter(request, response);
  }

  public void init(filterconfig config) throws servletexception {
    this.config = config;
    this.filename = this.config.getinitparameter("file");
    this.filtername = this.config.getfiltername();
  }

  // 获取时间
  private string gettime(){
    simpledateformat sdf  = new simpledateformat("yyyy-mm-dd-hh-mm-ss");
    return sdf.format(new date());
  }

}

这里利用session来限制同一个会话只会记录一次日志,而不管这个会话中的访问者访问了多少个页面,在第一次访问的时候,由于session的logged是空的,所以这个时候记录日志并把logged设置为yes,这样第二次判断的时候将不会执行记录日志。
然后在来配置xml:

复制代码 代码如下:

<filter>
    <filter-name>logfilter</filter-name>
    <filter-class>com.filter.loginfilter</filter-class>
    <init-param>
      <param-name>file</param-name>
      <param-value>d:/log.txt</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>logfilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

配置好xml后,访问跟目录下地任何文件,都会可以在d:/log.txt文件中得到访问者的记录。