Java Apache Camel REST端点不返回最终正文
我已经声明了一个REST端点,它使用Java Apache Camel REST端点不返回最终正文,java,spring-boot,jackson,apache-camel,Java,Spring Boot,Jackson,Apache Camel,我已经声明了一个REST端点,它使用direct调用另一个路由。在第二条路径的末尾,我记录了主体,但返回到浏览器的不是同一主体 下面是一个复制该行为的小示例(我使用ApacheCamel和Spring Boot): @组件 公共类EntidadeRoute扩展RouteBuilder{ @凌驾 public void configure()引发异常{ restConfiguration().bindingMode(json); 其余(“/entidade”) .get(“/{id}”) 。至(“
direct
调用另一个路由。在第二条路径的末尾,我记录了主体,但返回到浏览器的不是同一主体
下面是一个复制该行为的小示例(我使用ApacheCamel和Spring Boot):
@组件
公共类EntidadeRoute扩展RouteBuilder{
@凌驾
public void configure()引发异常{
restConfiguration().bindingMode(json);
其余(“/entidade”)
.get(“/{id}”)
。至(“直接:通过id进行搜索”);
发件人(“直接:按id搜索”)
.routeId(“按id搜索”)
.setProperty(“idEntidade”,简单(${header.id}”))
.pollEnrich(“文件:files/mock/dados?noop=true&幂等元=false”)
.unmarshal().json(JsonLibrary.Jackson)
.split(jsonpath($))
.filter(jsonpath(“$[?(@.id==${property.idEntidade})]”)
.marshal().json(JsonLibrary.Jackson)
.log(“${body}”);
}
}
我在浏览器中使用URL调用它:
http://localhost:8080/camel/entidade/1
在文件夹files/mock/dados
中,我有一个名为entidades.json
的文件,其中有一个json数组(见下文)
我知道拆分和筛选器正在工作,因为我正在最后一行代码中记录正文,这是日志中显示的内容:
2021-04-28 18:15:15.707信息3905542---[nio-8080-exec-1]按id搜索:{“id”:“1”,“tipo”:“PF”,“nome”:“João Maria”}
但这是返回到浏览器的内容(即entidades.json
文件的确切内容):
[{“id”:“1”,“tipo”:“PF”,“nome”:“João Maria”},{“id”:“2”,“tipo”:“PF”,“nome”:“Maria João”},{“id”:“4”,“tipo”:“PF”,“nome”:“JoséSouza”}]
为什么记录的正文与浏览器中显示的正文不同,并修复它
PS:如果我删除那些封送和解封送调用,我会在浏览器中看到以下错误:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:找不到类org.apache.camel.component.file.FileBinding的序列化程序,也找不到创建BeanSerializer的属性(为了避免异常,请禁用空bean上的SerializationFeature.FAIL_)(通过引用链:org.apache.camel.component.file.GenericFile[“binding”])
如果没有输入文件,并且知道您调用的具体URI(包括path变量
{id}
的给定值),我只能怀疑以下一些问题:
- 在GET通话结束时,您是否提供了id
- 为什么要转换JSON
- 你测试了正确的分割吗?你又来了吗
- 是否要记录每条消息
剩余端点 您将端点指定为
GET/entidada/{id}
。
{id}
是一个路径变量
因此,假设您使用1作为ID调用GET/entidata/1
。
然后您的JSON文件被轮询(读取),解组到
JSON解组/封送
这些unmarshal
和marshal
方法要么用于在不同的数据格式之间转换,要么用于从数据表示转换为Java对象(POJO)(如果它们在内部使用)(例如,传递给处理器Bean等)
我假设文件dados
包含JSON格式的文本数据。
因此,您只需将此文本读入(文本!)消息体(如文本消息、比较JMS等)并使用它:(a)按JSON路径拆分,(b)按JSON路径筛选,(c)记录此JSON结果,(d)将其作为HTTP响应发送回调用客户端(例如,您的浏览器)
分裂发生了什么?
在此之后,您尝试拆分(假设您有一个JSON数组):
//传入:
//一条丰富的消息,在正文中:包含4个元素的JSON数组
.split(jsonpath($)//您希望输出什么?
//在这里,通常应该使用“.end”DSL方法结束拆分
.filter(jsonpath(“$[?(@.id==${property.idEntidade})])//JSON主体的每个数组元素都与id匹配,例如1
我将您的HTTP响应(JSON数组中有4个人)填充到了online中。对$
的评估不是分割,而是单个元素(在结果数组中):与原始数组完全相同(有4个人)
- 为什么文件没有拆分成4条消息,每条消息包含一个person对象
- 因为JSON路径
只表示根元素$
.split()
之后有一个.end()
,它会再次聚合它们。
你忘了。我想这也是一个问题
过滤器按预期工作 之后,您根据剩余的给定id进行筛选:
.filter(jsonpath(“$[?(@.id==${property.idEntidade})]”)`
这将导致记录的元素:
{“id”:“1”,“tipo”:“PF”,“nome”:“João Maria”}
过滤器工作成功:只留下一个id为1
的过滤器
骆驼登陆
日志EIP
将.log()
添加到路由链时,这意味着您正在使用。在其文档中,给出了警告提示:
使用流式消息记录消息正文:
如果消息体是基于流的,那么记录消息体可能会导致消息体随后为空。看这个。对于流式消息,您可以使用流式缓存来允许记录消息正文,并能够在之后再次读取消息正文
因此,当使用它记录基于流的消息体时,空日志消息可能是由副作用引起的
测井方法的差异
第节解释:
log DSL更轻,用于记录人类日志,例如开始做…代码>等
下面的示例(根据您的休息路线调整)说明了其用法:
rest(“/