[英]spring-integration jdbc outbound-gateway advice for handling empty result-sets
我正在接受@gary-russel 的建議並提出一個新問題 w.r.t 這個老問題( 使用 jdbc 時出現問題:當查詢返回空結果集時出站網關)關於 spring-integration JDBC outbound-gateway calls on requests that return一個空的結果集。
我嘗試使用處理程序建議來獲取返回空數組的請求,而不是拋出異常。
你能告訴我為什么這個建議不對嗎?
<beans:beans xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans = "http://www.springframework.org/schema/beans"
xmlns:jdbc = "http://www.springframework.org/schema/jdbc"
xmlns:int = "http://www.springframework.org/schema/integration"
xmlns:int-jdbc = "http://www.springframework.org/schema/integration/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd">
<int:gateway id="getAllCustomers-Gateway"
default-request-channel="getAllCustomers"
service-interface="demo.StringInputJsonOutputGatewayMethod" />
<int:channel id="getAllCustomers" />
<int-jdbc:outbound-gateway id="getAllCustomers-OutboundGateway"
request-channel="getAllCustomers"
query="select * from Customer"
data-source="dataSource"
max-rows="0" >
<int-jdbc:request-handler-advice-chain>
<beans:bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice" >
<beans:property name="onSuccessExpressionString" value="payload ?: {} " />
<beans:property name="returnFailureExpressionResult" value="#{true}" />
<beans:property name="onFailureExpressionString" value="{}" />
</beans:bean>
</int-jdbc:request-handler-advice-chain>
</int-jdbc:outbound-gateway>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource" >
<beans:property name="driverClass" value="org.h2.Driver" />
<beans:property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" />
<beans:property name="username" value="sa" />
<beans:property name="password" value="" />
</beans:bean>
<jdbc:initialize-database data-source="dataSource" >
<jdbc:script location="classpath:/schema.sql" />
</jdbc:initialize-database>
</beans:beans>
使用此腳本初始化測試數據庫( schema.sql
:
CREATE TABLE Customer (
ID BIGINT NOT NULL AUTO_INCREMENT,
FIRST_NAME VARCHAR(30) NOT NULL,
LAST_NAME VARCHAR(30) NOT NULL,
PRIMARY KEY (ID)
);
出站網關拋出異常:
org.springframework.integration.handler.ReplyRequiredException: No reply produced by handler 'getAllCustomers-OutboundGateway', and its 'requiresReply' property is set to true.
任何建議或指示表示贊賞。
一些調試后續:
我可以看到調用了ExpressionEvaluatingRequestHandlerAdvice
來評估successExpression
但這不會改變返回結果,即使提供了成功表達式,如payload?: {}
。 不failureExpression
是因為AdviceChain運行后JdbcOutboundGateway
拋出null
結果失敗異常。
這個JdbcOutboundGateway
問題最令人驚訝的部分是方法handleRequestMessage()
確實從 JDBC 調用接收到一個空列表,這看起來完全有效,但它隨后繼續明確地將其設置為null
。
if (this.poller != null) {
...
list = this.poller.doPoll(sqlQueryParameterSource);
}
Object payload = list;
if (list.isEmpty()) {
return null;
}
我想你的意思是按原樣返回一個空列表,而不是null
,因為它默認存在於JdbcOutboundGateway
中。
null
是 AOP 通知中Joinpoint
執行的有效結果。 ExpressionEvaluatingRequestHandlerAdvice
中的邏輯是這樣的:
try {
Object result = callback.execute();
if (this.onSuccessExpression != null) {
evaluateSuccessExpression(message);
}
return result;
}
由於null
可以返回,所以只需將 go 傳遞給evaluateSuccessExpression()
即可,根本不需要它的結果。 所以,最后我們只返回null
。
這個 null 在AbstractReplyProducingMessageHandler
中查詢:
if (result != null) {
sendOutputs(result, message);
}
else if (this.requiresReply && !isAsync()) {
throw new ReplyRequiredException(message, "No reply produced by handler '" +
getComponentName() + "', and its 'requiresReply' property is set to true.");
}
您可能真的考慮將requiresReply
設置為false
以忽略查詢執行中的空列表。 我們可能會修改我們的“空列表”邏輯,但現在它直接轉換為null
: https://jira.spring.io/browse/INT-3333 。
您可以考慮實現自定義AbstractRequestHandlerAdvice
並檢查callback.execute()
結果並返回一個空列表,如您所料。
提到的ExpressionEvaluatingRequestHandlerAdvice
也是可能的,但它有點涉及從onSuccessExpression
拋出的其他選項和異常。
感謝@artem-bilan 的建議。 這似乎最終起到了作用。
將自定義建議處理程序擴展添加到ExpressionEvaluatingRequestHandlerAdvice
:
package demo;
import org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice;
import org.springframework.messaging.Message;
import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.unmodifiableList;
public class ReplaceNullWithEmptyListHandlerAdvice extends ExpressionEvaluatingRequestHandlerAdvice {
private static final List<Object> EMPTY_LIST = unmodifiableList(new ArrayList<>());
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
final Object result = super.doInvoke(callback, target, message);
return result != null ? result : EMPTY_LIST;
}
}
現在可以像這樣設置建議鏈:
<int-jdbc:outbound-gateway id="getAllCustomers-OutboundGateway"
request-channel="getAllCustomers"
query="select * from Customer"
data-source="dataSource"
max-rows="0" >
<int-jdbc:request-handler-advice-chain>
<beans:bean class="demo.ReplaceNullWithEmptyListHandlerAdvice" />
</int-jdbc:request-handler-advice-chain>
</int-jdbc:outbound-gateway>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.