为了提高接口安全性,防止初级黑客直接手机抓包,因此在springcloud gateway增加了一层加解密协议,但是在和客户端对接加解密过程中,收到手机端反馈调用新接口报错,而老的未加密接口,则没有报错。手机端没有明确提示错误,只是告知服务器端响应500状态码。通过日志我发现,服务器端显示如下错误:

这是加解密全局过滤器报的错误。看到 提示“The body is not set. Did handling complete with success”,我首先怀疑客户端是不是没有传递body?因此还跟手机端理论了一会儿,但是手机端也很硬气,“我调用未加密接口”就不报错。

好吧,我安抚一下,暗示自己要用代码来征服对方。

百度,google了一大片,焦头烂额,没有找到答案,心里想,完了,又遇到短板了。难道要苦读spring cloud gateway的源码么?这问题怎么跟手机端交代呢?完了,架构师要丢人了。

过了好长时间,整理了一下烦躁的情绪,拿出必死的决心,干!

重新梳理了一下问题:

1、手机端在非加密接口请求没有问题,同样的参数和数据,在加密端有问题。这个是毋庸置疑了。

2、其他接口加解密没有问题,就这个接口有问题。

3、这个接口是一个上传附件的接口,一个附件上传也没有问题,增加到2个附件的时候,就报错。接口采用base64编码上传附件。

突然一个年头闪现在脑海,是不是也是因为请求数据量太大的原因。之前测试加解密接口时,因为一个接口返回的数据量太大,网关也报了一次错。这次是不是相同的解决方法?

于是赶紧查看上次解决问题都变更的记录。这个查看变更过程也很曲折,因为上次解决完问题,不是一次性提交的代码(分了好几次提交),导致我法完快速查找出整个问题的改动。又过了半天,终于理清了思路,解决了这个问题。

解决方法如下:

1、在ModifiedRequestDecorator中增加ServerCodecConfigurer类,ModifiedRequestDecorator中的filter方法中,messageReaders从ServerCodecConfigurer中获取。

核心代码如下:

2、在全局filter中,把spring管理的ServerCodecConfigurer注入进来,并在spring配置文件中配置大小为spring.codec.max-in-memory-size=5242880 我这里默认设置的是5M,可以结合实际情况进行修改。

问题完美解决

2022年10月26日 补充

今天发现另外一个问题,也会导致报The body is not set. Did handling complete with success的异常。那就是当http请求的body为空时,在程序中,如果没有处理好,也会报错。

修改方法是,当遇见空的body请求时,返回空字符串即可。

spring-cloud-gateway增加全局过滤器后对部分接口报The body is not set. Did handling complete with success错误, @Override public Mono<Void> filter(ServerWebExchange exchange, Gateway FilterChain chain) { log.info("进入request拦截器**********"); ServerHttpRequ
我们的一些企业对于HTTP服务有一些非正常的做法,它们客户端的请求 body 是加密的,即在服务端需要对请求 body 进行解密,而服务端响应的 body 也要求加密。本文就来揭秘这一需求在 WebFlux 中如何实现,我们给 request/response body 均增加一个表示时间戳的字段 start/end 来模拟请求数据解密和响应数据加密,思路如下。 首先我们需要知道,WebFlux 的过滤器/拦截器是统一用WebFilter 来表示的,与 Spring MVC 类似,对于 application/js.
错误案例一 Com ponent constructors should be called while initialization. A constructor call has been ignored. Com ponent像页面一样由wxml、wxss、js和json4个文件组成,且需要把这4个文件放在同一个目录中。与页面不一样的是, Com ponent中的构造函数(也可以称构造器)是Co...
故事还得从一个bug说起。今天有人问我,为什么发到后端的请求400了,我说肯定是参数不对,你去检查检查GET、POST之类的方法写没写对,要么就是字段没对上,无非是这几个问题。然后他说检查过了,没问题啊;我不太相信,但是看了看前端发送的请求,好像确实没啥问题: 我说既然这样,那肯定是后端写错了,但后端说他已经用postman测过了,肯定没问题。这就很有意思了。于是我要来了后端的代码: 不出所料,...
错误类型大致为以下几种: java.lang.IllegalStateException:Cannot   forward   a   response   that   is   already com mitted  IllegalStateException:response already com mited  IllegalStateException:get elasitcsearch 开启认证后,报DecoderException: javax.net.ssl.SSLHandshakeException: No available authentic异常 10282 elasitcsearch 开启认证后,报DecoderException: javax.net.ssl.SSLHandshakeException: No available authentic异常 DiQi.: 如果您使用密码保护节点的证书,请将密码添加到您的Elasticsearch密钥库中: 如果签署的证书是PKCS#12格式,请使用以下命令: bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password docker与直接运行本地程序的区别 灵狐技术: 在拥有大量服务器和应用的软件系统,它们的安装、更新、环境配置的需要大量的人工操作。 虚拟机镜像和docker被用来解决,这类运维阶段的人海战术问题。 IT行业对新技术,存在言必“最佳实践”的风起。其实,适合的才是最好的,而不是最新的才是最好的。 对于广大IT行业的中小站点、企业,用户量不大,业务量不大,服务器数量几个,自己几个人就能够完成运维的,docker跟你们根本没有什么关系,根本不需要画蛇添足,使用什么docker,直接运行本地程序。 docker与直接运行本地程序的区别 灵狐技术: 你的话没说到点上,也难怪人家对docker的嘲讽。 docker和虚拟机的镜像是被用来解决发布后,程序安装和运行,还得依赖操作系统环境的问题,过去必须要专业人员到现场解决。docker和虚拟机的镜像,都要付出一定环境开销的代价。 博主的困惑是,(开发者几个人就能够运维的个人小网站,服务器才几台,环境),我安装一个docker有什么好处?除了炒作,有啥意义? 我会直接说,除了给自己制造问题,docker对博主这类小站的开发者而言,确实没有任何意义,建议直接运行本地程序。 log4j2(随机数用尽)导致的springboot项目启动慢 Xd聊架构: 写的太棒了把,忍不住三连,期待大佬的回访哦