黑马小日子--过滤器

来源:互联网 发布:循环冗余检查 数据丢失 编辑:程序博客网 时间:2024/05/17 02:36

过滤器

一、过滤器入门

1. 概念:

    Filter 过滤器,又称拦截器实现 Filter 接口的类称之为 Filter (过滤器或拦截器)

过滤器的作用

1、放行前对请求对象(request)进行预处理

2、目标资源之后后对响应对象(response)进行处理

    chain.doFilter(request, response) 方法放行,目标Servlet使用的是同一个请求和响应

    当目标Servlet 返回响应后, doFilter方法后面的代码会执行,

2编写过滤器步骤

    1、建立一个类,实现javax.servlet.Filter接口

        主要实现doFilter方法:

        SerlvetRequest request:

        SerlvetResposne response:

        FilterChain chain:  doFilter让目标执行

    public class FilterDemo1 implements Filter {

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

            System.out.println("doFilter执行前");

            chain.doFilter(request, response);

            System.out.println("doFilter执行后");

    }

    2) 在web.xml中配置Filter拦截的资源路径

    <filter>

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

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

    </filter>

    <filter-mapping>

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

        <url-pattern>/*</url-pattern>   拦截当前web应用下的所有web资源

    </filter-mapping>

3.   Filter 

在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。

    可以针对某一个url配置多个Filter, 这些Filter就会组成一个Filter链, 用FilterChain对象表示

拦截顺序:web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter

即那个过滤器的<filter-mapping>在前面,哪个过滤器就先拦截

4. Filter Servlet

    Filter 就像一个特殊的Servlet 

    Filter 在web容器启动是就初始化,服务器停掉或卸载web应用时才会被销毁

    Filter 可以实现拦截功能,因为有个 FilterChain 对象,有个 doFilter方法可以实现对访问资源的放行

    Filter可以替代Servlet所有的功能,还多一个放行功能

二、 Filter细节

1. Filter 的生命周期

    在应用启动时就创建过滤器的对象。日后驻留内存服务器停掉或卸载web应用时才会被销毁

2. 获得 Filter 的初始化参数

    在 web.xml 文件中为Filter 配置初始化参数

    <filter>

    <filter-name>CharacterEncodingFilter</filter-name>

    <filter-class>com.itheima.example.CharacterEncodingFilter</filter-class>

    <init-param>

        <param-name>encode</param-name>

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

    </init-param>

  </filter>

    读取参数

    通过public void init(FilterConfig filterConfig) 中的filterConfig.get getInitParameter(“encode”)来获取参数

3. Filter拦截方式

通过一个页面访问另外一个资源,有以下4中方式

1、REQUEST:直接请求(默认过滤器会过滤直接请求的资源)

2、FORWARD:转发(指令的errorPage,实际上就是转发)

3、INCLUDE:包含(静态包含不起作用,因为静态包含就是一个servlet).只对动态包含起作用

4、ERROR:出现异常,转向错误页面(只对web.xml中全局错误页面有效)

 

过滤器可以针对以上情况进行拦截。

<filter-mapping>

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

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

    <dispatcher>REQUEST</dispatcher>

    <dispatcher>FORWARD</dispatcher>

    <dispatcher>ERROR</dispatcher>

    <dispatcher>INCLUDE</dispatcher>

</filter-mapping>

三、 过滤器案例

禁止浏览器缓存所有动态页面

response.setDateHeader("Expires",-1);

response.setHeader("Cache-Control","no-cache");

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

 

强制浏览器缓存所有的静态页面 html jpg css

String uri = request.getRequestURI();  /day17/1.html   /day17/style.css  /day17/script.js

//截取扩展名

String value = null;

String extend = uri.substring(uri.lastIndexOf(".")+1);

if("html".equals(extend))

value = filterConfig.getInitParameter("html");

if("css".equals(extend))

value = filterConfig.getInitParameter("css");

if("js".equals(extend))

    value = filterConfig.getInitParameter("js");

response.setDateHeader("Expires", System.currentTimeMillis()+Long.parseLong(value)*60*60*1000);

chain.doFilter(request, response);

 

实现用户自动登陆

1)在用户登陆成功后,发送一个名称为user的cookie给客户端,cookie的值为用户名和md5加密后的密码

2)编写过滤器检查用户是否带名为user的cookie来,如果有,检查用户名和密码做自动登陆

核心思路:

用户登陆后找LoginServlet , LoginServlet中做登陆,如果登陆成功, 获得用户选择的自动登陆时间

创建一个新的cookie 将用户名和密码用 “_”连接作为value,autoLogin作为name

设置cookie 的有效路径 request.getContextPath() 作用于整个web应用

设置cookie的有效时间为 autologintime

发送 cookie

写一个过滤器,对全站的资源进行拦截, 检查用户发送的cookie有没有一个名为autologin的

如果有 取出用户名和密码 再次做登陆处理 如果登陆成功, 将 user 存入session ,放行

出于安全性考虑, cookie 中的密码应该进行 md5 加密

统一全站字符编码

l       Decorator设计模式的实现

         1.首先看需要被增强对象继承了什么接口或父类,编写一个类也去继承这些接口或父类。

         2.在类中定义一个变量,变量类型即需增强对象的类型。

         3.在类中定义一个构造函数,接收需增强的对象。

         4.覆盖需增强的方法,编写增强的代码。

 

// 解决全站的乱码问题  request response

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

request.setCharacterEncoding("utf-8"); // 只对 post 方式起作用,对get方式不起作用

MyHttpServletRequest mrequest = new MyHttpServletRequest(request); 包装类

对于request的get方式需要手工转换,此时就需要用到 包装设计模式decorator包装 getParameter方法

包装类:

public class MyHttpServletRequest extends HttpServletRequestWrapper{

    private HttpServletRequest request;

    public MyHttpServletRequest(HttpServletRequest request){

       super(request);

       this.request = request;

    }

    //解决get方式编码

    public String getParameter(String name) {

       try {

           String method = request.getMethod();

           String value  = request.getParameter(name);

           if(value==null)

              return null;

           if("get".equalsIgnoreCase(method))

              value = new String(value.getBytes("ISO-8859-1"),request.getCharacterEncoding());

           return value;

       } catch (UnsupportedEncodingException e) {

           throw new RuntimeException(e);

       }

    }

}

原创粉丝点击