在Springboot项目通过filter修改接口的入参这篇记录中,我记录了一种软件开发的常用架构,关于用户权限信息,主要是在filter中进行过滤及处理,如果是Content-type=application/x-www-form-urlencoded方式,则入参信息从paramterMap中获取;如果Content-type=application/json,入参信息从getInputStream中获取。这其实对应了post请求的两种不同方式,虽然都是放到body中,但是数据封装的方式是不同的,前者类似get请求,将所有入参都通key=value&key=value的方式拼接,并且进行urlencoded,后者是纯粹的json格式字符串放到输入流中。 

       在实际的开发过程中,遇到一个问题。 项目中的接口都是通过form-data的方式提交参数到后端的,有一个接口的入参是根据前端勾选的参数多少进行传递,在前期简单测试的时候,接口一直是没问题,后面偶然一次将选择传递到后端的参数选的非常多的时候,发现报系统异常了。 

       通过跟踪代码发现是在Filter中处理入参信息转换的时候,报JSON转换失败了。 通过跟踪代码发现,请求虽然是form-data,但是入参信息还是放到inputStream中去了,从inputStream中获取的参数在进行json对象转码的时候失败了,这必然会失败,因为form-data的入参是urlencoded方式的,肯定不对。

       然后对代码进行优化,将content-type的限制也加上去。 这时候filter不报错了,但是在controller层获取不到任何入参信息。

问题1:为什么form-data请求的入参在inputStream中,而不是在paramterMap中?

问题2:为什么到了controller中获取不到任何参数了,明明inputStream中是有参数的啊?

       先说下解决方案,解决方案是修改springboot项目的post请求的数据大小,默认大小是2M,我们修改为20M。

server.tomcat.max-http-post-size=20MB

       再进行尝试,问题1和问题2都不存在了,controller可以获取到参数,请求参数也是在paramterMaps中。

总结:

       Springboot默认web容器是tomcat,tomcat关于post请求参数长度有默认限制为2MB,当请求的入参信息大于2MB的时候,会自动将参数封装到请求流中,而不是放到paramterMap中,而对于controller层,框架在进行参数自动转换的时候,是根据content-type到流或者paramterMap中取数据,当content-type是form-data的时候,肯定到paramterMap中取数据,但是因为数据过大放到inputStream中去了,所以获取不到参数。 

       最后通过修改post请求参数大小的限制,将问题解决。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