一、过滤器Filter

1.filter的简介

filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目   标资源访问前后进行逻辑处理

2.快速入门

步骤:

1)编写一个过滤器的类实现Filter接口

2)实现接口中尚未实现的方法(着重实现doFilter方法)

3)在web.xml中进行配置(主要是配置要对哪些资源进行过滤)

(1)创建Filter实现Filter

拦截之后要放行。

package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class FirstFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
//        自动拦截请求
            System.out.println("filter running.......");
//            放行
            chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}

 

(2)Web.xml配置一下

<filter>
      <filter-name>FirstFilter</filter-name>
      <filter-class>filter.FirstFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>FirstFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

 

/*代表所有请求,如果不放行,客户端得不到响应。

3.Filter的API详解

(1)filter生命周期及其与生命周期相关的方法

Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法

init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行

doFilter(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法

destory():代表是filter销毁方法 当filter对象销毁时执行该方法

 

Filter对象的生命周期:

Filter何时创建:服务器启动时就创建该filter对象

中间在客户端访问过滤器过滤的资源时调用doFilter方法

Filter何时销毁:服务器关闭时filter销毁

 

(2)Filter的API详解

1)init(FilterConfig)

其中参数config代表 该Filter对象的配置信息的对象,内部封装是该filter的配置信息。

 

2)destory()方法

filter对象销毁时执行

3)doFilter方法

doFilter(ServletRequest,ServletResponse,FilterChain)

其中的参数:

ServletRequest/ServletResponse:每次在执行doFilter方法时 web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request个该response就是在访问目标资源的service方法时的request和response。

FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求

 

4.Filter的配置

<filter>
      <filter-name>Filter2</filter-name>
      <filter-class>filter.Filter2</filter-class>
       <init-param>
          <param-name>name</param-name>
          <param-value>dahua</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>Filter2</filter-name>
      <url-pattern>/*</url-pattern>
      <dispatcher>REQUEST</dispatcher>
  </filter-mapping>

 

也可以直接拦截Servlet(等价于url-pattern   /sertvle1)

<filter-mapping>
      <filter-name>Filter2</filter-name>
      <servlet-name>servlet</servlet-name>
  </filter-mapping>

①url-pattern配置时(不用写工程名字,直接写路径)

1)完全匹配  /sertvle1

2)目录匹配  /aaa/bbb/* ----最多的

/user/*:访问前台的资源进入此过滤器

/admin/*:访问后台的资源时执行此过滤器

3)扩展名匹配  *.abc  *.jsp

 

注意:url-pattern可以使用servlet-name替代,也可以混用

 

dispatcher:访问的方式(了解)

REQUEST:默认值,代表直接访问某个资源时执行filter

        转发拦截一次,重定向2次

FORWARD:转发时才执行filter

INCLUDE: 包含资源时执行filter

ERROR:发生错误时 进行跳转是执行filter

 

5.总结Filter的作用?

1)公共代码的提取

2)可以对request和response中的方法进行增强(装饰者模式/动态代理)

3)进行权限控制

6.总结

1.Filter先写实现方法,再在web.xml中配置(名字,映射以及拦截的请求)

url-pattern配置时  不写工程名字

1)完全匹配  /sertvle1

2)目录匹配  /aaa/bbb/* ----最多的

/user/*:访问前台的资源进入此过滤器

/admin/*:访问后台的资源时执行此过滤器

3)扩展名匹配  *.abc  *.jsp

2.过滤器的执行顺序根据你在web.xml中映射的顺序执行。

3.可以过滤用户请求:

package web.filter;

import java.io.IOException;

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.HttpServletResponse;
import javax.servlet.http.HttpSession;

import daomain.User;

public class RequestFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletRequest req =(HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if(user==null){
            request.getRequestDispatcher("/index.jsp").forward(request, response);
        }
        else{
            System.out.println(user);
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

    
}

 

二、设置编码格式

1.post提交

(1)编写过滤器代码

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        chain.doFilter(request, response);
    }

(2)Web.xml中队所有请求拦截

(3)后台直接接受post提交的中文数据

2.get提交

接收前端:

String para = request.getParameter("name");
String para2 = new String(para.getBytes("iso-8859-1"),"utf-8");

 

向前端发送

//设置response查询的码表 
        //response.setCharacterEncoding("UTF-8");
        
        //通过一个头 Content-Type 告知客户端使用何种码表
        //response.setHeader("Content-Type", "text/html;charset=UTF-8");
        
//        这句与上句等价,开发中只用写这句,tomcat自动设置第一句
        response.setContentType("text/html;charset=UTF-8");

 

三、装饰者模式解决乱码
package filter;


import java.io.IOException;
import java.io.UnsupportedEncodingException;

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.HttpServletRequestWrapper;

public class EncodingFilter implements Filter{

    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        //request.setCharacterEncoding("UTF-8");
        
        //在传递request之前对request的getParameter方法进行增强
        /*
         * 装饰者模式(包装)
         * 
         * 1、增强类与被增强的类要实现统一接口
         * 2、在增强类中传入被增强的类
         * 3、需要增强的方法重写 不需要增强的方法调用被增强对象的
         * 
         */
        
        //被增强的对象
        HttpServletRequest req = (HttpServletRequest) request;
        //增强对象
        EnhanceRequest enhanceRequest = new EnhanceRequest(req);
        
        
        chain.doFilter(enhanceRequest, response);
        
    }

    @Override
    public void destroy() {
        
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        
    }

}

