How to pass nulls and Exceptions to client Spring integration inbound/outbound JMS gateways?

I have a setup with an outbound JMS gateway on the client side, and an inbound JMS gateway on the server side. The client calls a service on the server side in synchronous style using these gateways.

The server side service is a find-method that returns a found object, or alternatively null if nothing could be found.

Problem is that it is not possible to pass null back to to the client, so my questions are:

  1. What is best practice to pass null back to the client?
  2. If the server-side method throws an exception, how do I pass this exception back to the client?

Regards, Christian von Wendt-Jensen

Upvotes: 1

Views: 1017

Answers (1)

Manoj Arya
Manoj Arya

Reputation: 133

Spring doesn't support idea of null payloads yet but it can throw exceptions. Set "requires-reply" attribute of your service activator to true. If you are directly consuming call on inbound gateway then you need to throw an exception, you can't return null as it will silently return and invoker thread will wait indefinitely if time-out not specified.

e.g.

If you use Service activator, then by setting "requires-reply" to true, if null reply is generated spring integration will throw ReplyRequiredException that you can send to client calling code.

To send exception on client side you can use following strategy.

Configure error channel on inbound gateway.

<int-jms:inbound-gateway request-channel="req" reply-channel="reply" error-channel="serverError" /> 

On serverError channel add a service activator to to rethrow. I usually wrap the exception in some common Exception holder class to use it on client side for payload-routing.

<int:channel id="serverError" />

<int:service-activator input-channel="serverError"  expression="new package.ExceptionWrapper(payload.cause==null ? payload : payload.cause)" /> 

On client side, use a payload router and if it is of type ExceptionWrapper then route it to some channel say 'errorChannel' where you can unwrap the exception it's holding thrown from server side. By default send payload-router reply to gateway reply channel.

<int:payload-type-router input-channel="replyRoute" default-output-channel="reply">
  <int:mapping type="package.ExceptionWrapper" channel="errorThrower" />
</int:payload-type-router>

<int:channel id="errorThrower" /> 

<int:service-activator input-channel="errorThrower" ref="exceptionHandler" method="process" />

Upvotes: 1

Related Questions