I have the following configuration:
The first interceptor is basically a transformer. It takes an external message format, e.g.:
<!-- Base Gateway Message Channel -->
and extracts the headers and payload and converts the incoming message to a SI Message format.
The second interceptor parses the payload as a JSON message and extracts a 'type' attribute in the message payload that is used in routing.
With both of these interceptors, if the message format is incorrect (bad xml, missing fields, bad json, etc) then the message is not recoverable and there is no point in having the jms provider redeliver it. I just need to log the event and drop it on the floor.
Initially I had the interceptors return NULL if they could not process the message. This, however, was causing rollback. The message channel docs say:
So I changed the code to throw a RuntimeException instead of returning null in my interceptors. However, that exception is still bubbling all the way up to the message listener container and the message is still being rolled back.
Send a Message to this channel. May throw a RuntimeException for non-recoverable errors.
The rest of my message processing takes place in a chain:
Here I check for incoming duplicate messages (in the db) and then route them to the appropriate channel for processing.
<!-- Throw away duplicate messages -->
<!-- Route messages to appropriate channels for handling -->
<integration:router ref="jsonMessageTypeRouter" default-output-channel="unroutableMessageChannel"/>
Is there a better way to handle these error conditions? Can I just make them Transformers that return NULL in the case that they can't process the message (will this trigger a redelivery as well)?
I certainly want exceptions (such as temporary db access) that are recoverable to trigger message delivery but I don't want to waste my time when repeated attempts to reprocess the message will never succeed.