[英]Camel Spring MVC integration
我想使用Spring MVC和Camel集成服务器公开RESTful服务。 此服务将接受JSON作为输入,并且仅返回JSON输出。
主要思想-定义一个接受来自某些URI的POST请求的路由,Camel将此请求转发给Spring控制器,Spring控制器返回一些JSON响应,而Camel应该对其进行处理并返回到其他客户端。
这是我定义的路线
<camel:route>
<camel:from
uri="restlet:/url1?restletMethod=POST" />
<camel:setBody>
<camel:simple>${body}</camel:simple>
</camel:setBody>
<camel:setHeader headerName="Content-Type">
<camel:constant>{application/json}</camel:constant>
</camel:setHeader>
<camel:to uri="restlet:{springMVCUrl}?restletMethod=POST" />
</camel:route>
我从firefox Rest客户端打了Url1并发送了我的JSON,请求来自Camel到我的Spring控制器,它返回了JSON字符串。 如果我在eclipse中调试骆驼端的代码,则可以正常工作。
但是,如果我在没有调试模式的情况下运行,它将始终返回null主体
是某些同步问题,还是inout频道?
您面临的问题是Restlet生产者端点的Async
处理行为。 有关Camel异步处理以及如何使用不同组件的详细信息,请参见此处 。 路由的“从”部分调用RestletConsumer ,路由的“至”部分调用RestletProducer 。 Restlet生产者默认情况下在Async mode
下运行,在该Async mode
下它刚刚通过交换,并在完成工作(在您的情况下为外部服务调用)时填充交换。 可以在实现DefaultAsyncProducer
的RestletProducer类中对此进行验证。
public class RestletProducer extends DefaultAsyncProducer {
.......................................
......................................
@Override
public boolean process(final Exchange exchange, final AsyncCallback callback) {
RestletEndpoint endpoint = (RestletEndpoint) getEndpoint();
final RestletBinding binding = endpoint.getRestletBinding();
Request request;
try {
String resourceUri = buildUri(endpoint, exchange);
request = new Request(endpoint.getRestletMethod(), resourceUri);
binding.populateRestletRequestFromExchange(request, exchange);
} catch (CamelExchangeException e) {
// break out in case of exception
exchange.setException(e);
callback.done(true);
return true;
}
// process the request asynchronously
LOG.debug("Sending request: {} for exchangeId: {}", request, exchange.getExchangeId());
client.handle(request, new Uniform() {
@Override
public void handle(Request request, Response response) {
LOG.debug("Received response: {} for exchangeId: {}", response, exchange.getExchangeId());
try {
if (response != null) {
Integer respCode = response.getStatus().getCode();
if (respCode > 207 && throwException) {
exchange.setException(populateRestletProducerException(exchange, response, respCode));
} else {
binding.populateExchangeFromRestletResponse(exchange, response);
}
}
} catch (Exception e) {
exchange.setException(e);
}
}
});
callback.done(false);
return false;
}
调试时,输出路由跟随信息。 请注意在其上面写着“ Exchange已处理,并继续为exchangeId异步路由 ”
01:08:03.824 [qtp723059574-46] TRACE org.apache.camel.processor.Pipeline - Processing complete for exchangeId: ID-NB0629-50370-1395170917014-0-2 >>> Exchange[Message: [Body is instance of java.io.InputStream]]
01:08:03.825 [qtp723059574-46] TRACE o.a.c.p.CamelInternalProcessor - Exchange processed and is continued routed asynchronously for exchangeId: ID-NB0629-50370-1395170917014-0-2 -> Exchange[Message: [Body is instance of java.io.InputStream]]
01:08:03.831 [qtp723059574-46] TRACE org.apache.camel.processor.Pipeline - Processing exchangeId: ID-NB0629-50370-1395170917014-0-2 is continued being processed asynchronously
01:08:03.832 [qtp723059574-46] TRACE o.a.c.p.CamelInternalProcessor - **Exchange processed and is continued routed asynchronously for exchangeId**: ID-NB0629-50370-1395170917014-0-2 -> Exchange[Message: [Body is instance of java.io.InputStream]]
01:08:03.834 [qtp723059574-46] DEBUG o.a.c.c.r.DefaultRestletBinding - Populate Restlet response from exchange body: org.restlet.engine.io.UnclosableInputStream@c107903
Mar 19, 2014 1:08:03 AM org.restlet.engine.log.LogFilter afterHandle
INFO: 2014-03-19 01:08:03 0:0:0:0:0:0:0:1 - 0:0:0:0:0:0:0:1 8082 POST /context/endpoint - 200 - 66 221 http://localhost:8082 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36 -
01:08:06.251 [Restlet-1502737852] DEBUG o.a.c.c.restlet.RestletProducer - Received response: HTTP/1.1 - OK (200) - OK for exchangeId: ID-NB0629-50370-1395170917014-0-2
01:08:06.253 [Restlet-1502737852] DEBUG o.a.c.c.r.DefaultRestletBinding - Populate exchange from Restlet response header: org.restlet.virtualHost value: 344880096
01:08:06.254 [Restlet-1502737852] DEBUG o.a.c.c.r.DefaultRestletBinding - Populate exchange from Restlet response header: org.restlet.context value: org.restlet.Context@6675e3e5
01:08:06.254 [Restlet-1502737852] DEBUG o.a.c.c.r.DefaultRestletBinding - Populate exchange from Restlet response header: org.restlet.http.headers value: [[Set-Cookie: JSESSIONID=s5bnkehrfq2d1hd9mc2jz93rf;Path=/finnone-webapp], [Expires: Thu, 01 Jan 1970 00:00:00 GMT], [Content-Type: application/json;charset=UTF-8], [Transfer-Encoding: chunked], [Server: Jetty(8.1.12.v20130726)]]
01:08:06.307 [Restlet-1502737852] DEBUG o.a.c.c.r.DefaultRestletBinding - Populate exchange from Restlet response: { Your expected JSON response comes here}
Camel文档在此指出,出于可伸缩性原因,几个组件都使用此异步行为,但是可以通过在端点配置中使用synchronous=true
来强制它们以同步方式运行。 但是不幸的是,restlet生产者似乎并不支持这一点,因为我在此处的配置中看不到任何此类URI选项。 还要看看RestletComponent ,似乎对此没有支持。
在另一方面在Apache CXF成分确实有作为的URI选项列表中提及的同步调用支持在这里 。
在Camel文档中 ,给出了一个如何将Camel用作HTTP代理的示例:
<route>
<from uri="jetty:http://0.0.0.0:8080/myapp?matchOnUriPrefix=true"/>
<to uri="jetty:http://realserverhostname:8090/myapp?bridgeEndpoint=true&throwExceptionOnFailure=false"/>
</route>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.