簡體   English   中英

如何使用Camel REST DSL處理來自傑克遜綁定的異常?

[英]How to handle exceptions from jackson binding with Camel REST DSL?

我正在使用Camel 2.14.1構建一些RESTful服務,這些服務使用Camel REST DSL的Jackson json綁定功能。 這很好用,但是當綁定期間發生問題時,我希望能夠向客戶端發送自定義響應。

例如,如果將輸入字符串值轉換為整數時引發NumberFormatException ,因為客戶端錯誤地發送了不是數字的字符。 該異常不是Jackson特定的異常,因此我無法捕獲到它以綁定失敗消息來答復客戶端,因為它可能是合法的內部錯誤。

同樣,我想捕獲json到POJO的入站綁定期間引發的任何其他異常,並以類似的方式處理這些異常,至少要通知客戶端其有效負載無效。

由於這些都是在我的代碼“上方”處理的,因此我看不到如何輕松處理此類錯誤,因為這些錯誤都是在我無法控制的庫中處理的。 我正在使用Camel的onException子句來處理我自己的異常,所以我知道這一點,只是不確定如何確切地實現我所需要的...

最糟糕的情況是,我想我可以將每個客戶輸入作為字符串並自己綁定它,但這似乎不符合傑克遜的觀點。

tl; dr:Camel中是否有某種模式可以讓我在使用REST DSL從Jackson進行POJO綁定失敗時返回自定義響應?

編輯 -這是一些偽代碼來說明我正在嘗試做的事情:

class errorHandler {

  void handleException(Exchange exchange, @ExchangeException Exception exception) {

    if (myException.class.isAssignableFrom(exception.getClass())) {
      // Set exchange body and response code header
      // This works as expected, though could probably do this more nicely
    }

    else if (camelBindingOrJacksonBindingException) {
      // Some other custom handling like above, but specific for these exception types
    }

    else {
      // Generic catch all with generic error response body
      // This also works fine
    }
  }
}

目前,我最終在最后的else塊中捕獲到綁定/傑克遜異常,這就是我要避免的事情,因為對於客戶端來說,知道他們的輸入無效是非常有用的。 這似乎等同於下面的isaac.hazan的答案。

這樣做的問題是,我找不到Jackson綁定異常是否具有我可以捕獲的父類,所有此類可能異常的列表,或無法分辨出它來自綁定的方式。

第二個問題是,當Camel希望通過類似@Header int number的方法的綁定注釋中的@Header int number真正來自Camel或我自己的代碼時,我無法分辨駱駝綁定異常(例如NumberFormatException 非常不願意捕獲任何舊的NumberFormatException因為如果進一步的內部更改可能引發此錯誤,我最終將返回錯誤的響應。 是否有某種方法可以找出異常的來源(是否在綁定時)?

我的一個應用程序中遇到了類似的問題。 我通過為每個異常類型配備專用處理器和方法來解決了該問題。

例如,您可能具有以下2個處理程序,一個處理程序是特定的異常,另一個處理程序是任何其他異常:

    <onException id="handleAmazonServiceException">
        <exception>com.amazonaws.AmazonServiceException</exception>
        <handled><constant>true</constant></handled>
        <bean ref="errorHandlerProcessor" method="handleAmazonServiceException" />
        <setHeader headerName="CamelFileName">
            <simple>{{local.failed.records.dir}}/${header.S3Prefix}/${date:now:yyyy-MM-dd}/${header.failedRecordFileName}</simple>
        </setHeader>
        <to id="failedRecordsFile" uri="ref:s3FailedRecordsEndpoint" />
    </onException>

    <onException id="handleGeneralException">
        <exception>org.apache.camel.CamelExecutionException</exception>
        <exception>java.lang.Exception</exception>
        <handled><constant>true</constant></handled>
        <bean ref="errorHandlerProcessor" method="handleGeneralException" />
        <setHeader headerName="CamelFileName">
            <simple>{{local.failed.records.dir}}/${header.S3Prefix}/${date:now:yyyy-MM-dd}/${header.failedRecordFileName}</simple>
        </setHeader>
        <to id="failedRecordsFile" uri="ref:s3FailedRecordsEndpoint" />
    </onException>

上面的鍵是“ errorHandlerProcessor” bean,它負責處理任何類型的異常。 這是一種從一個地方處理所有錯誤的簡單方法。

看起來像這樣:

@Service(value = "errorHandlerProcessor")
public class ErrorHandlerProcessor
{
// General handler
public void handleGeneralException(Exchange exchange)
{
    Throwable caused = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
    logger.error("An unexpected error camel error occurred:" + caused.getMessage());
    logger.debug("Caught exception within the camel engine:", caused);
    ...
}

//AmazonClientException handler
public void handleAmazonClientException(Exchange exchange)
{
    AmazonClientException caused = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, AmazonClientException.class);
    StringBuffer errorMessage = new StringBuffer();
    errorMessage.append("AmazonClientException,AWS communication problem, Error Message: " + caused.getMessage());
    ...
}
}

最后,我最終將Camel onException子句用於在Jackson的javadoc中可以找到的所有內容。 這些是JsonMappingExceptionJsonParseException (盡管您可以走得更遠,並選擇其他子類)。

為了處理Camel綁定問題,我最終使用@Header屬性作為字符串從Camel Headers進行綁定,並進行了自己的輸入驗證,解析等。這讓我拋出了自己的自定義異常,因此可以處理它們在onException子句中。

不知道是否有更好的方法,很高興知道是否有!

暫無
暫無

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

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