如何使用Java JAX-WS添加SOAP头

25

JAX-WS通常使用的SOAP客户端请求可能如下:

FooService service = new FooService();
FooPort port = service.getFooPort();
FooPayload payload = new FooPayload();
payload.setHatSize(3);
payload.setAlias("The Hat");
...
port.processRequest(payload);

这将生成类似于HTTP请求内容的东西

<?xml ... ?>
<S:Envelope xmlns:S="http://...soap-envelope">
  <S:Body>
    <!-- payload -->
  </S:Body>
</S:Envelope>
通过操作port.processRequest()调用的参数,您只能影响“负载”部分。您无法影响XML消息的外部部分。 我想在SOAP Body之前插入一个SOAP头
<S:Header>
   <X:Security xmlns:X="http://...wsssecurity...>
      <X:BinarySecurityToken>kjh...897=</X:BinarySecurityToken>
   </X:Security>
</S:Header>

我该如何做到这点?


WSDL是否描述了头信息?如果是这样,那么JAX-WS会生成添加它们的代码吗? - John Saunders
3个回答

19

谢谢Nuno,

一旦我弄清楚如何正确登录stackoverflow.com,我会按照您的回复做正确的事情。

与此同时,这是我最终得出的代码:

FooService service = new FooService();
service.setHandlerResolver(new HandlerResolver() {
    public List<Handler> getHandlerChain(PortInfo portInfo) {
        List<Handler> handlerList = new ArrayList<Handler>();
        handlerList.add(new RGBSOAPHandler());
        return handlerList;
    }
});
FooPort port = service.getFooPort();
FooPayload payload = new FooPayload();
payload.setHatSize(3);
payload.setAlias("The Hat");
...
port.processRequest(payload);

并且

class RGBSOAPHandler implements SOAPHandler<SOAPMessageContext> {

    public Set<QName> getHeaders() {
        return new TreeSet();
    }

    public boolean handleMessage(SOAPMessageContext context) {
        Boolean outboundProperty = 
            (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty.booleanValue()) {
            SOAPMessage message = context.getMessage();
            try {
                SOAPEnvelope envelope = context.getMessage()
                        .getSOAPPart().getEnvelope();
                SOAPFactory factory = SOAPFactory.newInstance();
                String prefix = "X";
                String uri = "http://...wsssecurity...";
                SOAPElement securityElem = 
                        factory.createElement("Security",prefix,uri);
                SOAPElement tokenElem = 
                        factory.createElement("BinarySecurityToken",prefix,uri);
                tokenElem.addTextNode("kjh...897=");
                securityElem.addChildElement(tokenElem);
                SOAPHeader header = envelope.addHeader();
                header.addChildElement(securityElem);

            } catch (Exception e) {
                System.out.println("Exception in handler: " + e);
            }
        } else {
            // inbound
        }
        return true;
    }

    public boolean handleFault(SOAPMessageContext context) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void close(MessageContext context) {
        //
    }
}

我按照你的步骤进行,但是出现以下异常:org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: 尝试在不允许的位置插入节点。你遇到过这个问题吗?该应用正在运行于Weblogic 10.1。 - Vladimir

1

你可能想要查看处理程序和处理程序链。最近我不得不向给定的Web服务调用添加一个cookie,这就是我所做的,只需创建一个拦截初始调用并注入cookie的处理程序,您还可以使用Pivot Handler操纵调用头。


0

如果您在Web应用程序服务器上实现WS,则需要添加Soap标头。 Was将在标头中添加安全部分,之后您需要根据WS-SECURITY标准进行配置,例如web-policy等。除了加密内容部分(例如加密密码等),我不明白为什么需要自己添加。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接