我正在接受@gary-russel 的建議,并針對回傳空結果的請求的 spring-integration JDBC outbound-gateway 呼叫這個較舊的問題( Trouble using jdbc:outbound-gateway when query returns empty result set )提出一個新問題-放。
我嘗試使用處理程式建議來獲取回傳空陣列而不是拋出例外的請求。
你能告訴我為什么這個建議是不正確的嗎?
<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 運行后引發了結果失敗null例外。JdbcOutboundGateway
這個JdbcOutboundGateway問題最令人驚訝的部分是該方法handleRequestMessage()確實從 JDBC 呼叫中接收到一個空串列,這似乎完全有效,但它接著將其顯式設定為null.
if (this.poller != null) {
...
list = this.poller.doPoll(sqlQueryParameterSource);
}
Object payload = list;
if (list.isEmpty()) {
return null;
}
uj5u.com熱心網友回復:
我想你的意思是按原樣回傳一個空串列,而不是null默認情況下在JdbcOutboundGateway.
AOP Advice 中的執行結果null是有效的。Joinpoint其中的邏輯ExpressionEvaluatingRequestHandlerAdvice是這樣的:
try {
Object result = callback.execute();
if (this.onSuccessExpression != null) {
evaluateSuccessExpression(message);
}
return result;
}
既然null可以回傳,你就去吧,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.
uj5u.com熱心網友回復:
感謝@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;
}
}
現在可以像這樣設定advicechain:
<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>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/511714.html
