I'm writing an application to support a protocol that in the same HTTP endpoint mixes SOAP messages (a POST with SOAP XML) with empty messages (a POST without body), which are not empty SOAP messages.
I tried to receive the empty messages using SimpleWebServiceInboundGateway
but I get 400 (bad request), which is reasonable because an empty body is not a valid SOAP message.
My idea (maybe is not the best) is to use Http.inboundGateway
to receive all HTTP requests and then route the messages to SimpleWebServiceInboundGateway
if they are not empty, but I'm having a problem.
If I use SimpleWebServiceInboundGateway
directly I am able to receive messages using this SoapMessageService
:
@ServiceActivator(inputChannel = SOAP_MESSAGE_SERVICE_CHANNEL_NAME)
public SoapMessage receive(SoapMessage soapMessage) {
System.out.println(soapMessage);
return soapMessage;
}
But when I put in the flow the Http.inboundGateway
before the SimpleWebServiceInboundGateway
, that service will not work anymore because:
EL1004E: Method call: Method receive(java.lang.String) cannot be found on type com.example.services.SoapMessageService
This (using String
instead of SoapMessage
) works fine:
@ServiceActivator(inputChannel = SOAP_MESSAGE_SERVICE_CHANNEL_NAME)
public String receive(String soapMessage) {
System.out.println(soapMessage);
return soapMessage;
}
But definitely I don't want to perform the conversion from String to SoapMessage by myself, specially when I know that the framework can resolve it, like when I receive the messages directly in SimpleWebServiceInboundGateway
and I process them as SoapMessage
.
So I would like to know how can I use Spring Integration in the best possible way to receive the HTTP messages as SoapMessage
in a service activator.
Thanks in advance!
The Http.inboundGateway()
has this option:
/**
* Set the message body converters to use.
* These converters are used to convert from and to HTTP requests and responses.
* @param messageConverters The message converters.
* @return the current Spec.
*/
public S messageConverters(HttpMessageConverter<?>... messageConverters) {
So, essentially you can write an HttpMessageConverter
to create a SoapMessage
from the HTTP request:
public class SoapMessageHttpConverter extends AbstractHttpMessageConverter<SoapMessage> {
private final SoapMessageFactory soapMessageFactory;
SoapMessageHttpConverter(SoapMessageFactory soapMessageFactory) {
this.soapMessageFactory = soapMessageFactory;
}
@Override
protected boolean supports(Class<?> clazz) {
return true;
}
@Override
protected SoapMessage readInternal(Class<? extends SoapMessage> clazz, HttpInputMessage inputMessage)
throws HttpMessageNotReadableException, IOException {
return soapMessageFactory.createWebServiceMessage(inputMessage.getBody());
}
@Override
protected void writeInternal(SoapMessage soapMessage, HttpOutputMessage outputMessage)
throws HttpMessageNotWritableException {
throw new UnsupportedOperationException();
}
}