11 Replies Latest reply on Aug 19, 2010 2:07 PM by fredk

    setHeader and setServerURL, using javax.xml.ws.Service?

    eric2

      Trying to integrate into SalesForce using JBossws1.2 SP1 instead of Axis.

      I've generated the java stubs and I can connect just fine. One I login I'm given a new SeverURL and a sessionID. I need to change the location that I connect to and I need to attach the SessionID to the soap Bindings for every subsequent request.

      QName q = new QName("urn:partner.soap.sforce.com", "SforceService");
      SforceService service = new SforceService(urlToWSDL, q);
      LoginResult lr = service.getSoap().login("username", "password");
      System.out.println("lr.getServerUrl() = " + lr.getServerUrl());
      System.out.println("lr.getSessionId() = " + lr.getSessionId());



      SforceService extends javax.xml.ws.Service and it was generated by wsconsume from the sales-force partner wsdl.

      I need to set the new server url to the lr.getServerUrl and I need to include the lr.getSessionId as a SOAP header.

      I can get this to work using Axis but I want to use JBossWS.
      --------USING AXIS ---------
      SforceService service extends org.apache.axis.client.Stub. The axis org.apache.axis.client.Stub provides _setProperty and setHeader
      Example:
      service._setProperty(SoapBindingStub.ENDPOINT_ADDRESS_PROPERTY, serverURL);

      and
      SessionHeader sessionHeader = new SessionHeader();
      sessionHeader.setSessionId(sessionID);
      // Add the header to the binding stub.
      String sforceURI = new SforceServiceLocator().getServiceName().getNamespaceURI();
      service.setHeader(sforceURI, "SessionHeader", sessionHeader);







        • 1. Re: setHeader and setServerURL, using javax.xml.ws.Service?

          Hi,
          first of all consider upgrading to 2.0.GA. To change the web service address dynamically for a request, you might do something like

          ((BindingProvider)proxy).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "...");


          Bye
          Alessio Soldano
          http://www.javalinux.it

          • 2. Re: setHeader and setServerURL, using javax.xml.ws.Service?
            eric2

            That seems to reset the URL:

            SforceService service = new SforceService(urlToWSDL, q);
            Soap soapBinding = service.getSoap();
            LoginResult lr = soapBinding.login("username", password");
            ((BindingProvider)soapBinding).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, lr.getServerUrl());
            


            That works perfectly, with JBoss 1.2.1 sp1

            I still haven't figured out how to set the sessionID. I've tried:

            SessionHeader session = new SessionHeader();
            session.setSessionId(lr.getSessionId());
            ((BindingProvider)soapBinding).getRequestContext().put("SessionHeader", session);
            


            but I still get the following error:


            Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session
            at org.jboss.ws.core.jaxws.SOAPFaultHelperJAXWS.getSOAPFaultException(SOAPFaultHelperJAXWS.java:56)
            at org.jboss.ws.core.jaxws.binding.SOAP11BindingJAXWS.throwFaultException(SOAP11BindingJAXWS.java:111)
            at org.jboss.ws.core.CommonSOAPBinding.unbindResponseMessage(CommonSOAPBinding.java:460)
            at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:333)
            at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:185)
            at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:163)
            at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:149)
            at $Proxy22.query(Unknown Source)



            THIS IS HOW YOU SET THE SESSION HEADER IN AXIS:
            SoapBindingStub service; // public class SoapBindingStub extends org.apache.axis.client.Stub implements com.sforce.soap.partner.Soap


            SessionHeader sessionHeader = new SessionHeader();
            sessionHeader.setSessionId(sessionID);
            
            String sforceURI = new SforceServiceLocator().getServiceName().getNamespaceURI();
            service.setHeader(sforceURI, "SessionHeader", sessionHeader);
            


            • 3. Re: setHeader and setServerURL, using javax.xml.ws.Service?
              eric2

              I think i'm getting a little closer, after reading the JAX-RPC user guild I think I need to set the: Unbound SOAP Headers on the client proxy, see
              http://jbws.dyndns.org/mediawiki/index.php?title=JAX-RPC_User_Guide#Unbound_SOAP_Headers

              I've tried this but it didn't seem to work

              URL urlToWSDL = JbossWSConnection.class.getResource("/partner-wsdl.xml");
              QName q = new QName("urn:partner.soap.sforce.com", "SforceService");
              SforceService service = new SforceService(urlToWSDL, q);
              Soap soapBinding = service.getSoap();
              StubExt stub = (StubExt)soapBinding;
              LoginResult lr = soapBinding.login("username", "password");
              SessionHeader session = new SessionHeader();
              session.setSessionId(lr.getSessionId())
              QName headerQ = new QName(service.getServiceName().getNamespaceURI(), "SessionHeader");
              stub.addUnboundHeader(headerQ, Constants.TYPE_LITERAL_ANYTYPE, SessionHeader.class, ParameterMode.IN);
              stub.setUnboundHeaderValue(headerQ, session);


              This is the error that I get:
              Caused by: org.jboss.ws.WSException: Cannot obtain serializer factory for: [xmlType={http://www.w3.org/2001/XMLSchema}anyType,javaType=class com.sforce.soap.partner.SessionHeader]
              at org.jboss.ws.core.soap.ObjectContent.getSerializerFactory(ObjectContent.java:189)
              at org.jboss.ws.core.soap.ObjectContent.marshallObjectContents(ObjectContent.java:139)
              at org.jboss.ws.core.soap.ObjectContent.transitionTo(ObjectContent.java:65)
              at org.jboss.ws.core.soap.SOAPContentElement.transitionTo(SOAPContentElement.java:129)
              at org.jboss.ws.core.soap.SOAPContentElement.writeElement(SOAPContentElement.java:536)
              at org.jboss.ws.core.soap.SOAPHeaderElementImpl.writeElement(SOAPHeaderElementImpl.java:132)
              at org.jboss.ws.core.soap.SOAPElementImpl.writeElementContent(SOAPElementImpl.java:825)
              at org.jboss.ws.core.soap.SOAPElementImpl.writeElement(SOAPElementImpl.java:810)
              at org.jboss.ws.core.soap.SOAPElementImpl.writeElementContent(SOAPElementImpl.java:825)
              at org.jboss.ws.core.soap.SOAPElementImpl.writeElement(SOAPElementImpl.java:810)
              at org.jboss.ws.core.soap.SOAPElementWriter.writeElementInternal(SOAPElementWriter.java:149)
              at org.jboss.ws.core.soap.SOAPElementWriter.writeElement(SOAPElementWriter.java:130)
              at org.jboss.ws.core.soap.SOAPMessageImpl.writeTo(SOAPMessageImpl.java:288)
              at org.jboss.ws.core.soap.SOAPMessageMarshaller.write(SOAPMessageMarshaller.java:76)
              at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:164)



              I'm guessing the problem has to do with
              stub.addUnboundHeader(headerQ, Constants.TYPE_LITERAL_ANYTYPE, SessionHeader.class, ParameterMode.IN);
              any Idea on which QName xmlType I should pick? I'm using the org.jboss.ws.Constants Interface.

              I've also tried:
              QName headerQ = new QName(service.getServiceName().getNamespaceURI(), "SessionHeader");
              SessionHeader.class, ParameterMode.IN);
              stub.addUnboundHeader(headerQ, Constants.TYPE_LITERAL_STRING, String.class, ParameterMode.IN);
              stub.setUnboundHeaderValue(headerQ, lr.getSessionId());
              


              but then I get the infamous:

              Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session
              at org.jboss.ws.core.jaxws.SOAPFaultHelperJAXWS.getSOAPFaultException(SOAPFaultHelperJAXWS.java:56)
              at org.jboss.ws.core.jaxws.binding.SOAP11BindingJAXWS.throwFaultException(SOAP11BindingJAXWS.java:111)
              at org.jboss.ws.core.CommonSOAPBinding.unbindResponseMessage(CommonSOAPBinding.java:460)
              at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:333)
              at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:185)
              at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:163)
              at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:149)
              at $Proxy22.query(Unknown Source)
              at salesforce.JbossWSConnection.querySample(JbossWSConnection.java:165)
              at salesforce.JbossWSConnection.main(JbossWSConnection.java:66)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:585)
              at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)



              • 4. Re: setHeader and setServerURL, using javax.xml.ws.Service?
                eric2

                Does anyone know if JBossws 2.0.GA has added anything in the setHeaders arena? I'm sitll looking for a solution to my problem. I'm currently on JBoss 1.2.1 SP1

                • 5. Re: setHeader and setServerURL, using javax.xml.ws.Service?
                  lowecg2004

                  Eric,

                  Did you ever find a solution to setting the sessionId and setHeaders?

                  Regards,

                  Chris.

                  • 6. Re: setHeader and setServerURL, using javax.xml.ws.Service?
                    eric2

                    I wasn't able to find a solution, I'm currently using AXIS. I'd love to switch over - but no one knows how to do this. Not even the jboss team has responded to this thread.

                    • 7. Re: setHeader and setServerURL, using javax.xml.ws.Service?
                      thomas.diesler

                      We have support to bound and unbound headers.

                       public void testUnboundInHeader() throws Exception
                       {
                       // Add a header to the stub
                       StubExt stub = (StubExt)port;
                       QName xmlName = new QName("http://otherns", "HeaderValue");
                       stub.addUnboundHeader(xmlName, Constants.TYPE_LITERAL_STRING, String.class, ParameterMode.IN);
                       stub.setUnboundHeaderValue(xmlName, "Unbound IN header message");
                      
                       port.testInHeader("Hello world!", "IN header message");
                      
                       String unboundRet = (String)stub.getUnboundHeaderValue(xmlName);
                       assertEquals("Unbound OUT header message", unboundRet);
                       }
                      


                      This should work for jaxrpc and jaxws

                      • 8. Re: setHeader and setServerURL, using javax.xml.ws.Service?
                        eric2

                        Yeah I too could do the simple "Hello World", but i don't know how to include a complex type, such as

                        <soapenv:Header>
                         <urn:SessionHeader>
                         <urn:sessionId>QwWsHJyTPW.1pd0_jXlNKOSU</urn:sessionId>
                         </urn:SessionHeader>
                        </soapenv:Header>


                        as a header. Notice it wraps sessionId inside SessionHeader.

                        I've tried a number of things including
                        StubExt soapStub = (StubExt)soapBinding;
                        QName headerQ = new QName(service.getServiceName().getNamespaceURI(), "SessionHeader");
                        QName sessionId = new QName(service.getServiceName().getNamespaceURI(), "SessionHeader", "sessionId");
                        soapStub.addUnboundHeader(headerQ, Constants.TYPE_LITERAL_STRING, String.class, ParameterMode.IN);
                        soapStub.setUnboundHeaderValue(sessionId, "QwWsHJyTPW.1pd0_jXlNKOSU");


                        but that only managed to produce:
                        <ns1:SessionHeader xmlns:ns1='urn:partner.soap.sforce.com'>QwWsHJyTPW.1pd0_jXlNKOSU</ns1:SessionHeader>



                        I've tried several other things bug I haven't had much luck.

                        • 9. Re: setHeader and setServerURL, using javax.xml.ws.Service?
                          kbhdk1976

                          Has anyone found a solution to this ? I can't seem to add a complex type as a header, and I can only find simple string type examples.

                          If you have the anwer, please reply to this post.

                          • 10. Re: setHeader and setServerURL, using javax.xml.ws.Service?
                            eric2

                            Wow it's already been a year. Kbhdk1976, to be honest I just used Axis. As far as I can tell JBossws1.2 SP1 doesn't support headers of complex type. I haven't tried the new jbossws so I can't comment on it.

                            • 11. Re: setHeader and setServerURL, using javax.xml.ws.Service?
                              fredk

                              Don't know whether you still need the info, but I found a solution:
                              (examples uses the sf wsdl, but can be applied in general)

                               

                              Soap port = .....
                              SessionHeader sessionHeader = ......
                              // Sessionheader properties
                              QName xmlType = new QName( "urn:enterprise.soap.sforce.com","SessionHeader" );
                              QName xmlName = new QName( "urn:enterprise.soap.sforce.com","SessionHeader" );
                              Class<?> javaType = SessionHeader.class
                              // Register mapping
                              StubExt stub = (StubExt) port;
                              TypeMapping mapping = stub.getEndpointMetaData().getServiceMetaData().getTypeMapping();
                              AbstractSerializerFactory serFactory = new JAXBSerializerFactory();
                              AbstractDeserializerFactory deserFactory = new JAXBDeserializerFactory();
                              mapping.register( javaType, xmlType, serFactory, deserFactory );
                              // Add header to message
                              stub.addUnboundHeader( xmlName, xmlType, javaType, ParameterMode.IN );
                              stub.setUnboundHeaderValue( xmlName, this.sessionHeader );