camel丢失请求body问题排查

项目组要和被收购的公司做接口对接,使用camel进行集成。在使用的过程当中,我们几个小伙伴都遇到了一个相同的问题:请求request body的内容失踪了。这里贴出有问题的路由配置:

<?xml version="1.0"  encoding="UTF-8"?>
<routes xmlns="http://camel.apache.org/schema/spring"><route><from uri="rest:post:sett/pay/apply.json"/><log message="接收clivet请求, ${body}"/><setProperty name="template_code"><constant>clivet_payment_request_json</constant></setProperty><process ref="json2TemplateProcessor"/><to uri="netty-http:http://127.0.0.1:1234/****/save.json"/><!-- ?httpMethod=POST&amp;transferExchange=true --></route>
</routes>

原因是from接口后紧随的log把HttpServletRequest的InputStream给消费掉了。导致转发的请求的springmvc读不到数据。把 ${body}去掉即可解决问题。
给出我的排查过程。

排查过程

debug CamelServlet的入口方法

  1. CamelServlet先把HttpServletRequest的InputStream读出来,构成成一个InputStreamCache对象,然后写入Exchange的in字段里面。调用堆栈如下:
	  at org.apache.camel.http.common.HttpHelper.readRequestBodyFromServletRequest(HttpHelper.java:147)at org.apache.camel.http.common.DefaultHttpBinding.parseBody(DefaultHttpBinding.java:646)at org.apache.camel.http.common.HttpMessage.createBody(HttpMessage.java:101)at org.apache.camel.support.MessageSupport.getBody(MessageSupport.java:65)at org.apache.camel.http.common.DefaultHttpBinding.readBody(DefaultHttpBinding.java:193)at org.apache.camel.http.common.DefaultHttpBinding.readRequest(DefaultHttpBinding.java:118)at org.apache.camel.http.common.HttpMessage.init(HttpMessage.java:73)at org.apache.camel.http.common.HttpMessage.<init>(HttpMessage.java:39)at org.apache.camel.http.common.CamelServlet.doExecute(CamelServlet.java:274)at org.apache.camel.http.common.CamelServlet.doService(CamelServlet.java:214)at org.apache.camel.http.common.CamelServlet.service(CamelServlet.java:130)

在这里插入图片描述
2. 进入 org.apache.camel.processor.LogProcessor#process 方法这里camel会消费exchange的InputStreamCahce。
在这里插入图片描述
在这里插入图片描述
读完之后,这个流就close了,你是无法再次读出来了。至此,破案。

我们组三个小伙伴都遇到了这个问题,camel官方也意识到了这个问题。官方faq :WHY IS MY MESSAGE EMPTY?

In Camel the message body can be of any types. Some types are safely readable multiple times, and therefore do not ‘suffer’ from becoming ‘empty’. So when you message body suddenly is empty, then that is often related to using a message type that is no re-readable; in other words, the message body can only be read once. On subsequent reads the body is now empty. This happens with types that are streaming based, such as java.util.InputStream, etc.

意即如果消息体是基于流式的, 如java.util.InputStream、Reader等,是不能重复读取的。

解决方案

1 官方解决方案

camel给出的解决方案 STREAM CACHING,把inputstream缓存起来,供后续重复读。

需要增加如下配置

context.getStreamCachingStrategy().setSpoolEnabled(true);
context.getStreamCachingStrategy().setSpoolDirectory("/tmp/cachedir");
context.getStreamCachingStrategy().setSpoolThreshold(64 * 1024);
context.getStreamCachingStrategy().setBufferSize(16 * 1024);context.setStreamCaching(true);

2 去掉from节点后的${body}

${body}可以在某个processor(LogProcessor除外)消费了HttpServletRequest的Inputstream后再使用,但决不能紧跟着from节点用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/285602.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高速口相关知识

一.不通系列fpga对高速口的叫法不一样&#xff1a; artix7——GTP kintex7——GTX virtex7——GTH 二.高速口的架构基本一致————4对rx/tx对1个时钟模块&#xff08;包含4个cpll1个Qpll&#xff09; 1&#xff1a;一个高速口【一个高速bank&#xff1a;&#xff08;eg&a…

ADB:获取坐标

命令&#xff1a; adb shell getevent | grep -e "0035" -e "0036" adb shell getevent -l | grep -e "0035" -e "0036" 这一条正确&#xff0c;但是&#xff0c;grep给过滤了&#xff0c;导致没有输出 getevent -c 10 //输出10条信息…

