SpringWebFlux RequestBody多出双引号问题——ProxyPin抓包揪出真凶

缘起

公司有个服务做埋点收集的,可以参考我之前的文章埋点日志最终解决方案,今天突然发现有些数据日志可以输出,但是没法入库。

多出的双引号

查看Flink日志发现了JSON解析失败,Flink是从Kafka拿数据,Kafka本身不处理数据,Kafka前面是埋点收集服务,这个服务是SpringWebFlux+ReactorKafka做的,收集到数据后对数据做一些解码或解密(如UrlDecode,Base64Decode或者Aes解密等),写入日志并且扔进Kafka。查看日志发现类似以下内容:

log 复制代码
# 省略了大部分字段,只为说明问题
"{"client":"xcx","os":"windows","ip":"192.168.1.1","xx":"xxxx"}"
"{"client":"xcx","os":"Macos","ip":"192.168.1.1","xx":"xxxx"}"

明显看出前后各多了一个双引号。

场景复现

仔细比对了大量日志,发现只有MacOS和Windows下的微信打开小程序时会出现这个问题,安卓,iOS系统的微信小程序不会出现这个问题,分别使用了一台MacOS和Windows,成功复现

SpringWebFlux的HttpMessageConverter捣的鬼???

顺着日志输出的往上找,有一个UrlDeocde操作,仔细测试了下这个UrlDeocde步骤,发现不会自动产生双引号。我第一个想到的就是SpringMVC如果HttpMessageConverter使用不当就导致这个问题,尤其是想使用FastJson序列化JSON但没处理Jackson,这俩同时存在的时候,会多出双引号。于是我在Controller里面对应的方法下了一个断点。

java 复制代码
@PostMapping(value = "/receive/xcx")
public Mono<ResultBase<String>> receiveXcx(@RequestBody Mono<String> body) {
	return xcxKafkaSink.sendRecord(body).map(ResultBase::of); //这一行下断点
}

从这个点开始回溯发现SpringWebFluxSpringMVC差距太大,这个Reactor风格的异步调用链,真是看不出中间干了啥,更别提找到HttpMessageConverter在哪执行的,后来找到了HttpMessageConverter的实现类,在对应的方法read()中都下了断点,根本没走到断点。

我在xcxKafkaSink.sendRecord(body)加了一行输出日志打印了一下body,发现当前端传入双引号时会这里会出现双引号,当前端不传入双引号时,这里就没有双引号,证明了问题大概率出在请求方。

后来和架构聊了下发现以上存在2个问题:

  1. SpringWebFlux是异步的,在Controller的方法下断点根本没用,因为RequestBody走到Controller这里还没使用,数据还在Buffer中,根本没有读取,就不会走HttpMessageConverter,所以在HttpMessageConverter的实现类中下断点根本走不到,需要经过数据使用的那里理论上才会走HttpMessageConverter链。(我后来有去找过在哪调用HttpMessageConverter,没找到所谓的HttpMessageConverter链,可能需要好好了解SpringWebFlux原理才能知道在哪吧)
  2. 只有Windows和MacOS下微信小程序会有这个问题,安卓和iOS下都没有,说明大概率不是后端的问题。

抓包显露真凶

如果服务端没法看出来啥问题,那就直接从客户端入手,试试能不能看到客户端请求时body体里面带了双引号。

从网上找了找资料,发现国产的ProxyPin比较好用,于是下载使用。

地址:https://github.com/wanghongenpin/network_proxy_flutter/releases

我的电脑是M2芯片的MacOS,下载对应的包即可。

  1. 打开提示包损坏,去设置->隐私里点仍要打开即可
  2. 打开后点击最上方的锁标志,打开启用HTTPS代理,然后点安装根证书到本机,按提示安转并信任根证书。
  3. 打开微信小程序,触发问题
  4. ProxyPin中查找抓到的包,查看请求体,清楚的看到请求时前后都有引号
相关推荐
苹果醋310 分钟前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行11 分钟前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
azhou的代码园14 分钟前
基于JAVA+SpringBoot+Vue的制造装备物联及生产管理ERP系统
java·spring boot·制造
wm10431 小时前
java web springboot
java·spring boot·后端
smile-yan1 小时前
Provides transitive vulnerable dependency maven 提示依赖存在漏洞问题的解决方法
java·maven
老马啸西风1 小时前
NLP 中文拼写检测纠正论文-01-介绍了SIGHAN 2015 包括任务描述,数据准备, 绩效指标和评估结果
java
Earnest~1 小时前
Maven极简安装&配置-241223
java·maven
皮蛋很白1 小时前
Maven 环境变量 MAVEN_HOME 和 M2_HOME 区别以及 IDEA 修改 Maven repository 路径全局
java·maven·intellij-idea
青年有志1 小时前
JavaWeb(一) | 基本概念(web服务器、Tomcat、HTTP、Maven)、Servlet 简介
java·web
上海研博数据1 小时前
flink+kafka实现流数据处理学习
java