2017-09-19 73 views
2

我有一個http網關調用,偶爾會返回503錯誤。我想在該呼叫周圍配置retry advice,但我不想爲每個錯誤都做這個,只是503s。Spring集成消息流中的條件重試通知?

<int-http:outbound-gateway ... errorHandler="..."> 
    <int-http:request-handler-advice-chain> 
     <int:retry-advice max-attempts="3" /> 
    </int-http:request-handler-advice-chain> 
</int-http:outbound-gateway> 

我已經有一個自定義的錯誤處理程序配置了過濾器的狀態(例如:404),我不想當作錯誤,但我沒有看到一個明顯的方式來控制的建議是如何應用基於我可以在錯誤處理程序中做什麼。 This question涉及相同的問題,但答案並未解釋如何控制建議行爲或在錯誤處理程序級別重新發出請求。是否有特定的異常類型拋出?

編輯:例如基於答案:

<bean id="spelParser" class="org.springframework.expression.spel.standard.SpelExpressionParser" /> 

<int-http:outbound-gateway ...> 
    <int-http:request-handler-advice-chain> 
     <bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice"> 
      <property name="retryTemplate"> 
       <bean class="org.springframework.retry.support.RetryTemplate"> 
        <property name="retryPolicy"> 
         <bean class="org.springframework.retry.policy.ExpressionRetryPolicy"> 
          <constructor-arg index="0" type="org.springframework.expression.Expression" value="#{spelParser.parseExpression('cause.statusCode.value() == 503')}" /> 
          <property name="maxAttempts" value="3" /> 
         </bean> 
        </property> 
        <property name="backOffPolicy"> 
         <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy"> 
          <property name="initialInterval" value="1000" /> 
          <property name="multiplier" value="2" /> 
         </bean> 
        </property> 
       </bean> 
      </property> 
     </bean> 
    </int-http:request-handler-advice-chain> 
</int-http:outbound-gateway> 

回答

0

那麼,對於情況下,當你有一個HttpServerErrorException但想通過statusCode從別人區別開來,不重試,我會建議採取看看進入:

* Subclass of {@link SimpleRetryPolicy} that delegates to super.canRetry() and, 
* if true, further evaluates an expression against the last thrown exception. 
* 
* @author Gary Russell 
* @since 1.2 
* 
*/ 
@SuppressWarnings("serial") 
public class ExpressionRetryPolicy extends SimpleRetryPolicy implements BeanFactoryAware { 

您的表達可以像:

expression="statusCode.value() == 503" 

UPDATE

啊!我懂了。由於ExpressionRetryPolicy使用TemplateParserContext您的表達式肯定必須與#{statusCode.value() == 503}一樣。但同時它將在bean工廠初始化期間進行評估。我建議你做這樣的事情:

<bean id="spelParser" class="org.springframework.expression.spel.standard.SpelExpressionParser"/> 

,並在ExpressionRetryPolicy bean定義做:

<constructor-arg index="0" type="org.springframework.expression.Expression" 
       value="#{spelParser.parseExpression('statusCode.value() == 503')}" /> 

爲了克服衝突。

+0

要定製策略,您需要將建議作爲''('RequestHandlerRetryAdvice')提供,併爲自定義策略注入一個自定義的'RetryTemplate'。 –

+0

我想我看到了如何連接ExpressionRetryPolicy。 (因爲spring-integration:4.3.12.RELEASE只抓取spring-retry:1.1.x,而不是引入該類的新版本1.2,所以我必須分別引入該依賴項。)但是,出現錯誤時啓動,因爲它無法解析表達式。 ('EL1008E:在'org.springframework.beans.factory.config.BeanExpressionContext'類型的對象上找不到屬性或字段'$ statusCode' - 可能不公開?')我試過的SPEL是'expression =「#{$ statusCode.value()== 503}「'。 –

+0

???這不是SpEL。你必須指定'運行時表達式'。我已經告訴過你了:'expression =「statusCode.value()== 503」'。你試圖做的就是調用'bean factory initialization expression',但實際上並不是運行時。無論如何''''符號也是錯誤的... –