天猫数据分析-天猫查数据软件-11月天猫平台饮料市场品牌及店铺销量销额数据分析

今年以来&#xff0c;饮料是快消品行业中少数保持稳定增长的品类之一。 11月份&#xff0c;饮料市场同样呈现较好的增长态势。根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年11月份&#xff0c;天猫平台上饮料市场的销量为2700万&#xff0c;环比增长约42%&#xf…

MLOps在极狐GitLab 的现状和前瞻

什么是 MLOps 首先我们可以这么定义机器学习&#xff08;Machine Learning&#xff09;&#xff1a;通过一组工具和算法&#xff0c;从给定数据集中提取信息以进行具有一定程度不确定性的预测&#xff0c;借助于这些预测增强用户体验或推动内部决策。 同一般的软件研发流程比…

PyTorch机器学习与深度学习

近年来&#xff0c;随着AlphaGo、无人驾驶汽车、医学影像智慧辅助诊疗、ImageNet竞赛等热点事件的发生&#xff0c;人工智能迎来了新一轮的发展浪潮。尤其是深度学习技术&#xff0c;在许多行业都取得了颠覆性的成果。另外&#xff0c;近年来&#xff0c;Pytorch深度学习框架受…

Python办公自动化全网最全干货,高效工作再不加班!

文章目录 前言Python Excel库对比一、Python xlrd 读取 操作Excel1.1 xlrd模块介绍1.2 安装xlrd模块1.3 使用介绍1.4 实战训练 二、Python xlwt 写入 操作Excel&#xff08;仅限xls格式&#xff01;&#xff09;2.1 pip安装xlwt2.2 使用xlwt创建新表格并写入2.3 xlwt 设置字体格…

性能加速包: SpringBoot 2.7JDK 17,你敢尝一尝吗 | 京东物流技术团队

前言 众所周知&#xff0c;SpringBoot3.0迎来了全面支持JDK17的局面&#xff0c;且最低支持版本就是JDK17&#xff0c;这就意味着&#xff0c;Spring社区将完全抛弃JDK8&#xff0c;全面转战JDK17。作为JAVA开源生态里的扛把子&#xff0c;Spring可以说是整个JAVA生态的风向标…

Arcgis中利用模型构建器统一栅格数据的行列号

1、统一&#xff08;X,Y) 方法&#xff1a;"数据管理工具箱"→"Projections and Transformations"→"Raster"→"Project Raster" 构建模型 这里以行列号最小的栅格&#xff08;X,Y&#xff09;为准&#xff08;其实也就是栅格数据的空…

网络编程day3作业

多进程实现TCP并发服务器 #include<myhead.h>#define PORT 8888 #define IP "192.168.125.130"void hadder(int signo) {if(signo SIGCHLD){while(waitpid(-1,NULL,WNOHANG) > 0);} }int information_exchange(int newfd,struct sockaddr_in cin) {char b…

Redis原理之网络模型笔记

目录 1. 阻塞IO 2. 非堵塞IO 3. IO多路复用 ​3.1 select 3.2 poll 3.3 epoll 4. 信号驱动IO 5. 异步IO 6. Redis是单线程还是多线程 Redis采用单线程模型&#xff0c;这意味着一个Redis服务器在任何时刻都只会处理一个请求。Redis的网络模型涉及到阻塞I/O&#xff08;Blo…

Mac managing Multiple Python Versions With pyenv 【 mac pyenv 管理多个python 版本 】

文章目录 1. 简介2. 安装2.1 brew 安装 pyenv2.2 脚本安装 3. pyenv 安装 Python4. 卸载 python5. 管理 python 1. 简介 Pyenv 是一个用于管理和切换多个 Python 版本的工具。它允许开发人员在同一台计算机上同时安装和使用多个不同的 Python 版本&#xff0c;而无需对系统进行…

STM32与Freertos入门(三)任务的创建、删除

1、串口配置 首先将串口进行配置&#xff0c;后续经常会应用&#xff0c;具体步骤点击&#xff1a;串口配置。 2、任务 创建一个任务&#xff0c;就是开辟一个空间、每个任务中都会有while&#xff08;1&#xff09;死循环。 2.1相关函数 动态创建&#xff1a;xTaskCreate…