我必须自定义项目的错误处理。如果出现错误,根据错误类型,我想将其发送到不同的队列。
但是,在根据类型将它发送到队列之前,我们在异常消息中进行了一些转换以及将对象转换为String(我为其使用transformer
)以便队列可以具有将对象值作为消息文本,以便我们可以轻松跟踪。
现在的问题是,在将对象转换为String或发生任何其他错误(特定于代码)期间,服务开始抛出异常而没有注册错误通道。
此错误处理代码针对多个组件进行了推广,因此即使在转换中也会出现任何故障。我想将异常传递给Error Transformer
,将其传递给Error Queue
。
错误的XML配置是:
<int:transformer id = "errorTransformer" input-channel="errorsDest"
ref="exceptionTransformer" output-channel="errors" />
<bean id="exceptionTransformer"
class="com.commons.spring.integration.error.ErrorTransformer">
</bean>
<int-jms:outbound-channel-adapter id ="errorQueueAdapter"
explicit-qos-enabled="${jms.qos.enabled}"
auto-startup="${jms.connect}" channel="errors" pub-sub-domain="false"
connection-factory="connectionFactory" destination-name="${error}" />
@Transformer
public Message<String> handleError(MessagingException message) {
headers.put("stacktrace", ExceptionUtils.getStackTrace(message));
headers.put("serviceCausedTheException", EnvironmentResolver.getService());
Message<?> failedMessage = message.getFailedMessage();
Object msgPayload = failedMessage.getPayload();
String payload = "";
try {
if (msgPayload instanceof String)
payload = (String) failedMessage.getPayload();
else if (msgPayload instanceof MyObject)
payload = XMLMarshallingUtil.objectToXml((MyObject) msgPayload);
} catch (Exception e) {
payload = msgPayload.toString();
headers.put("Object Conversion Exception Occurred in Error Transformer",
e.getMessage());
}
Message<String> parsed = MessageBuilder.withPayload(payload).copyHeaders(headers).
copyHeaders(message.getFailedMessage().getHeaders()).build();
return parsed;
}
现在,由于此Transformer
期望Messaging Exception Object
,因此为了将消息从其他变换器转发到Error Transformer
,我需要传递Messaging Exception Object
。使用MessageChannel.send
方法,我只能传递消息对象。请建议
下面是我的另一个变换器代码,我希望将消息转发到错误队列
public Message<MyObject> handleError(MessagingException message) {
Message<MyObject> messageMyObject = null;
try {
Object obj = message.getFailedMessage().getPayload();
MyObject styleML = null;
if (obj instanceof String) {
String temp = (String) obj;
if (temp != null && temp.contains("MyObject"))
styleML = XMLMarshallingUtil.xmlToObject(temp, MyObject.class);
} else if (obj instanceof MyObject) {
styleML = (MyObject) obj;
}
String serviceName = EnvironmentResolver.getService();
Throwable t = ExceptionUtils.getRootCause(message.getCause());
if (t == null)
t = message.getCause();
String userComment = "Exception Occurred";
String sysComment = t.getMessage();
MyObject= MyObjectUtils.addMessageEventToMyObject(sysComment, userComment, styleML, serviceName, ProcessState.IN_ERROR);
messageMyObject = MessageBuilder.withPayload(styleML).copyHeaders(message.getFailedMessage().getHeaders()).build();
} catch (Exception e) {
errorsDest.send(MessageBuilder.withPayload(message).build());
}
return messageStyleML;
}
答案 0 :(得分:1)
右。频道与发送和接收方法签订Message
合同。但是每封邮件都有payload
。在您的情况下handleError
接受MessagingException
payload
的邮件。如果对errorChannel
进行错误处理,当任何端点抛出异常时,它将被MessagingException
包围failedMessage
并进一步包含ErrorMessage
。
因此,如果您想直接向频道发送内容,即使它是Exception
,您需要将其与Message
一起包装。它可能是MessageBuilder
的结果。
从另一方面,Spring Integration的方法调用原则允许您对方法参数具有任何所需的灵活性。在您的情况下,handleError
方法接受MessagingException
,这是将消息的有效负载映射到方法参数的默认策略。
希望我理解正确...
<强>更新强>
关于如何避免向两个频道发送消息的第二个问题。
我建议最简单的方法:
<transformer>
更改为<service-activator>
。 (Fom方法调用的观点与它们相似。)errorsDest.send
添加return null;
之后。 Transformer
不允许返回null
。 ServiceActivator
默认允许它。在这种情况下,您的主流将停止。