簡體   English   中英

Camel REST 服務在返回 null 時拋出異常

[英]Camel REST service throws Exception when returning null

我有一個簡單的 REST 服務。 有客戶,我可以通過其 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})")

我懷疑它的 .bean() 當你返回一個null值作為新的消息體時有一個小錯誤,這使底層的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 ,即使我正在逐步執行我的代碼並看到一切按預期進行。 像您一樣,當該方法返回一個對象時一切正常,但僅在主體設置為null時才拋出此異常。

在這一點上,我認為當響應主體設置為null時,Camel 中有一些復雜的一系列事件會出錯。 單步執行代碼並沒有我希望的那么有用,所以我只是查看了響應實體的標准做法是在NO_CONTENTNOT_FOUND的情況下,並偶然發現了這篇文章 我相信 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM