SOAP request in JAVA. How to pass HEADER - java

I have a problem with create SOAP request. I have a works request from command line with usage curl
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:SetVolume xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1">
<InstanceID>0</InstanceID>
<Channel>Master</Channel>
<DesiredVolume>20</DesiredVolume>
</u:SetVolume>
</s:Body>
</s:Envelope> | curl -v -d #- -H 'SOAPAction: "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume"' -H 'content-type: text/xml; charset="utf-8"' http://192.168.0.172:1400/MediaRenderer/RenderingControl/Control
I tried crate equivalent in JAVA
import javax.xml.namespace.QName;
import javax.xml.soap.*;
public class SOAPClientSAAJ {
public static void main(String args[]) {
try {
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage sm = mf.createMessage();
SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
sh.detachNode();
QName bodyName = new QName("urn:schemas-upnp-org:service:RenderingControl:1#SetVolume", "SetVolume", "u");
SOAPBodyElement bodyElement = sb.addBodyElement(bodyName);
QName instanceID = new QName("InstanceID");
QName channel = new QName("Channel");
QName volumeLevel = new QName("DesiredVolume");
SOAPElement qInstanceID = bodyElement.addChildElement(instanceID);
SOAPElement qChannel = bodyElement.addChildElement(channel);
SOAPElement qVolumeLevel = bodyElement.addChildElement(volumeLevel);
qInstanceID.addTextNode("0");
qChannel.addTextNode("Master");
qVolumeLevel.addTextNode("30");
sm.writeTo(System.out);
System.out.println();
} catch(Exception e) {
}
}
}
This give me build request
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<u:SetVolume xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1#SetVolume">
<InstanceID>0</InstanceID>
<Channel>Master</Channel>
<DesiredVolume>30</DesiredVolume>
</u:SetVolume>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Unfortunately this don't want to works. I supose that problem is in HEADER, but actualy I don't know how to pass them in other way to my request. I also try solution from, but also get error
SOAP request to WebService with java

It seems like you are setting wrong QName. What you are setting is action so apart from that your generated soap envelope is fine I would suggest you to try calling this using SOAP UI.

Related

How to add childElements without prefix to Soap header?

