1.过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应。
2.Filter也称之为过滤器,它是Servlet技术中核心的技术之一,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp,Servlet, 静态图片文件,xss攻击,或静态html文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
3.Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截
例如:水净化器,可以看成是生活中的一个过滤器,他可以将污水中的杂质过滤,从而使进入的污水变成净水。
过滤器是随着web应用的启动而启动的,只会初始化一次,之后便可以拦截过滤相关的请求或响应,当web应用停止或重新部署的时候才会被销毁。
springmvc的filter位于 org.springframework.web.filter 包下
最顶层的GenericFilterBean、CompositeFilter无疑都实现javax.servlet.filter接口,其子类都间接地实现了该接口。
GenericFilterBean是javax.servlet.Filter接口的一个基本的实现类,主要有init方法,获取web.xml的配置参数,保存到bean适配器。该类包含一个内部私有类,主要用于将web.xml中定义的init-param的值取出。它的子类要求实现doFilter()方法。
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>
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过滤器的作用就是获取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>
Spring对页面的request进行转发,通常是通过设置LocaleContextHolder和RequestContextHolder,这种方式通常是用于配置第三方servlet,如jsf时
该类其实并不能说是一个过滤器,它的原型是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接口就可能经常使用了,比如项目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接口不生效情况,这个就需要问项目里的人了,每个项目可能都不同,但是大部分的项目以上配置都是好使的
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_45203607/article/details/122096988
内容来源于网络,如有侵权,请联系作者删除!