我想使用Spring和Camel集成服务器公开RESTful服务。此服务将接受JSON作为输入,并仅返回JSON输出。
主要思想-定义一个接受来自某个URI的POST请求的路由,Camel将这个请求转发给Spring控制器,Spring控制器返回一些JSON响应,Camel应该处理它并返回给rest客户端。
在这里,我定义的路线
<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客户端点击Url1并发送我的JSON,请求来自Camel到我的Spring控制器,它返回JSON字符串。如果我在camel侧调试eclipse中的代码,它将非常好地工作。
但是,如果我运行时没有调试模式,它总是返回空体。
是同步问题,还是inout频道?
发布于 2014-03-19 06:27:43
您面临的问题是Restlet生产者端点的Async处理行为。有关骆驼异步处理以及不同组件如何使用的详细信息,请参阅详细的这里。"from“部件调用RestletConsumer,"to”部分调用RestletProducer。默认情况下,Restlet生产者在Async mode中运行,它只是在那里传递交换,并且在完成工作后(在您的例子中,调用外部服务)它填充了交换。这可以在实现RestletProducer的DefaultAsyncProducer类中得到验证。
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;
}在调试路由时,将输出后续ginformation。注意:“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组件确实支持同步调用,如URI选项列表这里中提到的那样。
发布于 2014-03-19 17:49:00
在骆驼文献中,给出了一个如何将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>https://stackoverflow.com/questions/22476632
复制相似问题