如何使用带有org.w3c.dom.Node的CXF拦截器修改Web服务请求

时间:2011-09-21 03:37:40

标签: web-services dom cxf interceptor

使用CXF拦截器我想将一些Node附加到发送到服务器的xml上。我创建了一个拦截器(见下文),它将消息作为DOM节点接收,修改它并将其写回消息对象。

不幸的是,代码没有按预期工作 - 发送到服务器的XML不包含'magicWord'。恕我直言,我正在使用错误的阶段。

所以问题是:如何使用org.w3c.dom.Node语法修改传出的Web服务请求?

package dummy;

import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

class DummyInterceptor extends AbstractPhaseInterceptor {

    String magicWord = "abc";

    public DummyInterceptor() {
        super(Phase.PRE_PROTOCOL);
    }

    public void handleMessage(Message message) {
        Document document = (Document) message.getContent(Node.class);
        NodeList nodes = document.getElementsByTagName("wsse:Security");
        if (nodes.getLength() == 1) {
            Node wsseSecurityNode = nodes.item(0);
            wsseSecurityNode.appendChild(document.createTextNode(magicWord));
        }
        message.setContent(Node.class, document);
    }
}

2 个答案:

答案 0 :(得分:5)

最后我发现自己该怎么做。

  • 拦截器必须使用'Phase.PRE_PROTOCOL'
  • 拦截器必须使用addAfter(SaajOutInterceptor) - SaajOutInterceptor在Message中提供Node
  • 拦截器类应该派生自AbstractSoapInterceptor
  • 拦截器的handleMessage不会修改DOM本身的脏工作,而是使用message.getInterceptorChain()添加一个新的拦截器.add(...)。
  • 然后新添加的拦截器应该修改DOM

答案 1 :(得分:0)

如果要在cxf拦截器中使用DOM api修改请求的正文,则正确的阶段是USER_PROTOCOL

SAAJOutInterceptor创建DOM结构,因此必须在此之后运行拦截器,这意味着您可能必须将其添加到拦截器链中,因为出于性能原因,cxf并不总是将其添加。

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Node;

import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

abstract public class SoapNodeModifierInterceptor extends AbstractSoapInterceptor {
    SoapNodeModifierInterceptor() { super(Phase.USER_PROTOCOL); }

    @Override public void handleMessage(SoapMessage message) throws Fault {
        try {
            if (message == null) {
                return;
            }
            SOAPMessage sm = message.getContent(SOAPMessage.class);
            if (sm == null) {
                throw new RuntimeException("You must add the SAAJOutInterceptor to the chain");
            }

            modifyNodes(sm.getSOAPBody());

        } catch (SOAPException e) {
            throw new RuntimeException(e);
        }
    }

    abstract void modifyNodes(Node node);
}

添加拦截器:

import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.endpoint.Client;

/*[...]*/
client.getOutInterceptors().add(new SAAJOutInterceptor())
client.getOutInterceptors().add(new MySoapNodeModifierInterceptor())