jsp读书笔记——servlet过滤器

 Servlet过滤器简介      

       Servlet过滤器是通过一个配置文件来灵活声明的模块化的可重用组建。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来部署到应用中。
      配置如下
   

[html]  view plain  copy
 print ?
  1. < filter>  
  2.             <filter-name>Filtername</filter-name>  
  3.   
  4.             <filter-class>com.filter.Filter/class</filter-class>  
  5.   
  6.        <init-param>  
  7.            <param-name>file</param-name>  
  8.            <param-value>filename</param-value>  
  9.        </init-param>  
  10.     </filter>  
  11.   
  12.     <filter-mapping>  
  13.          <filter-name>Filtername</filter-name>  
  14.         <url-pattern>/*</url-pattern>  
  15.    </filter-mapping>  

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

[java]  view plain  copy
 print ?
  1. package com.filter;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.Filter;  
  6.   
  7. import javax.servlet.FilterChain;  
  8.   
  9. import javax.servlet.FilterConfig;  
  10.   
  11. import javax.servlet.ServletException;  
  12.   
  13. import javax.servlet.ServletRequest;  
  14.   
  15. import javax.servlet.ServletResponse;  
  16.   
  17. public class CharacterEncodingFilter implements Filter {  
  18.   
  19. private FilterConfig config;  
  20.   
  21. private String encoding = "ISO8859_1";  
  22.   
  23. public void destroy() {  
  24.   
  25.   config = null;  
  26.   
  27. }  
  28.   
  29. public void doFilter(ServletRequest request, ServletResponse response ,  
  30.   
  31.    FilterChain chain) throws IOException, ServletException {  
  32.   
  33.   request.setCharacterEncoding(encoding);  
  34.   
  35.   chain.doFilter(request, response);  
  36.   
  37. }  
  38.   
  39. public void init(FilterConfig config) throws ServletException {  
  40.   
  41.   this.config  = config;  
  42.   
  43.   String s = config.getInitParameter("encoding");  
  44.   
  45.   if(s!=null){  
  46.   
  47.    encoding = s;  
  48.   
  49.   }  
  50.   
  51. }  
  52.   
  53. }  

然后在是XML的配置:

[html]  view plain  copy
 print ?
  1. <filter>  
  2.   
  3.   <filter-name>encodingFilter</filter-name>  
  4.   
  5.   <filter-class>com.filter.CharacterEncodingFilter</filter-class>  
  6.   
  7.   <init-param>  
  8.   
  9.     <param-name>encoding</param-name>  
  10.   
  11.     <param-value>utf-8</param-value>  
  12.   
  13.   </init-param>  
  14.   
  15. </filter>  
  16.   
  17. <filter-mapping>  
  18.   
  19.   <filter-name>encodingFilter</filter-name>  
  20.   
  21.   <url-pattern>/*</url-pattern>  
  22.   
  23. </filter-mapping>  

最后是encoding。jsp的编写?: 

[html]  view plain  copy
 print ?
  1. 用户名:<c:out value="${param.username}" default="none"></c:out><br>  
  2.   
  3.       密码:<c:out value="${param.userpassword}" default="none"></c:out><br>  
  4.   
  5.       <form action="MyJsp.jsp" method="post">   
  6.   
  7.         用户名:<input type="test" name="username"> <br>  
  8.   
  9.         密码:<input type="password" name="userpassword"><br>  
  10.   
  11.         <input type="submit" value="提交">  
  12.   
  13.       </form>  


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

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

[html]  view plain  copy
 print ?
  1. package com.filter;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.RandomAccessFile;  
  6.   
  7. import java.text.SimpleDateFormat;  
  8. import java.util.Date;  
  9. import javax.servlet.Filter;  
  10. import javax.servlet.FilterChain;  
  11. import javax.servlet.FilterConfig;  
  12. import javax.servlet.ServletException;  
  13. import javax.servlet.ServletRequest;  
  14. import javax.servlet.ServletResponse;  
  15. import javax.servlet.http.HttpServletRequest;  
  16. import javax.servlet.http.HttpSession;  
  17.   
  18. import com.sun.org.apache.bcel.internal.generic.NEW;  
  19.   
  20. public class LoginFilter implements Filter{  
  21.   
  22.   private FilterConfig config =null;  
  23.   private String filename = null;  
  24.   private String filtername = null;  
  25.   public void destroy() {  
  26.     this.config = null;  
  27.     this.filename = null;  
  28.     this.filtername = null;  
  29.   }  
  30.   
  31.   public void doFilter(ServletRequest request , ServletResponse response,  
  32.       FilterChain chain ) throws IOException, ServletException {  
  33.     HttpServletRequest hRequest = (HttpServletRequest) request;  
  34.     // 获取session对象  
  35.     HttpSession session = hRequest.getSession();  
  36.     // 先判断session中的LOGGED是否有值,如没有则说明是新的请求  
  37.     if(null==session.getAttribute("LOGGED")){  
  38.       session.setAttribute("LOGGED", "yes");    // 设置LOGGED的值为yes,防止同一会话重复记录  
  39.       File file = new File(this.filename);  
  40.       if(!file.exists())  
  41.         file.createNewFile();        // 判断文件是否存在,如果不存在,就建立一个新的  
  42.         
  43.       /*  
  44.        * 创建日志记录内容logContent包括访问者的IP, 访问的页面URL和访问的时间以及日志过滤器的名字  
  45.        */  
  46.       String logContent = hRequest.getRemoteHost()+"->"+hRequest.getRequestURI()+" Logged "+getTime()+" By s"+this.filtername+"\r\n";  
  47.       RandomAccessFile rf = new RandomAccessFile(this.filename,"rw");   // 建立一个随机文件操作对象  
  48.       rf.seek(rf.length());   // 将写入指针指向文件的尾部,rf.length()获得文件的长度,seek文件长度这么长得距离正好是文件的尾部  
  49.       rf.writeBytes(logContent);   // 将日志写入到文件中去  
  50.       rf.close();   // 关闭文件  
  51.     }  
  52.     chain.doFilter(request, response);  
  53.   }  
  54.   
  55.   public void init(FilterConfig config) throws ServletException {  
  56.     this.config = config;  
  57.     this.filename = this.config.getInitParameter("file");  
  58.     this.filtername = this.config.getFilterName();  
  59.   }  
  60.     
  61.   // 获取时间  
  62.   private String getTime(){  
  63.     SimpleDateFormat sdf  = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");  
  64.     return sdf.format(new Date());  
  65.   }  
  66.   
  67. }  


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

[html]  view plain  copy
 print ?
  1. <filter>  
  2.   <filter-name>LogFilter</filter-name>  
  3.   <filter-class>com.filter.LoginFilter</filter-class>  
  4.   <init-param>  
  5.     <param-name>file</param-name>  
  6.     <param-value>D:/log.txt</param-value>  
  7.   </init-param>  
  8. </filter>  
  9.   
  10. <filter-mapping>  
  11.   <filter-name>LogFilter</filter-name>  
  12.   <url-pattern>/*</url-pattern>  
  13. </filter-mapping>  

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李晓LOVE向阳

你的鼓励是我持续的不断动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值