返回null时,Camel REST服务抛出异常

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了返回null时,Camel REST服务抛出异常相关的知识,希望对你有一定的参考价值。

我有一个简单的REST服务。有客户,我可以通过其ID获得客户。如果没有客户端具有所请求的ID,则应返回未找到的404。

这是相关部分:

rest("/client")
    .consumes("application/json").produces("application/json")
    .get("{id}")
        .to("direct:getClient");

from("direct:getClient")
    .bean(clientService, "getClient(${header.id})")
     .choice()
        .when(simple("${body} == null"))
            .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(404));

当找到客户端时,一切都很好,但是,当找不到客户端并且clientService返回null时,我得到以下堆栈跟踪:

org.apache.camel.RuntimeCamelException: java.io.IOException: Stream closed
    at org.apache.camel.http.common.HttpMessage.createBody(HttpMessage.java:74)
    at org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:47)
    at org.apache.camel.processor.CamelInternalProcessor$StreamCachingAdvice.after(CamelInternalProcessor.java:799)
    at org.apache.camel.processor.CamelInternalProcessor$StreamCachingAdvice.after(CamelInternalProcessor.java:767)
    at org.apache.camel.processor.CamelInternalProcessor$InternalCallback.done(CamelInternalProcessor.java:246)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:573)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:542)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)

我无法想出这个。从bean方法调用返回null应该是可能的,对吧?

答案

尝试使用变通方法

.setBody().method(clientService, "getClient(${header.id})")

当你将null值作为新的消息体返回时,我怀疑它的.bean()有一个小错误,它欺骗了底层的HttpMessage,认为消息体还没有初始化,因此你得到那个流错误读取再次流。

另一答案

我认为,如果在bean中找不到clientid并在休息路径中处理,则可以抛出新异常SomeClassException的主要思想

public class SomeClassException  extends Exception {
    private static final long serialVersionUID = 2542653496302641967L;    
    public SomeClassException() {
    }    
    public SomeClassException(String arg0) {
        super(arg0);
    }
}

你的路线:

                rest("/client/")
                .consumes("application/json").produces("application/json")
                .get("{id}")
                    .to("direct:getClient");

                onException(SomeClassException.class) .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(404)).handled(true);

                from("direct:getClient")
                .bean(clientService, "getClient(${header.id})")
                ;
另一答案

我在路径上返回NO_CONTENT时遇到了类似的问题,该方法可以选择返回一个对象,具体取决于是否有任何排队。代码的结构如下:

rest("/foo")
    .get("/bar").route().to("direct:foo").endRest()
;

from("direct:bar")
    .process(exchange -> {
        // ... service calls that eventually resulted in this ...
        //       (status code of 204 and a body of null)
        ResponseEntity responseEntity = 
exchange.getIn().getBody(ResponseEntity.class);
        exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, responseEntity.getStatusCodeValue());
        exchange.getIn().setBody(responseEntity.getBody());
    })
    .marshal().json(JsonLibrary.Jackson)
;

我遇到了同样的错误,org.apache.camel.RuntimeCamelException: java.io.IOException: Stream closed,即使我正在踩着我的代码并按预期看到所有进程。和你一样,当方法返回一个对象时,一切正常,但只有当body设置为null时才抛出此异常。

在这一点上,我认为当响应体设置为null时,Camel中存在一些复杂的事件。单步执行代码并不像我希望的那样有用,所以我只是查看了响应实体的标准做法是在NO_CONTENTNOT_FOUND的情况下,偶然发现了this post。我相信Camel以与转换器相同的方式工作并且需要某种类型的对象,所以我只修改了我的代码:

exchange.getIn().setBody(responseEntity.getBody() == null ? "" : responseEntity.getBody());

因此,消息中仍然没有正文返回给客户端,并且没有更多的IOException: Stream closed错误。

以上是关于返回null时,Camel REST服务抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

在clickhouse中,投射失败时如何返回null而不是抛出异常?

Apache Camel 的 REST 端点

Apache Camel JMS - 异常未通过请求/回复返回给调用者

Find() 和 First() 抛出异常,如何改为返回 null?

如何在 Apache Camel 中定义要通过 ref 抛出的异常

Jersey REST 服务抛出超时异常