• Spring MVC 八 - 内置过滤器


    SpringMVC内置如下过滤器:

    1. Form Data
    2. Forwarded Headers
    3. Shallow ETag
    4. CORS
    Form Data

    浏览器可以通过HTTP GET或HTTP POST提交form data(表单数据),但是非浏览器客户端可以通过HTTP PUT、HTTP DELETE、HTTP PATCH提交表单数据。但是Servlet规范约定,通过Servlet API的ServletRequest.getParameter*()系列接口只能获取到HTTP POST提交的表单数据。

    所以,通过其他方式提交的表单数据就获取不到。

    SpringMVC提供了一个解决该上述问题的方案,就是FormContentFilter过滤器,FormContentFilter 是SpringMVC的内置过滤器,配置后立即生效,可以把除POST的其他方法提交上来的表单数据(content type为application/x-www-form-urlencoded)包装成servletRequest的参数、从而通过Servlet API的ServletRequest.getParameter*()方法获取到。

    源码:

    	@Override
    	protected void doFilterInternal(
    			HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    			throws ServletException, IOException {
    
    		MultiValueMap params = parseIfNecessary(request);
    		if (!CollectionUtils.isEmpty(params)) {
    			filterChain.doFilter(new FormContentRequestWrapper(request, params), response);
    		}
    		else {
    			filterChain.doFilter(request, response);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    解析context type为"application/x-www-form-urlencoded"的body信息获取到表单数据组成params Map,之后将params包装到FormContentRequestWrapper中的formParams属性中:

    		public FormContentRequestWrapper(HttpServletRequest request, MultiValueMap params) {
    			super(request);
    			this.formParams = params;
    		}
    
    		@Override
    		@Nullable
    		public String getParameter(String name) {
    			String queryStringValue = super.getParameter(name);
    			String formValue = this.formParams.getFirst(name);
    			return (queryStringValue != null ? queryStringValue : formValue);
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    之后调用HttpServletRequest的getParameter方法会从formParams中获取数据。

    Forwarded Headers

    RFC 7239 定义了HTTP Forwarded请求头来反应经过代理之后的原始请求头信息,比如原始请求主机、端口号等信息。此外,还会有其他的非标准的转发头信息比如:X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, X-Forwarded-Ssl, X-Forwarded-Prefix等等。

    SpringMVC提供了一个内置过滤器ForwardedHeaderFilter,目的是:

    1. 改变Forwarded请求头的host、port等相关信息
    2. 移除这些头信息,以便消除后续影响(比如处于安全考虑)

    如果配置ForwardedHeaderFilter的参数removeOnly=true的话,所有forwarded相关的参数都会被移除:

    	@Override
    	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
    			FilterChain filterChain) throws ServletException, IOException {
    
    		if (this.removeOnly) {
    			ForwardedHeaderRemovingRequest wrappedRequest = new ForwardedHeaderRemovingRequest(request);
    			filterChain.doFilter(wrappedRequest, response);
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    否则,ForwardedHeaderFilter将会从HTTP Forwarded请求头中重新构建request及response的包装类,使得包装类中的请求反应HTTP Forwarded中的原始请求信息。因此,后续的处理从request中拿到的就会是原始请求的相关信息。

    Shallow ETag

    ShallowEtagHeaderFilter是SpringMVC用来处理“弱”ETag的过滤器,配置打开该过滤器后,会计算请求内容的MD5到response中,下次浏览器再次发送请求的时候会通过request的头信息If-None-Match发送该MD5数据,ShallowEtagHeaderFilter会再次计算请求内容的MD5值并与request头信息的If-None-Match比较,如果相等的话,则返回前台304状态码。

    这个策略会节约网络带宽但是不会节省CPU计算,因为每次请求上来之后请求内容都需要被计算一次MD5,如果通过MD5判断后请求内容和上次请求相同的话,只返回304状态码而无需再次返回内容。

    测试发现chrome浏览器在后台发送Etag回来之后也并不会发送If-None-Match,会导致该过滤器无效,应该是需要chrome端做一个什么设置,尚未搞定,各位如果需要使用本过滤器的话需要注意。但是换成Edge浏览器之后是正常的、可以收到304的。

    COR

    跨域过滤器CorsFilter,如果不使用Spring Security的话,可以通过CorsFilter进行跨域处理。

    上一篇 Spring MVC 七 - Locale 本地化

  • 相关阅读:
    为什么建议项目经理尽快考CSPM?告诉你答案
    gpu是什么和cpu的区别
    【数字IC】深入浅出理解AXI协议
    新生报到小程序毕业设计,新生报到管理系统设计与实现,毕设作品参考
    Java毕业设计-会议室预约小程序系统
    深度学习卷积神经网络垃圾分类系统 - 深度学习 神经网络 图像识别 垃圾分类 算法 小程序 计算机竞赛
    「九章云极DataCanvas」完成C+轮融资, 用云中云战略引领数据智能基础软件升级
    ansible copy模块--持续创作中
    《HelloGitHub》第 89 期
    归并排序-Python
  • 原文地址:https://blog.csdn.net/weixin_44612246/article/details/132891210