SSM-SpringMVC过滤器

x33g5p2x  于2021-12-24 转载在 Spring  
字(5.4k)|赞(0)|评价(0)|浏览(472)

过滤器介绍

1.过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应。

2.Filter也称之为过滤器,它是Servlet技术中核心的技术之一,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp,Servlet, 静态图片文件,xss攻击,或静态html文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

3.Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截

例如:水净化器,可以看成是生活中的一个过滤器,他可以将污水中的杂质过滤,从而使进入的污水变成净水。

过滤器是随着web应用的启动而启动的,只会初始化一次,之后便可以拦截过滤相关的请求或响应,当web应用停止或重新部署的时候才会被销毁。

filter 常用类

springmvc的filter位于 org.springframework.web.filter 包下


最顶层的GenericFilterBean、CompositeFilter无疑都实现javax.servlet.filter接口,其子类都间接地实现了该接口。

常用Filter类介绍

GenericFilterBean

GenericFilterBean是javax.servlet.Filter接口的一个基本的实现类,主要有init方法,获取web.xml的配置参数,保存到bean适配器。该类包含一个内部私有类,主要用于将web.xml中定义的init-param的值取出。它的子类要求实现doFilter()方法。

CharacterEncodingFilter

CharacterEncodingFilter 该过滤器是配置编码格式的,在web.xml中设置如下:

<filter>  
  <filter-name>springCharacterEncodingFilter</filter-name>  
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
  <init-param>  
     <param-name>forceEncoding</param-name>  
     <param-value>true</param-value>  
  </init-param>  
  <init-param>  
     <param-name>encoding</param-name>  
     <param-value>UTF-8</param-value>  
  </init-param>  
</filter>  
<filter-mapping>  
   <filter-name>springCharacterEncodingFilter</filter-name>  
   <url-pattern>/*</url-pattern>  
</filter-mapping>

HiddenHttpMethodFilter

html中form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求。可以配置如下:

<filter>  
    <filter-name>HiddenHttpMethodFilter</filter-name>  
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
    <init-param>  
        <param-name>methodParam</param-name>  
        <param-value>_method_</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>HiddenHttpMethodFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>

在页面的form表单中设置method为Post,并在表单内添加一个如下的隐藏域:

<input type="hidden" name="_method_" value="put" />

HttpPutFormContentFilter

HttpPutFormContentFilter过滤器的作用就是获取put表单的值,并将之传递到Controller中标注了method为RequestMethod.PUT的方法中。
与HiddenHttpMethodFilter不同,在form中不用添加参数名为_method的隐藏域,且method不必是post,直接写成put,但该过滤器只能接受enctype值为application/x-www-form-urlencoded的表单,也就是说,在使用该过滤器时,form表单的代码必须如下:

<form action="" method="put" enctype="application/x-www-form-urlencoded">    </form>

配置如下:

<filter>  
   <filter-name>httpPutFormcontentFilter</filter-name>  
   <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>  
</filter>  
<filter-mapping>  
   <filter-name>httpPutFormContentFilter</filter-name>  
   <url-pattern>/*</url-pattern>  
</filter-mapping>

RequestContextFilter

Spring对页面的request进行转发,通常是通过设置LocaleContextHolder和RequestContextHolder,这种方式通常是用于配置第三方servlet,如jsf时

DelegatingFilterProxy

该类其实并不能说是一个过滤器,它的原型是FilterToBeanProxy,即将Filter作为spring的bean,由spring来管理。该类提供了在web.xml和application context之间的联系。
spring-bean实现了Filter接口,但默认情况下,是由spring容器来管理其生命周期的(不是由tomcat这种服务器容器来管理)。如果没有设置,则使用spring来管理Filter.init()和Filter.destroy();
在Spring Security中就是使用该类进行设置。即在web.xml中配置该过滤器,然后在spring security相关的配置中设置相应的过滤器bean。但是该类是spring-web包下的类,不属于Spring Security类。

Filter接口实现方式

这种方式是最简单而且是最常用的方式,上面讲到的类基本可能你这辈子都用不到但是Filter接口就可能经常使用了,比如项目ajax跨域问题,xss攻击问题,inputStream流二次读写问题,指定资源拦截,或者非法输入…等这些我们在日常项目中是经常遇到的.
我们来实现一个简单的案例:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class MyFilter implements Filter {

    @Override
    public void destroy() {
        System.out.println("销毁过滤器方法");

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("----拦截器");
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        String servletPath = request.getServletPath();
        //访问login.jsp时,才放过,并且login.jsp的后续操作,继续执行,不拦截
        if (servletPath.equals("/login")||servletPath.equals("/index.jsp")) {
            chain.doFilter(req, res); //放行
        } else {
            String contextPath = request.getContextPath();
            response.setCharacterEncoding("utf-8");
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html");
            PrintWriter pw = response.getWriter();
            //否则拦截,跳转指定的页面
            pw.print("<script>window.top.location.href='" + contextPath + "/index.jsp'" + ";</script>");
// request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);//转发
// response.sendRedirect(request.getContextPath()+"/index.jsp"); //重定向就相当于地址栏输入 也不能随便访问jsp

        }

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("初始化过滤器的方法");

    }

}

然后在web.xml中配置

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.config.MyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter</filter-name>
    <!-- 拦截路径 -->
    <url-pattern>/*</url-pattern>
    <!-- <url-pattern>/login/*</url-pattern>-->
  </filter-mapping>

之后启动项目就生效了,但是也有例外的Filter接口不生效情况,这个就需要问项目里的人了,每个项目可能都不同,但是大部分的项目以上配置都是好使的

相关文章