[英]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中可以找到的所有內容。 這些是JsonMappingException
和JsonParseException
(盡管您可以走得更遠,並選擇其他子類)。
為了處理Camel綁定問題,我最終使用@Header
屬性作為字符串從Camel Headers進行綁定,並進行了自己的輸入驗證,解析等。這讓我拋出了自己的自定義異常,因此可以處理它們在onException
子句中。
不知道是否有更好的方法,很高興知道是否有!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.