SharePoint Web Services jax-ws namespace conflict

一曲冷凌霜 提交于 2019-12-24 09:59:55

问题


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>

回答1:


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

}



来源:https://stackoverflow.com/questions/9223529/sharepoint-web-services-jax-ws-namespace-conflict

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