SpringMVC源码阅读:过滤器

1.前言SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧本文将通过源码(基于Spring4.3.7)分析,弄清楚SpringMVC过滤器是如何执行的2.源码分析web.xml配置<filter><!--过滤器名称--><filter-name>SetCha...

SpringMVC源码阅读:过滤器

1.前言

SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧

本文将通过源码(基于Spring4.3.7)分析,弄清楚SpringMVC过滤器是如何执行的

2.源码分析

web.xml配置

 <filter>  <!--过滤器名称-->  <filter-name>Set Character Encoding</filter-name>  <!--过滤器处理类-->  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  <!--初始化参数-->  <init-param><param-name>encoding</param-name><param-value>UTF-8</param-value>  </init-param>  <init-param><param-name>forceEncoding</param-name><param-value>true</param-value>  </init-param> </filter> <filter-mapping>  <filter-name>Set Character Encoding</filter-name>  <!--拦截路径-->  <url-pattern>/*</url-pattern> </filter-mapping>

打开CharacterEncoding类,该类为request设置字符编码,打开类继承图

CharacterEncodingFilter重写父类OncePerRequestFilter的doFilterInterval方法

forceRequestEncoding为True

188行获取编码

191行为request设置编码

194行为response设置编码

197行调用FilterChain

打开CharcterEncodingFilter的父类OncePerRequestFilter,OncePerRequestFilter保证请求分发执行一次Filter

CharcterEncodingFilter实现Filter接口的doFilter方法,打开之

96行获取属性,该属性表明这个方法是否被过滤

98行hasAlreadyFilteredAttribute表明这个方法是否被过滤;skipDispatch方法判断是否跳过分发;shouldNotFilter方法默认返回False,被子类重写,然而,CharacterEncodingFilter类并未重写,ForwardedHeaderFilter重写该方法,暂时不看

101行直接调用FilterChain的doFilter方法,FilterChain部分

98行的上述条件都不满足,则进入105行,为request设置“已过滤”标识

107行调用子类CharacterEncodingFilter的doFilterInterval方法

继续深入,打开OncePerRequestFilter类的父类GenericFilterBean类

重点看init方法,该方法启动服务才会进入,主要负责获取web.xml里配置的参数

180行获取FilterConfig

filterClass和filterName是我们在web.xml配置的属性

184行获取<init-param>里属性

185行声明BeanWrapper,一个通用的JavaBean接口,封装了setget方法,在SpringMVC源码阅读:属性编辑器、数据绑定我已经讲过

186行声明资源加载器,加载classpath和文件系统

189行给属性设置True

199行initFilterBean方法被子类重写,用于补充初始化方法,OncePerRequestFilter未重写,我们暂时不看

3.自定义过滤器

现在Web项目基本都是前后端分离的,不可避免地要解决跨域问题。看Filter接口继承图,发现CorsFilter可以处理跨域,但是并不方便

什么是跨域?

前端地址和后台地址的

IP一致,端口不一致

IP不一致,端口不一致

IP不一致,端口一致

都属于跨域范畴

前端代码如下

<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <!-- <link rel="stylesheet" href=""> --> <style> </style></head><body> <script></script> <script type="text/javascript" src="jquery-3.1.1.min.js"></script> <script type="text/javascript">  $.ajax({url: "http://localhost:8080/springmvcdemo/employee/detail/8",data: {},success: function (data) { console.log(html)},dataType: "json"  }); </script></body></html>

将前端代码地址设置为http://localhost:1234,VSCode可以做,不赘述。后台代码地址http://localhost:8080,因为端口不一致,形成了跨域,不做跨域处理,直接访问有如下效果

现在我们来自定义过滤器解决跨域问题

3.1 自定义过滤器继承OncePerRequestFilter

web.xml

 <filter>  <!--过滤器名称-->  <filter-name>CorsFilter</filter-name>  <!--过滤器处理类-->  <filter-class>org.format.demo.custom.ExtendedCorsFilter</filter-class> </filter> <filter-mapping>  <filter-name>CorsFilter
源文地址:https://www.guoxiongfei.cn/cntech/11065.html