问题
I want to build a soap client in java using JAXWS. I searched on google but didn't find any relevant information. Here is what I have tried:
QName serviceName = new QName("urn:Site", "Site");
QName portName = new QName("urn:Site", "Server_HandlerPort");
String endpointAddress = "http://myhost/url/soap";
Service service = Service.create(serviceName);
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
BindingProvider bp = (BindingProvider) dispatch;
MessageFactory factory = ((SOAPBinding) bp.getBinding()).getMessageFactory();
SOAPMessage request = factory.createMessage();
SOAPHeader header = request.getSOAPHeader();
SOAPBody body = request.getSOAPBody();
QName payloadName = new QName("session");
SOAPBodyElement payload = body.addBodyElement(payloadName);
SOAPMessage reply = null;
try {
reply = dispatch.invoke(request);
} catch (WebServiceException wse){
wse.printStackTrace();
}
body = reply.getSOAPBody();
QName responseName = new QName("urn:site","sessionResponse");
SOAPBodyElement bodyElement = (SOAPBodyElement) body.getChildElements(responseName).next();
System.out.println(bodyElement.getValue());
This do not work. This always returns null
I'm not sure why? Can anyone help me on this? Any example? for doing such thing?
回答1:
JAX-WS allows you to generate a client from the web service's WSDL using wsimport. This will make the client code much simpler. Here's a sample tutorial
回答2:
From what I noticed, the unmarshalling that occurs in dispatch.invoke
of a response does not populate the body, envelope etc. from SOAPMessage
, but instead it creates an internal Document
that it is linked to the SOAPPart
.
If you invoke reply.writeTo(System.out)
after the invoke is called, it will print the full response message into console.
You can browse the Document
(in this case actually the root Element
) and get your sessionResponse
. Here is an code snippet:
NodeList nodeList = reply.getSOAPPart().getDocumentElement().getElementsByTagNameNS("urn:site", "sessionResponse");
Node node = nodeList.item(0);
Now depending on the structure of the response, you may need to do some navigation in the tree. Let's suppose that your response looks like this:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:sessionResponse xmlns:ns2="urn:site">
<return>Hello World!</return>
</ns2:sessionResponse >
</S:Body>
</S:Envelope>
In order to get the returned value you will call:
System.out.println(node.getFirstChild().getFirstChild().getNodeValue());
- 1st getFirstChild returns
return
Node - 2nd getFirstChild returns
text
Node
If you need the Document
object instead of Element
object from the SOAPPart
you need to cast the SOAPPart
to SOAPPartImpl
:
Document document = ((SOAPPartImpl) response.getSOAPPart()).getDocument();
来源:https://stackoverflow.com/questions/7646591/connect-to-soap-using-jax-ws