Apache-CXF JAX-WS client error : Message part not recognized - java

I wrote a webservice using Apache-CXF. It works fine when tested with SoapUI. I wrote a Java client to call the webservice, and it fails with the following error:
org.apache.cxf.interceptor.Fault: Message part customer was not recognized. (Does it exist in service WSDL?)
The client program reads data from a xml file and adds it as a Document to the SOAPBody.
Here is the input data in SoapUI:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:app="ApplyLoanRequest">
<soapenv:Header/>
<soapenv:Body>
<app:customer>
<contact>
<!--1 to 2 repetitions:-->
<name part="first">J</name>
<name part="last">H</name>
<country>US</country>
</contact>
</app:customer>
</soapenv:Body>
</soapenv:Envelope>
Here is the SOAP generated by my client available on the console from the writeTo System.out
Starting BankLoan Client ...
Service request ...
====================================
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:app="ApplyLoanRequest"><SOAP-ENV:Header/><SOAP-ENV:Body><customer>
<contact>
<!--1 to 2 repetitions:-->
<name part="first">J</name>
<name part="last">H</name>
<country>IN</country>
</contact>
</customer></SOAP-ENV:Body></SOAP-ENV:Envelope>
Service response ...
====================================
soap:Fault
faultcode = soap:Client
The difference is that in SoapUI, the root element is sent with namespace, as app:customer whereas in my client program there is no prefix. Is this causing the error? How do I prefix the root element with app: ?
Here is the Java client program:
public class BankLoanClient
{
public Document convertXMLFileToDocument(String pathToFile) throws Exception
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(pathToFile);
return doc;
}
public static void main(String[] args) throws Exception
{
System.out.println("Starting BankLoan Client ... ");
SOAPMessage message = MessageFactory.newInstance().createMessage();
SOAPBody body = message.getSOAPBody();
SOAPPart part = message.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
envelope.addNamespaceDeclaration("app", "ApplyLoanRequest");
body.addDocument(new BankLoanClient().convertXMLFileToDocument(args[0]));
System.out.println("Service request ... ");
System.out.println("====================================");
message.writeTo(System.out);
System.out.println();
URL endpoint = new URL("http://localhost:8080/bankloan/services/applyloan");
SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
SOAPConnection connection = factory.createConnection();
SOAPMessage response = connection.call(message, endpoint);
connection.close();
// Process the response message
SOAPBody respBody = response.getSOAPBody();
Iterator it = respBody.getChildElements();
SOAPBodyElement element = (SOAPBodyElement) it.next();
System.out.println("Service response ... ");
System.out.println("====================================");
System.out.println(element.getNodeName());
it = element.getChildElements();
SOAPElement ret = (SOAPElement) it.next();
System.out.println(ret.getNodeName() + " = " + ret.getTextContent());
}
}
Even if I change the URL to point at the wsdl, I get the same error.
URL endpoint = new URL("http://localhost:8080/bankloan/services/applyloan?wsdl");

Related

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");

Server did not recognize the value of HTTP Header SOAPAction:

I'm trying to call a SOAP webservice using SAAJ for this WSDL. I submitted the request for this WSDL here http://www.webservicex.net/ws/WSDetails.aspx?WSID=64and it generated the following SOAP requests..
<?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>
<GetGeoIP xmlns="http://www.webservicex.net/">
<IPAddress>string</IPAddress>
</GetGeoIP>
</soap:Body>
</soap:Envelope>
Using SAAJ I generated the same SOAP requests and submitted it but get this error - Server did not recognize the value of HTTP Header SOAPAction: .
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Header/>
<SOAP-ENV:Body>
<GetGeoIP xmlns="http://www.webservicex.net/">
<IPAddress>SUNW</IPAddress>
</GetGeoIP>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Java Code:
package newpackage;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
public class SOAPClientSAAJ {
public static void main(String args[]) throws Exception {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
String url = "http://www.webservicex.net/geoipservice.asmx";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
// print SOAP Response
System.out.print("Response SOAP Message:");
soapResponse.writeTo(System.out);
soapConnection.close();
}
private static SOAPMessage createSOAPRequest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://www.w3.org/2001/XMLSchema";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("xsd", serverURI);
SOAPBody body = soapMessage.getSOAPBody();
QName bodyName = new QName("http://www.webservicex.net/", "GetGeoIP" );
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
QName name = new QName("IPAddress");
SOAPElement symbol = bodyElement.addChildElement(name);
symbol.addTextNode("SUNW");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
}
Add
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", "http://www.webservicex.net/" + "GetGeoIP");
If you are using Marshelling and Unmarsheling, Just implement WebseviceMessageCallback interface like:
public class SOAPConnector extends WebServiceGatewaySupport
{
public Object callWebService( String url, Object request )
{
return getWebServiceTemplate().marshalSendAndReceive( url, request,
webServiceMessage -> {
(( SoapMessage )webServiceMessage).setSoapAction(
"https://www.w3schools.com/xml/CelsiusToFahrenheit" );
} );
}
}
Otherwise proceed with: https://stackoverflow.com/a/26253141/6097074

