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中查找抓到的包,查看请求体,清楚的看到请求时前后都有引号
相关推荐
paopaokaka_luck2 分钟前
[371]基于springboot的高校实习管理系统
java·spring boot·后端
以后不吃煲仔饭14 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师15 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
The_Ticker21 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
大数据编程之光43 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
爪哇学长1 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
ExiFengs1 小时前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
paj1234567891 小时前
JDK1.8新增特性
java·开发语言
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net