Java 驼峰REST服务在返回null时引发异常

Java 驼峰REST服务在返回null时引发异常,java,rest,exception,apache-camel,http-status-code-404,Java,Rest,Exception,Apache Camel,Http Status Code 404,我有一个简单的休息服务。存在客户机,我可以通过其ID获取客户机。如果没有具有请求ID的客户机,则应返回404 not found 以下是相关部分: rest("/client") .consumes("application/json").produces("application/json") .get("{id}") .to("direct:getClient"); from("direct:getClient") .bean(clientServi

我有一个简单的休息服务。存在客户机,我可以通过其ID获取客户机。如果没有具有请求ID的客户机,则应返回404 not found

以下是相关部分:

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,并在rest路由中处理

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()
;
来自(“直接:酒吧”)
.流程(交换->{
//…最终导致此问题的服务调用。。。
//(状态代码204,主体为空)
响应响应响应响应=
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.runtimecameleexception:java.io.IOException:Stream closed
,尽管我正在逐步检查代码并看到所有过程都如预期的那样。与您一样,当方法返回一个对象时,一切都正常工作,但只有当body设置为
null
时才会抛出此异常

此时,我发现当响应主体设置为
null
时,Camel中出现了一系列复杂的错误事件。逐步浏览代码并不像我希望的那样有用,所以我只是查找了在
无内容
未找到
的情况下响应实体的标准做法,然后偶然发现。我相信Camel与转换器的工作方式相同,并且需要某种类型的对象,因此我只是对代码进行了如下修改:

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

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

只是为了添加一个特定场景,当引发类似错误时,根本原因是无效的Json

考虑到这个具体例子:

 String tempDate = yourExchangeObject.getIn().getBody(String.class);
 JSONObject inputJson = new JSONObject(tempDate); //Exception

您使用哪种骆驼版本?您在rest dsl中使用什么Camel组件作为HTTP?2.18.0和Camel servletOk。。。2.18.0中似乎有一个bug。我降到了2.17.3,效果很好。这是一个严重的问题,我将创建一个测试并报告它。我发现了错误并记录了一张罚单:啊,谢谢!我本来打算今天就这么做:)这是有道理的。但是,它也不起作用,但错误稍有不同:“org.apache.camel.language.bean.RuntimeBeanExpressionException:未能在null上调用方法:getClient(${header.id}),原因是:org.apache.camel.RuntimeCamelException:java.io.IOException:Stream closed”。这条消息似乎说clientService为null(“on null”),但情况绝对不是这样,因为当getClient返回非null结果时,一切都正常。