2016-11-15 31 views
2

我想在使用Camel Rest端点时记录原始的'原始'请求正文(例如JSON)。什么是正确的方法来做到这一点?如何在使用Camel Rest时记录请求负载?

我的设置(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: [email protected]。我想记录的是在绑定到POJO之前的原始JSON。

在RestConfigurationDefinition或RestDefinition中似乎没有启用“原始”请求记录的内置方式。

我可以摆脱自动JSON绑定,并手动读取HTTP Post请求的InputStream,记录和执行手动解组等,但我想保持内置绑定。

+0

如果你使用的是logback和jetty 7(也许是8),你可能会看看[logback-access](http://logback.qos.ch/access.html)。根据[Camel-Jetty文档](http://camel.apache.org/jetty.html),Camel(特别是DefaultHttpBinding)会将输入流复制到放入消息正文中的sream缓存中。从他们你可以简单地使用'.log(LoggingLevel.Debug,“$ {in.body}”)''来记录它。除此之外,Camel会将HTTP头自动复制到您可以像普通交换头一样访问的交换头。 –

+0

通过记录最初的原始请求,不能确定你的意思吗?您可以从()中记录原始有效负载。可以从Exchange头文件/属性访问HTTP头文件。你还想记录什么? –

+0

@ roman-vottner我编辑的问题包括骆驼的日志EIP以及它不会产生预期效果的事实。尽管如此,我还没有尝试过logback-access。 – ahor

回答

1

在此通过不使用REST DSL与高度复杂处理器,用于记录所述有效载荷结合I“解决”末端:

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

我同意没有办法使用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

我没有测试这个,但这似乎是在使用Jetty框架机制方面的正确答案 - 尽管必须深入挖掘核心的“Handler”机制,恕我直言,IMHO仅仅是为了获得简单的日志记录而有点超过顶端;-) – ahor