简体   繁体   English

Camel Spring MVC集成

[英]Camel Spring MVC integration

I want to expose RESTful service using Spring MVC and Camel integration server. 我想使用Spring MVC和Camel集成服务器公开RESTful服务。 This service will accept JSON as an input and return JSON output only. 此服务将接受JSON作为输入,并且仅返回JSON输出。

Main Idea - define a route which accepts POST request from some URI, the Camel forwards this request to Spring controller, Spring controller return some JSON response and Camel should process it and return to the rest client. 主要思想-定义一个接受来自某些URI的POST请求的路由,Camel将此请求转发给Spring控制器,Spring控制器返回一些JSON响应,而Camel应该对其进行处理并返回到其他客户端。

Here the route I am defining 这是我定义的路线

<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>

I hit Url1 from firefox Rest client and send my JSON, request comes from Camel to my Spring controller and it return the JSON string. 我从firefox Rest客户端打了Url1并发送了我的JSON,请求来自Camel到我的Spring控制器,它返回了JSON字符串。 If I debug the code in eclipse on camel side, it works absolutely fine. 如果我在eclipse中调试骆驼端的代码,则可以正常工作。

But if I run without debug mode it always return null body 但是,如果我在没有调试模式的情况下运行,它将始终返回null主体

Is it some synch issue, or inout channel? 是某些同步问题,还是inout频道?

The issue you are facing is that of Async processing behaviour of Restlet producer endpoint. 您面临的问题是Restlet生产者端点的Async处理行为。 For detailed information on Camel Asynchronous processing and how different components use that is detailed here . 有关Camel异步处理以及如何使用不同组件的详细信息,请参见此处 The "from" part invokes a RestletConsumer and the "to" part of the route invokes a RestletProducer . 路由的“从”部分调用RestletConsumer ,路由的“至”部分调用RestletProducer Restlet producer by default runs in Async mode where it is just passed the exchange and on completing the work (in your case call to external srvice) it populates the exchange. Restlet生产者默认情况下在Async mode下运行,在该Async mode下它刚刚通过交换,并在完成工作(在您的情况下为外部服务调用)时填充交换。 This can be verified in the RestletProducer class which implements DefaultAsyncProducer 可以在实现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;
    }

While debugging the route followin ginformation is outputted. 调试时,输出路由跟随信息。 Note where it says " Exchange processed and is continued routed asynchronously for exchangeId " 请注意在其上面写着“ 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 documents states here that several component use this async behaviour for scalability reasons but they can be forced to behave in synchronous manner by using synchronous=true in endpoint configuration. Camel文档在此指出,出于可伸缩性原因,几个组件都使用此异步行为,但是可以通过在端点配置中使用synchronous=true来强制它们以同步方式运行。 However unfortunately the restlet producer does not seem to be supporting this, as I cannot see any such URI option in their configuration here . 但是不幸的是,restlet生产者似乎并不支持这一点,因为我在此处的配置中看不到任何此类URI选项。 Also having a look at the RestletComponent there seems to be no support for this. 还要看看RestletComponent ,似乎对此没有支持。

On the other hand the Apache CXF component does have support for synchronous calls as mentioned in the list of URI options here . 在另一方面在Apache CXF成分确实有作为的URI选项列表中提及的同步调用支持在这里

In the Camel documentation , an example is given how Camel can be used as a HTTP proxy: 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