【问题标题】:Apache CXF: get SOAP message inside service methodApache CXF:在服务方法中获取 SOAP 消息
【发布时间】:2014-01-02 14:43:49
【问题描述】:

我们使用 Apache CXF 来托管 Web 服务。我有一个基本问题

是否可以在实际的 web 服务方法中获取肥皂消息/有效负载?该网络服务会将传递给它的值保存在数据库中,同时我们希望将实际的 XML 请求/响应(有效负载)保存在数据库中。

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

【问题讨论】:

  • 请检查这个答案,似乎问题是一样的:stackoverflow.com/questions/11038313/…
  • 感谢您的帮助,但我不想要拦截器,因为传入的拦截器会在到达服务方法之前获取有效负载。我想在服务方法本身中获取 XML 有效负载。对此的任何帮助都会非常有帮助。
  • 除了拦截器没有办法。默认情况下,CXF 会在使用时丢弃所有内容。这是 CXF 论坛上的相同答案:cxf.547215.n5.nabble.com/…

标签: java web-services apache soap cxf


【解决方案1】:

这个问题已经很久没有问过了,但万一有人遇到同样的问题:

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

您需要以编程方式将 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;      
    }
}

【讨论】:

  • 线程安全吗?我想不是。因为如果我们同时有 1k 个请求 - 服务方法中会采用什么 bean?
【解决方案2】:

我认为这是不可能的。但是你可以使用 aspectj 来捕捉这个方法的调用,然后你就可以得到 SOAP 消息

【讨论】:

    猜你喜欢
    • 2021-08-13
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    相关资源
    最近更新 更多