Apache CXF:在服务方法中获取SOAP消息

时间:2014-01-02 14:43:49

标签: java web-services apache soap cxf

我们正在使用Apache CXF来托管webservice。我有一个基本问题

是否可以在实际的webservice方法中获取soap消息/有效负载?此Web服务将保存在数据库中传递给它的值,同时我们希望将实际的XML请求/ repsonse(有效负载)保存在数据库中。

我尝试过处理程序/拦截器,我可以在那里看到SOAP消息。但我想在webservice方法中使用XML有效负载,以便我可以执行必要的操作并将有效负载保存到数据库。

2 个答案:

答案 0 :(得分:1)

自问这个问题以来已经很长时间了,但如果有人会遇到同样的问题:

这个想法是使用spring上下文,因为它比拦截器上下文大

您需要以编程方式将XML请求注册为spring bean,然后在您的Web服务方法中获取它

PS:您的拦截器和Web服务实现者都必须实现ApplicaionContextAware接口

这是我做的,它对我有用:

你的拦截器中的

@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();

}

在您的网络服务方法中:

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;      
    }
}

答案 1 :(得分:0)

我认为这是不可能的。但是您可以使用aspectj来捕获此方法的调用,之后您可以获取SOAP消息