繁体   English   中英

Camel Spring MVC集成

[英]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下它刚刚通过交换,并在完成工作(在您的情况下为外部服务调用)时填充交换。 可以在实现DefaultAsyncProducerRestletProducer类中对此进行验证。

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&amp;throwExceptionOnFailure=false"/>
 </route>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM