Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题
2021-10-05 15:28
696 查看
Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题
继实现动态修改请求 Body 以及重试带 Body 的请求之后,我们又遇到了一个小问题。最近很多接口,收到了错误的参数,在接口层报的错是:
class org.springframework.web.method.annotation.MethodArgumentTypeMismatchException, Failed to convert value of type 'java.lang.String' to required type 'java.lang.Integer'; nested exception is java.lang.NumberFormatException: For input string: "10#scrollTop=8178"
例如上面这个报错即本来应该是一个数字,结果收到的是 10#scrollTop=8178 导致转换异常。
正常的请求,是可以带 # 的,# 后面的部分属于 fragment。一个 URI 包括:
但是对于这些报错的请求,我们发现,发送的请求的原始 URI 中, # 被错误的 URL 编码了,变成了 %23,例如上面的请求,发到后端的是:
https://zhxhash@example.com:8081/test/service?id=test&number=10%23segment1
这样,后端解析到的 number 的值,就是
number=10#segment1,这样就会发生开头提到的报错。
由于前端没能复现这个问题,并且问题集中于某几个系统的浏览器版本,这个问题只能通过后台网关做修改解决。
我们的网关使用的是 Spring Cloud Gateway,我们可以针对全局请求添加全局 Filter,动态修正 URI,解决这个问题,代码如下:
@Log4j2 @Component public class QueryNormalizationFilter implements GlobalFilter, Ordered { @Override @SneakyThrows public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String originUriString = exchange.getRequest().getURI().toString(); if (originUriString.contains("%23")) { //将编码后的 %23 替换为 #,重新用这个字符串生成 URI URI replaced = new URI(originUriString.replace("%23", "#")); return chain.filter( exchange.mutate() .request( new ServerHttpRequestDecorator(exchange.getRequest()) { /** * 这个是影响转发到后台服务的 uri * * @return */ @Override public URI getURI() { return replaced; } /** * 修改这个主要为了后面的 Filter 获取查询参数是准确的 * * @return */ @Override public MultiValueMap<String, String> getQueryParams() { return UriComponentsBuilder.fromUri(replaced).build().getQueryParams(); } } ).build() ); } else { return chain.filter(exchange); } } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } }
注意点是:
- 我们需要将这个 Filter 放在最开始的位置,保证后续的 Filter 的 URI 是正确的,以免有的 Filter 拿 Fragment 做文章。
- 如果我们只关心转发的请求是正确的,那我们只替换 URI 即可,即覆盖 getURI 方法。
- 连 getQueryParams 也覆盖的原因,是后续的 Filter 可能也会对 QueryParams 做一些操作,我们要保证准确性。
- 只覆盖 getQueryParams,并不会修改后续转发到具体的微服务的请求的 QueryParams,这个只能通过覆盖 getURI 修改。
微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer:
相关文章推荐
- gateway动态路由nacos配置中心路由配置spring-cloud-alibaba 解决nacos config配置不生效问题
- Javascript escape 解决 Jquery Ajax 异步请求 URL中文传参乱码问题 一般处理程序Handler获取参数
- Spring Cloud Gateway -- ResponseBody修改(解决ResponseBody不完整的问题)
- spring cloud gateway请求跨域问题解决方案
- 解决spring设置filter过滤器结合rest风格获取post请求body参数输入流问题
- Android使用HttpUrlConnection get请求带中文参数的编码问题
- 微信公众号平台网页授权接口中获取到的授权code传递给(即一个微信公众号网页授权给)任何其他多个回调域名下的url,解决了只能设置一个网页授权回调域名的问题,解决了redirect_uri参数错误的问
- 前台页面使用utf-8编码,url中包含中文参数时后台获取参数乱码问题解决
- Spring Cloud中,如何解决Feign/Ribbon第一次请求失败的问题?
- SpringBoot2.1.3修改tomcat参数支持请求特殊符号问题
- 在filter过滤器里面使用动态代理的方法解决网站request请求乱码问题,实现统一编码(附带装饰者模式的写法)
- javascript 对url参数进行编码(解决中文乱码问题)
- 解决multipart/form-data表单中传递参数问题(动态更改表单提交URL)
- 解决spring设置filter过滤器结合rest风格获取post请求body参数输入流问题
- springcloud 中 zuul 如何修改请求参数
- Spring Tomcat Post Get 请求参数有中文时出现乱码或+号变空格等关于编码的问题
- 发送带参数的get请求,并解决httpclient编码问题
- springcloud+gateway 跨域问题解决
- thickbox中url传递参数的问题解决 -修改Thickbox.js
- 解决HttpURLConnection请求时传中文参数乱码问题