Is there a guaranteed way to get operation name in a custom soap handler?

安稳与你 提交于 2019-12-04 04:56:37

You could call body.getElementName().getLocalName() to retrieve the name of SOAP body element of the message payload. It's a little bit verbose and manual but it works. You could have the following in your handler

if ((boolean) context.get(MessageContext.MESSAGE_INBOUND_PROPERTY){ //for requests only
            SOAPEnvelope msg = context.getMessage().getSOAPPart().getEnvelope(); //get the SOAP Message envelope
                SOAPBody body = msg.getBody();
            String operationName = body.getChildNodes().item(1).getLocalName();
}

The result of the above code is guaranteed to carry the name of the operation as specified in your WSDL

EDIT: This solution is based solely on the condition that the web service is implemented as document/literal-wrapped or RPC/literal

I'm very late to this party but I tried to do this over the past week. The accepted answer doesn't actually work for every JAX-WS implementation (at least not that I tried).

I have been trying to make this work on standalone Metro in my development environment but also using Axis2 bundled with WebSphere 7 in a real environment.

I found the following works on Metro:

String operationName = body.getChildNodes().item(0).getLocalName();

and the following works on Axis2:

String operationName = body.getChildNodes().item(1).getLocalName();

What is happening is that Axis2 inserts a Node of type Text into the Body as the first child but Metro doesn't. This text node returns a null local name. My solution was to do the following:

NodeList nodes = body.getChildNodes();

// -- Loop over the nodes in the body.
for (int i=0; i<nodes.getLength(); i++) {
  Node item = nodes.item(i);

  // -- The first node of type SOAPBodyElement will be
  // -- what we're after.
  if (item instanceof SOAPBodyElement) {
    return item.getLocalName();
  }
}

As described in the comments we're actually looking for the first node of type SOAPBodyElement. Hopefully that will help out anyone else looking at this in the future.

The SOAPMessageContext contains this information and can be retrieved super easily like this:

public boolean handleMessage(SOAPMessageContext msgContext) {
    QName svcn = (QName) smc.get(SOAPMessageContext.WSDL_SERVICE);      
    QName opn = (QName) smc.get(SOAPMessageContext.WSDL_OPERATION);
    System.out.prinln("WSDL Service="+ svcn.getLocalPart());
    System.out.prinln("WSDL Operation="+ opn.getLocalPart());

    return true;
}

in case if someone searches for "elegant" way to get needed properties use

    for(Map.Entry e : soapMessageContext.entrySet()){
            log.info("entry:"+ e.getKey() + " = " + e.getValue());
    }

then decide what info you need and get it!

soapMessageContext.get(YOUR_DESIRED_KEY);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!