class EnhanceRequest extends HttpServletRequestWrapper{
    
    private HttpServletRequest request;

    public EnhanceRequest(HttpServletRequest request) {
        super(request);
        this.request = request;
    }
    
    //对getParaameter增强
    @Override
    public String getParameter(String name) {
        String parameter = request.getParameter(name);//乱码
        try {
            parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return parameter;
    }
    
}

 四、过滤登录的过滤器

 <filter>
  <filter-name>sessionFilter</filter-name>
  <filter-class>com.FlyPig.util.filter_session</filter-class>
 </filter>

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

 

filter代码如下:起到了过滤登陆界面login.jsp和根路径以外的过滤

 1 package com.FlyPig.util;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 import javax.servlet.http.HttpSession;
14 
15 public class filter_session implements Filter {
16     private String encoding;
17 
18     public filter_session() {
19     }
20 
21     public void init(FilterConfig filterconfig) throws ServletException {
22         encoding = "utf-8";
23     }
24 
25     public void doFilter(ServletRequest servletrequest,
26             ServletResponse servletresponse, FilterChain filterchain)
27             throws IOException, ServletException {
28         servletrequest.setCharacterEncoding(encoding);
29         servletresponse.setCharacterEncoding(encoding);
30         HttpServletRequest req=(HttpServletRequest)servletrequest;
31         HttpSession session=req.getSession();
32         HttpServletResponse resp=(HttpServletResponse) servletresponse;
33         
34         String url=req.getRequestURI();
35         System.out.println(url);
36         if(!url.equals("/FlyPig")&&!url.equals("/FlyPig/login.jsp")){
37             if(session.getAttribute("username")==null||session.getAttribute("username")==""){
38                 resp.sendRedirect("login.jsp");
39                 return ;
40             }
41         }
42         
43         
44         filterchain.doFilter(servletrequest, servletresponse);
45     }
46 
47     public void destroy() {
48     }
49 }

 

补充:过滤器在请求前可以执行一次,请求后也可以执行:

//前处理

filterchain.doFilter(servletrequest, servletresponse);

//后处理

 

  也就是说在请求完成并且页面载入完成之后会执行后处理,从Java的语法来看放行之后方法没有retur,所以方法会继续执行。用于在处理所有请求的一次请求前和请求后处理。

 

【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】