• 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来部署到应用中。配置如下 

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

     1 public class CharacterEncodingFilter implements Filter {
     2 
     3 private FilterConfig config;
     4 
     5 private String encoding = "ISO8859_1";
     6 
     7 public void destroy() {
     8 
     9   config = null;
    10 
    11 }
    12 
    13 public void doFilter(ServletRequest request, ServletResponse response ,
    14 
    15    FilterChain chain) throws IOException, ServletException {
    16 
    17   request.setCharacterEncoding(encoding);
    18 
    19   chain.doFilter(request, response);
    20 
    21 }
    22 
    23 public void init(FilterConfig config) throws ServletException {
    24 
    25   this.config  = config;
    26 
    27   String s = config.getInitParameter("encoding");
    28 
    29   if(s!=null){
    30 
    31    encoding = s;
    32 
    33   }
    34 
    35 }
    36 
    37 }

            然后在是XML的配置:

     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的编写?:

     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类,这个过滤器主要负责记录用户的访问记录:

    View Code
     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:

     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文件中得到访问者的记录:

    PS:如果你觉得文章对你有所帮助,别忘了推荐或者分享,因为有你的支持,才是我续写下篇的动力和源泉!
  • 相关阅读:
    农历查询
    C#颜色转换函数
    在IIS部署Silverlight网站
    silverlight双击事件处理
    关于List.Sort想到的
    sql获取总列数
    NHibernate的no persister for
    如何快速构建React组件库
    如何用canvas拍出 jDer's工作照
    Picker 组件的设计与实现
  • 原文地址:https://www.cnblogs.com/chenssy/p/2589619.html
Copyright © 2020-2023  润新知