Access Java Web Service and get response

I am doing a project which has to access to a given web service and send data to requested parameters and get the response from service. Currently I do something which I found from a forum and it parse the data to service, but unable to get the response since its giving an error.
My sample code is below.
package webserviceexample;
import javax.xml.soap.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class aaaa {
public static void main(String args[]) {
try {
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
String url = "https://vlmt.XXX.lk:0111/VendorRecharge/services/RechargeVendorService/wsdl/";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
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 {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://vendor.XXX.ZZZ.com/";
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("wsdl", serverURI);
SOAPBody soapBody1 = envelope.getBody();
SOAPElement soapBodyElemX = soapBody1.addChildElement("performRecharge", "wsdl");
SOAPElement soapBodyElem1 = soapBodyElemX.addChildElement("storeId", "wsdl");
soapBodyElem1.addTextNode("LA19BNPX");
SOAPElement soapBodyElem2 = soapBodyElemX.addChildElement("password", "wsdl");
soapBodyElem2.addTextNode("thilanka#456A");
SOAPElement soapBodyElem3 = soapBodyElemX.addChildElement("mobileNo", "wsdl");
soapBodyElem3.addTextNode("751238456");
SOAPElement soapBodyElem4 = soapBodyElemX.addChildElement("Amount", "wsdl");
soapBodyElem4.addTextNode("12");
SOAPElement soapBodyElem5 = soapBodyElemX.addChildElement("vendorTransactionId", "wsdl");
soapBodyElem5.addTextNode("15");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("performRecharge", serverURI + "performRecharge");
System.out.println("");
soapMessage.saveChanges();
System.out.print("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
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 error I am getting is:
Request SOAP Message
<SOAP-ENV:Envelope xmlns:SOAP- ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsdl="http://vendor.virtualization.ibm.com/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<wsdl:performRecharge>
<wsdl:storeId>LA19BNPX</wsdl:storeId>
<wsdl:password>thilanka#456A</wsdl:password>
<wsdl:mobileNo>751238456</wsdl:mobileNo>
<wsdl:Amount>12</wsdl:Amount>
<wsdl:vendorTransactionId>15</wsdl:vendorTransactionId>
</wsdl:performRecharge>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Response (error)
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>soapenv:Server.generalException</faultcode>
<faultstring>javax.xml.rpc.JAXRPCException: WSWS3122E: Error: Could not find service services/RechargeVendorService/wsdl/ referenced in URI /VendorRecharge/services/RechargeVendorService/wsdl/</faultstring>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
I have to call the "performRecharge" in the web service. Please help me.
A summary of the web service is below.
Please help me overcome this. It's very important.
Thank you.
WSDL FILE
Make sure that this is the correct service URL.
Seems like you specified the wsdl location and not registered service url. Set the request url specified in the wsdl file for the service.
String url = "https://vlmt.XXX.lk:0111/VendorRecharge/services/RechargeVendorService/wsdl/";
See the location tag in your wsdl
<service name="Hello_Service">
<documentation>WSDL File for HelloService</documentation>
<port binding="tns:Hello_Binding" name="Hello_Port">
<soap:address
location="**http://www.examples.com/SayHello/**">
</port>
</service>

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