ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-12-08 12:00:53  阅读:284  来源: 互联网

标签:www 调用 20 form contentLength zuul 网关 空格 Zuul


一、问题描述:

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<String, String>, 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,调用,20,form,contentLength,zuul,网关,空格,Zuul
来源: https://blog.csdn.net/DJYDFT2831djydft/article/details/121787113

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有