I need to add header elements to a Soap Request, but the child elements inside the header dont have any prefix defined. When I try to add the element without specifing a prefix, this throws a exception.
private SOAPHeader addSecuritySOAPHeader(SOAPMessageContext context) {
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
envelope.addNamespaceDeclaration("S", "http://schemas.xmlsoap.org/soap/envelope/");
envelope.addNamespaceDeclaration("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
SOAPEnvelope header = envelope.getHeader();
// ACTION NODE
SOAPElement action = header.addChildElement("Action");
return header;
}
Last line produces next exception
"com.sun.xml.messaging.saaj.SOAPExceptionImpl: HeaderElements must be namespace qualified"
Heaser i need to create:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<Action xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://cgbridge.rategain.com/2011A/ReservationService/HotelResNotif</Action>
</S:Header>
..............
</S:Envelope>
If I include any prefix, like S, request fail, server response with "Bad request"
How can i add a "clean" Action node?
Is I add a prefix in action:
SOAPElement action = header.addChildElement("Action","S");
Service responses with a "Bad request" message.
<S:Action xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://cgbridge.rategain.com/2011A/ReservationService/HotelResNotif</S:Action>
Any help, please?
This should work:
#Test
public void someTest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
var header = soapEnvelope.getHeader();
var actionElement = header.addChildElement("Action", "prefix", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
actionElement.addTextNode("http://cgbridge.rategain.com/2011A/ReservationService/HotelResNotif");
ByteArrayOutputStream out = new ByteArrayOutputStream();
soapMessage.writeTo(out);
System.out.println(new String(out.toByteArray()));
}
Prints:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header><prefix:Action xmlns:prefix="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://cgbridge.rategain.com/2011A/ReservationService/HotelResNotif</prefix:Action></SOAP-ENV:Header><SOAP-ENV:Body/></SOAP-ENV:Envelope>

Response throwing error: Server Did not recognize the value of HTTP Header SOAPAction

I am trying to test a soap url. But I am getting the error response as mentioned in the question everytime I send the soap request. My code is as shown:
public static void main(String[] args) {
try {
SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
SOAPConnection connection = sfc.createConnection();
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage sm = mf.createMessage();
SOAPPart soapPart = sm.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
sh.detachNode();
QName postageLabelXML = new QName("www.envmgr.com/LabelService", "GetPostageLabelXML");
SOAPBodyElement bodyElement = sb.addBodyElement(postageLabelXML);
QName qn = new QName("LabelRequestXML");
SOAPElement quotation = bodyElement.addChildElement(qn);
QName qnLabelRequest = new QName("LabelRequest");
SOAPElement qnLabelRequestQuotation = quotation.addChildElement(qnLabelRequest);
MimeHeaders mimeHeaders = sm.getMimeHeaders();
mimeHeaders.addHeader("Host", "https://elstestserver.endicia.com");
mimeHeaders.addHeader("Content-Length", "65536");
mimeHeaders.addHeader("Content-Type", "text/xml; charset=utf-8");
mimeHeaders.addHeader("SOAPAction", "http://www.envmgr.com/LabelService/GetPostageLabelXML");
System.out.println("\n Soap Request:\n");
sm.writeTo(System.out);
System.out.println();
URL endpoint = new URL("https://elstestserver.endicia.com/LabelService/EwsLabelService.asmx");
SOAPMessage response = connection.call(sm, endpoint);
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.writeTo(out);
String strMsg = new String(out.toByteArray());
System.out.println(response.getContentDescription());
System.out.println("xml -= " + strMsg);
} catch (Exception ex) {
ex.printStackTrace();
}
}
The above code produces the following xml as request :
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<GetPostageLabelXML xmlns="www.envmgr.com/LabelService">
<LabelRequestXML>
<LabelRequest />
</LabelRequestXML>
</GetPostageLabelXML>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The required xml is :
POST /LabelService/EwsLabelService.asmx HTTP/1.1
Host: elstestserver.endicia.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "www.envmgr.com/LabelService/GetPostageLabelXML"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetPostageLabelXML xmlns="www.envmgr.com/LabelService">
<LabelRequestXML>
<LabelRequest>...some xml </LabelRequest>
</LabelRequestXML>
</GetPostageLabelXML>
</soap:Body>
</soap:Envelope>
After spending around 2 hours now in this issue I am not able to guess the real issue behind this error response :
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Server did not recognize the value of HTTP Header SOAPAction: .</faultstring>
<detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>
Please let me know if any error is noticed in this code.
I was adding an additional 'http://' in my
mimeHeaders.addHeader("SOAPAction", "http://www.envmgr.com/LabelService/GetPostageLabelXML");
It worked fine when I removed the http:// suffix. So the changed line was
mimeHeaders.addHeader("SOAPAction", "www.envmgr.com/LabelService/GetPostageLabelXML");

Java - Error Non-default namespace can not map to empty URI in XML 1.0 documents

I try to invoke a webservice in Java. Mainly I followed this link and also I solved several problems with google and other questions of stackoverflow. However, I get an error that I can not solve:
Exception in thread "main" javax.xml.ws.WebServiceException: javax.xml.stream.XMLStreamException: Non-default namespace can not map to empty URI (as per Namespace 1.0 # 2) in XML 1.0 documents
I think that the problem is in the xml that I created but I see well.
SOAPUI request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acc="http://url/acceso">
<soapenv:Header/>
<soapenv:Body>
<acc:petitionSession>
<acc:codUser/>
<acc:pass>?</acc:pass>
<acc:codOp>?</acc:codOp>
</acc:petitionSession>
</soapenv:Body>
</soapenv:Envelope>
Request I generated:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acc="http://url/acceso">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<acc:petitionSession>
<acc:codUser/>
<acc:pass>user1</acc:pass>
<acc:codOp>Temp1</acc:codOp>
</acc:petitionSession>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Code:
Dispatch dispatcher = getDispatcher(wsdlLocation, namespace, serviceName, portName);
dispatcher.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
dispatcher.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY, soapActionUri);
...
...
public static SOAPMessage construirMensaje() throws SOAPException, IOException{
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage soapMsg = factory.createMessage();
SOAPPart part = soapMsg.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
envelope.addNamespaceDeclaration("acc", "http://url/acceso");
SOAPHeader header = envelope.getHeader();
SOAPBody body = envelope.getBody();
SOAPBodyElement element = body.addBodyElement(envelope.createName("petitionSession",
"acc", null));
element.addChildElement(body.addBodyElement(envelope.createName("codUser",
"acc", null)));
SOAPBodyElement pass = body.addBodyElement(envelope.createName("pass",
"acc", null));
pass.addTextNode("user1");
element.addChildElement(pass);
SOAPBodyElement codOp = body.addBodyElement(envelope.createName("codOp",
"acc", null));
codOp.addTextNode("Temp1");
element.addChildElement(codOp);
soapMsg.writeTo(System.out);
FileOutputStream fOut = new FileOutputStream("SoapMessage.xml");
soapMsg.writeTo(fOut);
System.out.println();
return soapMsg;
}
Any idea?
Regards.
I find the problem that was in the header that it wasn`t built well. It needed to add:
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "name");

Searching the right format for SOAP access

in order to check validation of turkish personal identification numbers, the gouverment in turkey has this free service: https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx?op=TCKimlikNoDogrula
over SOAP you may check wether or not a ID-Number is valid.
but how ever i can not use this service with this code
package sevsoap;
import javax.xml.soap.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class SevSOAP
{
public static void main(String args[])
{
try
{
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
String url = "https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx?op=TCKimlikNoDogrula";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
// Process the SOAP Response
printSOAPResponse(soapResponse);
soapConnection.close();
}
catch(Exception e)
{
System.err.println("Error occurred while sending SOAP Request to Server");
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest() throws Exception
{
SOAPMessage message = MessageFactory.newInstance().createMessage();
SOAPPart soapPart = message.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("TCKimlikNoDogrula");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("TCKimlikNo");
soapBodyElem1.addTextNode("10000000146");
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("Ad");
soapBodyElem2.addTextNode("Mustafa");
SOAPElement soapBodyElem3 = soapBodyElem.addChildElement("Soyad");
soapBodyElem3.addTextNode("Atatürk");
SOAPElement soapBodyElem4 = soapBodyElem.addChildElement("DogumYili");
soapBodyElem4.addTextNode("1881");
MimeHeaders headers = message.getMimeHeaders();
headers.addHeader("SOAPAction", "http://tckimlik.nvi.gov.tr/WS/TCKimlikNoDogrula");
message.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message = ");
message.writeTo(System.out);
System.out.println();
return message;
}
/**
* Method used to print the SOAP Response
*/
private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Source sourceContent = soapResponse.getSOAPPart().getContent();
System.out.print("\nResponse SOAP Message = ");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
}
}
The message is sent in the following format:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<TCKimlikNoDogrula>
<TCKimlikNo>10000000146</TCKimlikNo>
<Ad>Mustafa</Ad>
<Soyad>Atatürk</Soyad>
<DogumYili>1881</DogumYili>
</TCKimlikNoDogrula>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
but it seems like the server requires me to send my query only in the following format:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<TCKimlikNoDogrula xmlns="http://tckimlik.nvi.gov.tr/WS">
<TCKimlikNo>10000000146</TCKimlikNo>
<Ad>Mustafa</Ad>
<Soyad>Atatürk</Soyad>
<DogumYili>1881</DogumYili>
</TCKimlikNoDogrula>
</soap:Body>
</soap:Envelope>
It doesn't matter to what i am changing the Namespace, it still puts out this error from the server:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Server was unable to process request. ---> T.C. Kimlik No değeri 10000000000 değerinden büyük veya eşit ve 89999999999 değerinden küçük veya eşit olmalıdır.
T.C. Kimlik No alanına girdiğiniz değer geçerli bir T.C. Kimlik Numarası değildir.
Ad alanını boş geçemezsiniz.
Soyad alanını boş geçemezsiniz.
Doğum Yıl değeri 1000 değerinden büyük veya eşit ve 9999 değerinden küçük veya eşit olmalıdır.
</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
It says that i can't submit these variables empty, they must contain data in order to process my query.
So, what could i do in this case?
I am in a habit of generating WS clients through eclipse, it did all the hard work for me here as well. Below are the step by step instructions how you create them:
Please note the changed url for direct wsdl I have used here: https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx?wsdl
Then I write your caller, below is the entire code:
package tr.gov.nvi.tckimlik.WS;
public class TurkishWS {
public static void main(String args[]) {
try {
KPSPublicLocator loc = new KPSPublicLocator();
KPSPublicSoap soap = loc.getKPSPublicSoap();
boolean ret = soap.TCKimlikNoDogrula(new Long("10000000146"),
"Mustafa", "Atatürk", 1881);
System.out.println("My return : " + ret);
} catch (Exception e) {
System.err
.println("Error occurred while sending SOAP Request to Server");
e.printStackTrace();
}
}
}
The result:
My return : false
I have also tried the direct request through soapUI, below are the request and response:
soapUI Request
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://tckimlik.nvi.gov.tr/WS">
<soap:Header/>
<soap:Body>
<ws:TCKimlikNoDogrula>
<ws:TCKimlikNo>10000000146</ws:TCKimlikNo>
<!--Optional:-->
<ws:Ad>Mustafa</ws:Ad>
<!--Optional:-->
<ws:Soyad>Atatürk</ws:Soyad>
<ws:DogumYili>1881</ws:DogumYili>
</ws:TCKimlikNoDogrula>
</soap:Body>
</soap:Envelope>
soapUI Response
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<TCKimlikNoDogrulaResponse xmlns="http://tckimlik.nvi.gov.tr/WS">
<TCKimlikNoDogrulaResult>false</TCKimlikNoDogrulaResult>
</TCKimlikNoDogrulaResponse>
</soap:Body>
</soap:Envelope>
Hope it helps your cause, and good luck!
Missing one default namespace in your code. Please try it!
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("TCKimlikNoDogrula", "", "http://tckimlik.nvi.gov.tr/WS");
(...)
I use empty string for default namespace. I tried your code with this modification and I get this response:
Response SOAP Message = <?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><TCKimlikNoDogrulaResponse xmlns="http://tckimlik.nvi.gov.tr/WS"><TCKimlikNoDogrulaResult>false</TCKimlikNoDogrulaResult></TCKimlikNoDogrulaResponse></soap:Body></soap:Envelope>

SharePoint Web Services jax-ws namespace conflict

I am trying to use SharePoint Web service to retrieve list changes but there seems to be a namespace conflict between what the jax-ws client generates and what SharePoint will accept. Below is the xml that is generated by jax-ws.
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<GetListItemChanges xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>Documents</listName>
<viewFields>
<FieldRef Name="Modified"/>
<FieldRef Name="_CheckinComment"/>
<FieldRef Name="Title"/>
<FieldRef Name="Created"/>
</viewFields>
<since>1970-01-01T00:00:00</since>
<contains/>
</GetListItemChanges>
</S:Body>
</S:Envelope>
i need to remove the xmlns="http://schemas.microsoft.com/sharepoint/soap/" from GetListItemChanges. I have tried the following (and various permutations thereof) but the changes seem to be ignored. The xmlns is removed when debugging but the output xml does not change.
public class SharePointSoapHandler implements SOAPHandler<SOAPMessageContext> {
...
#Override
public boolean handleMessage(SOAPMessageContext p_soapMessageContext) {
try {
SOAPMessage l_soapMessage = p_soapMessageContext.getMessage();
l_soapMessage.getSOAPBody().getFirstChild().getAttributes().removeNamedItem("xmlns");
l_soapMessage.saveChanges();
ByteArrayOutputStream l_outputStream = new ByteArrayOutputStream();
l_soapMessage.writeTo(l_outputStream);
m_logger.info(new String(l_outputStream.toByteArray()));
} catch (Exception ex) {
m_logger.error("Soap exception modifying xml for request", ex);
}
return true;
}
}
Am I missing something? Is there a better way to accomplish this or do I need to generate the xml by hand?
EDIT: A valid soap request using soap ui. jax-ws drops the second prefix and moves the xmlns attribute.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.microsoft.com/sharepoint/soap/">
<soapenv:Header/>
<soapenv:Body>
<soap:GetListItemChanges>
<!--Optional:-->
<soap:listName>Shared Documents</soap:listName>
...
<soap:since>2012-02-15T00:00:00</soap:since>
</soap:GetListItemChanges>
</soapenv:Body>
</soapenv:Envelope>
See Changing the default XML namespace prefix generated with JAXWS for using a handler to intercept the soap and modify it as needed; also a useful technique for debugging the soap as its sent over the wire.
you can also set the namespace declarations in the soap header like so:
SOAPMessage request = factory.createMessage();
SOAPEnvelope envelope = request.getSOAPPart().getEnvelope();
envelope.addNamespaceDeclaration("uri", "uri:foo.bar.com");
request.saveChanges();
and then create elements with the namespace prefix like this:
SOAPBody body = request.getSOAPBody();
SOAPElement ping = body.addChildElement("foo", "uri");
without setting the declaration in the header first, adding the element with the prefix will fail.
doing things this way seems to circumvent having the namespace declaration hanging off of body nodes, which was breaking what i was trying to do.
here's my jUnit test that i used to verify this works:
public void testPing() throws Exception {
String endpoint = "http://www.foo.bar/ws/someWebservice";
QName port = new QName(endpoint, "uri");
QName serviceName = new QName(endpoint, "someWebserviceMethod");
Service service = Service.create(serviceName);
service.setHandlerResolver(new MyHandlerResolver());
service.addPort(port, SOAPBinding.SOAP11HTTP_BINDING, endpoint);
Dispatch<SOAPMessage> dispatch = service.createDispatch(port, SOAPMessage.class, Service.Mode.MESSAGE);
MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
SOAPMessage request = factory.createMessage();
SOAPEnvelope envelope = request.getSOAPPart().getEnvelope();
envelope.addNamespaceDeclaration("uri", "uri:bar.foo");
request.saveChanges();
SOAPBody body = request.getSOAPBody();
SOAPElement element = body.addChildElement("someRequestElement", "uri");
SOAPElement child = ping.addChildElement("someRequestChild");
SOAPElement text_node = child.addChildElement("someTextNode");
messageType.addTextNode("test text");
request.saveChanges();
System.out.println();
request.writeTo(System.out);
System.out.println();
Object o = dispatch.invoke(request);
System.out.println("ret: " + o.toString());
assertNotNull( o );
}

Categories