Reputation: 110
We are using Apache CXF for hosting webservice. I have a basic question
Is it possible to get the soap message/payload inside actual webservice method? This webservice will save the values passed to it in database and at the same time we want to save the actual XML request/repsonse(payload) in database.
I have tried Handlers/Interceptors, I'm able to see the SOAP message there. But I want the XML payload in webservice method so that I can preform necessary action and save the payload to database.
Upvotes: 1
Views: 5967
Reputation: 77
it's been a long time since this question was asked but in case anyone would have the same issue:
the idea is to use the spring context as it's larger than the interceptor context
you need to register progrmmatically the XML request as a spring bean and then get it in your web service method
PS: both your interceptor and web service implementor must implement the ApplicaionContextAware interface
here is what I did and it worked for me:
in your interceptor :
@Component
public class XmlInInterceptor extends AbstractPhaseInterceptor<Message> implements ApplicationContextAware{
private static final String BEAN_NAME = "yourBeanName";
private ConfigurableApplicationContext context;
private DefaultSingletonBeanRegistry registry;
public XmlInInterceptor() {
super(Phase.PRE_PROTOCOL);
}
@Override
public void handleMessage(final Message message) throws Fault {
try {
// get the SOAP message as String
final SOAPMessage soapMessage = message.getContent(SOAPMessage.class);
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
soapMessage.writeTo(byteArrayOutputStream);
final String encoding = (String) message.get(Message.ENCODING);
final String xmlRequest = new String(byteArrayOutputStream.toByteArray(), encoding);
//here is the fun part: here where you need to register the bean in runtime
SingletonBeanRegistry registry = context.getBeanFactory();
// you must check if the bean is already registered and destroy it
// otherwise the registerSingleton will fail
if(registry.containsSingleton(BEAN_NAME)){
registry.destroySingleton(BEAN_NAME);
}
registry.registerSingleton(BEAN_NAME, xmlRequest);
} catch (final Exception e) {
logger.error(e.getMessage(), e);
throw new Fault(e);
}
}
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
context = (ConfigurableApplicationContext) applicationContext;
registry = (DefaultSingletonBeanRegistry) context.getBeanFactory();
}
in your web service method:
public class MyWebServiceImpl implements MyWebService, ApplicationContextAware {
@Override
public Response myWebMethod(MyParams params) {
//get the XML request as classic spring bean access
final String xmlRequesteXML = applicationContext.getBean("xmlRequest", String.class);
//custom code here
}
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
}
Upvotes: 3
Reputation: 200
I think it's not possible. But you can use aspectj to catch the call of this method and after that you can get the SOAP Message
Upvotes: 0