简体   繁体   中英

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM