栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Zuul关于application/x-www-form-urlencoded踩坑

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Zuul关于application/x-www-form-urlencoded踩坑

一、问题描述:

POST请求,A项目调用B项目,空格转码成了%20;

POST请求,A项目调用zuul,zuul转发到B项目,空格变成了+号;

具体问题:

1、A通过调用FormBody对contentType为application/x-www-form-urlencoded的入参进行编码,其将空格转成了%20

 

2、通过A直接调用B,因为contentType为application/x-www-form-urlencoded,所以tomcat在处理这个请求的时候,从body里面拿出数据流写入parameter里面,导致B项目采取req.getInputStream()的方式拿入参时,没有获取到,所以需要从ParameterMap中获取

如图上第2点所示,最终拿到数据进行编码后再写回 req.getContentLength()长度的数组里面,方法为:in.readFully(dataOrigin),这样写没有问题,因为A入参过来编码空格转成了%20,这儿编码后也将+号替换成了%20,所以A直接调用B这段代码没有问题(URLEncoder.encode(nowStr,"utf-8")是将空格转成+)

3、通过A先调用zuul网关,由于在zuul网关中FormBodyWrapperFilter中会对contentType为application/x-www-form-urlencoded的数据进行特殊处理,将入参中的空格编码成+,然后再写回body中,org.springframework.http.converter.FormHttpMessageConverter.writeForm(MultiValueMap, MediaType, HttpOutputMessage)

 这样,contentLength将会变短,因为原先空格转成了%20,但是在zuul网关中空格转成了+号,所以当再次转发到B项目时,还是会走上图中的if块中的将+再次编码成%20的逻辑,这样

 入参的contentLength和改写后的字符串.getBytes的长度肯定是不等的,再用contentLength的长度去装改写后的入参的数据肯定装不下,所以会报错

二、解决办法

将图中的 req.getContentLength()换成改写后的body.length即可,如果是A直接调用B,那么contentLength肯定是和改写后的入参的长度相等的,因为本身就是将空格换成了%20,如果A调用Zuul网关,再由Zuul网关调用B,由于Zuul网关将空格换成了+号,所以contentLength变短了,那么在上图将空格转成了%20后,入参的byte长度肯定会变成,所以这个时候要么用入参的长度的数组去装改写后的入参,要么在改写后将新的长度写入contentLength里面即可!!!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/643908.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号