Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ApacheCXF:在服务方法中获取SOAP消息_Java_Web Services_Apache_Soap_Cxf - Fatal编程技术网

Java ApacheCXF:在服务方法中获取SOAP消息

Java ApacheCXF:在服务方法中获取SOAP消息,java,web-services,apache,soap,cxf,Java,Web Services,Apache,Soap,Cxf,我们使用ApacheCXF来托管webservice。我有一个基本问题 有可能在实际的webservice方法中获取soap消息/负载吗?这个Web服务将把传递给它的值保存在数据库中,同时我们希望将实际的XML请求/repsonse(有效负载)保存在数据库中 我尝试过处理程序/拦截器,我能够在那里看到SOAP消息。但我希望在webservice方法中使用XML负载,以便执行必要的操作并将负载保存到数据库。我认为这是不可能的。但是,您可以使用aspectj捕获此方法的调用,然后您可以获得SOAP消

我们使用ApacheCXF来托管webservice。我有一个基本问题

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


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

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

自提出此问题以来已经有很长时间了,但万一任何人都会遇到相同的问题:

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

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

PS:拦截器和web服务实现者都必须实现ApplicationContextAware接口

以下是我所做的,它对我起了作用:

在拦截器中:

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

}

请检查这个答案,问题似乎是一样的:谢谢你的帮助,但我不想要拦截器,因为传入的拦截器在到达服务方法之前获取有效负载。我想在服务方法本身中获得XML负载。这方面的任何帮助都会非常有用。除了拦截器之外,没有其他方法可以做到这一点。默认情况下,CXF在使用时丢弃所有内容。在CXF论坛上有同样的答案:它是线程安全的吗?我认为不会,因为如果我们同时有1k个请求,那么在服务方法中会采用什么bean?
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;      
    }
}