我想在使用Camel Rest端点时记录原始的'原始'请求体(例如JSON)。这样做的正确方法是什么?
我的设置(RouteBuilder)如下所示:
restConfiguration().component("jetty")
.host(this.host)
.port(this.port)
.contextPath(this.contextPath)
.bindingMode(RestBindingMode.json);
rest("myService/").post()
.produces("application/json; charset=UTF-8")
.type(MyServiceRequest.class)
.outType(MyServiceResponse.class)
.to(SERVICE_CONTEXT_IN);
from(SERVICE_CONTEXT_IN).process(this.serviceProcessor);
我的问题是,使用这种方法存储请求作为Exchange属性的机制“太晚了”,任何处理器在路由中都太晚了,即绑定已经发生并消耗了请求。此外,CamelHttpServletRequest的InputStream已被读取且不包含任何数据。
使用日志EIP的第一个地方就在单个处理器之前:
from(SERVICE_CONTEXT_IN).log(LoggingLevel.INFO, "Request: ${in.body}")
.process(this.serviceProcessor);
但此时${in.body}
已经是MyServiceRequest
的一个实例。上面添加的日志只会产生Request: x.y.z.MyServiceRequest@12345678
。我想记录的是绑定到POJO之前的原始JSON。
似乎没有内置的方法可以在RestConfigurationDefinition和RestDefinition中启用“原始”请求的记录。
我可以摆脱自动JSON绑定并手动读取HTTP Post请求的InputStream,记录并在专用处理器中执行手动解组等,但我想保留内置绑定。
答案 0 :(得分:2)
我同意使用Camel Rest端点无法记录原始请求(我假设您指的是在任何自动绑定之前有效负载通过线路)。
但考虑到Roman Vottner,您可以按如下方式更改restConfiguration()
:
restConfiguration().component("jetty")
.host(this.host)
.port(this.port)
.componentProperty("handlers", "#yourLoggingHandler")
.contextPath(this.contextPath)
.bindingMode(RestBindingMode.json);
您的#yourLoggingHandler
需要在注册表中注册并实施org.eclipse.jetty.server.Handler
。请参阅Jetty文档http://www.eclipse.org/jetty/documentation/current/jetty-handlers.html#writing-custom-handlers编写自定义处理程序。
答案 1 :(得分:1)
最后,我通过不使用REST DSL绑定和高度复杂的处理器来记录有效负载来解决这个问题:
restConfiguration().component("jetty")
.host(this.host)
.port(this.port)
.contextPath(this.contextPath);
rest("myService/").post()
.produces("application/json; charset=UTF-8")
.to(SERVICE_CONTEXT_IN);
from(SERVICE_CONTEXT_IN).process(this.requestLogProcessor)
.unmarshal()
.json(JsonLibrary.Jackson, MyServiceRequest.class)
.process(this.serviceProcessor)
.marshal()
.json(JsonLibrary.Jackson);
所有requestLogProcessor
所做的就是将in
正文作为InputStream
读取,获取并记录字符串,并最终传递它。
答案 2 :(得分:0)
您可以通过以下方式解决此问题:
RestBindingMode
并按原样记录传入的请求字符串。 ObjectMapper
将JSON字符串转换为IN类型对象。 在路由结束时,将java对象转换为JSON并将其放入exchange out主体,因为我们关闭了RestBindingMode。
rest("myService/").post()
.bindingMode(RestBindingMode.off)
.to(SERVICE_CONTEXT_IN);
答案 3 :(得分:0)
在我的情况下,streamCaching
之所以成功,是因为Stream
仅可读一次。因此,我可以登录,但无法再转发尸体。我希望这可能对某人有帮助