我接受了@gary russel的建议,并打开了一个新的问题。关于spring集成的旧问题(当查询返回空结果集时使用jdbc:出站网关的问题(jdbc出站网关调用返回空结果集中的请求。
我尝试使用处理程序建议来获得返回空数组的请求,而不是抛出异常。
你能告诉我为什么这个建议不对吗?
<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
,因为来自JdbcOutboundGateway
的null
结果失败异常是在运行AdviceChain后引发的。
这个JdbcOutboundGateway
问题最令人惊讶的部分是,方法handleRequestMessage()
确实从JDBC调用中接收到了一个空列表,这似乎完全有效,但它随后将其显式设置为null
。
if (this.poller != null) {
...
list = this.poller.doPoll(sqlQueryParameterSource);
}
Object payload = list;
if (list.isEmpty()) {
return null;
}
我想您的目的是按原样返回一个空列表,而不是像默认情况下JdbcOutboundGateway
中那样返回null
。
CCD_ 13是来自AOP建议中的CCD_ 14执行的结果。ExpressionEvaluatingRequestHandlerAdvice
的逻辑是这样的:
try {
Object result = callback.execute();
if (this.onSuccessExpression != null) {
evaluateSuccessExpression(message);
}
return result;
}
由于null
是OK返回,所以您只需转到evaluateSuccessExpression()
,而不必期待它的结果。所以,最后我们只返回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;
}
}
现在可以这样设置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>