System property "javax.xml.soap.MessageFactory" for two different soap versions
Asked Answered
L

1

9

i need to communicate with two webservices from my application. For one webservice i need to use soap1_1 version and for the other soap version is soap1_2. In this case what should be the value set for the system property "javax.xml.soap.MessageFactory"

Client 1:

public class SoapClient1 {


protected static Logger _logger = Logger.getLogger ("TEST");
private static Long retryDelay = null;


public String sendSoapMessage (String xml) throws Exception {

    SOAPMessage resp  = null;
    String response = null;
    String endpoint = "http:xxxx";



    System.setProperty("javax.xml.soap.MessageFactory","com.sun.xml.internal.messaging.saaj.soap.ver1_2.SOAPMessageFactory1_2Impl");
    SOAPConnectionFactory connectionFactory = SOAPConnectionFactory.newInstance();
    SOAPConnection soapConnection = connectionFactory.createConnection();

    long start = System.currentTimeMillis();
    long end = System.currentTimeMillis();

    //URL endPoint = new URL(endpoint);

    //setting connection time out and read timeout

    URL endPoint = new URL (null, endpoint, new URLStreamHandler () {
        @Override
        protected URLConnection openConnection (URL url) throws IOException {

            URL clone = new URL (url.toString ());
            URLConnection connection = clone.openConnection ();
            connection.setConnectTimeout (60000);
            connection.setReadTimeout (60000);
            // Custom header

            return connection;
        }});


    try{

        start = System.currentTimeMillis();


            resp = soapConnection.call(getSoapRequest(xml), endPoint);      

        end = System.currentTimeMillis();

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        resp.writeTo(os);
        response = os.toString();


        if (!resp.getSOAPBody().hasFault()) {

            response = "SucCess:" + response;

            }else{

                response = "FaiLure:" + response;
            }

        }else{

            response = "FaiLure:" + response;
        }


    }catch(SOAPException se){
        _logger.log(Level.ERROR," Service Provisioning Call Failed");
        _logger.log(Level.ERROR,"The call duration before SOAPException =" +(end-start)+" ms.");

        se.printStackTrace();
        throw se;
    }

    soapConnection.close();
    return response;
}


private SOAPMessage getSoapRequest(String xml) throws SOAPException,Exception{

    MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    /* Create a SOAP message object. */
    SOAPMessage soapMessage = mf.createMessage();
    SOAPPart soapPart = soapMessage.getSOAPPart();
    SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
    SOAPBody soapBody = soapEnvelope.getBody();
    soapEnvelope.getHeader().detachNode();
    soapEnvelope.addNamespaceDeclaration("soap","http://yyyy");
    SOAPHeader header = soapEnvelope.addHeader();



    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    builderFactory.setNamespaceAware(true);

    InputStream stream  = new ByteArrayInputStream(xml.getBytes());
    Document doc = builderFactory.newDocumentBuilder().parse(stream);

    _logger.log(Level.DEBUG, "Adding SOAP Request Body");
    soapBody.addDocument(doc);

    soapMessage.saveChanges();

    return soapMessage;

}
}

sample request

<?xml version="1.0" encoding="UTF-8"?>
       <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:soap="http://bridgewatersystems.com/xpc/tsc/entity/soap">
      <env:Header/>
        <env:Body>
             <TempTierChangeRequest xmlns="http://bridgewatersystems.com/xpc/tsc/entity/soap" credentials="root" principal="root">
           <temp-tier-change xmlns="">
                <service-components>
                     <service-component name="DSL_Tier_2"/>
                </service-components>
                <duration-sec>300</duration-sec>
                <description>1024 SC</description>
                <activation-date>2017-02-09T10:29:16</activation-date>
                <subscriber-id>[email protected]</subscriber-id>
                <partition-key>26752018010</partition-key>
                <ttc-id>3706043</ttc-id>
                <validity-period>
                     <duration>30</duration>
                     <expires-with-billing-reset>1</expires-with-billing-reset>
                </validity-period>
           </temp-tier-change>
      </TempTierChangeRequest>
      </env:Body>
      </env:Envelope>
Lamarckian answered 25/1, 2017 at 8:39 Comment(0)
U
5

It is not possible to set the value of System variable javax.xml.soap.MessageFactory for two different purposes. The default value is set for SOAP 1.1

Remove the system property javax.xml.soap.MessageFactory and depending on the type of client you are building use

Building the soap message with MessageFactory.newInstance()

If you want SOAP1.1, use the default constructor

 MessageFactory factory = MessageFactory.newInstance();

If you want SOAP1.2, use

MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);

See Java Tutorial.

JAX-WS clients configured with annotations @BindingType

@BindingType is used when the JAX-WS client is configured using annotations, for example if client is generated from WSDL. The annotation is added to Port to set the binding to SoapBinding.SOAP11HTTP_BINDING or SoapBinding.SOAP12HTTP_BINDING.

@WebService(targetNamespace = "https://myservice.services.com", name = "myserviceProxyProt")
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public interface MyServiceProxyPort {
Unrepair answered 4/2, 2017 at 9:32 Comment(17)
I am building two clients to talk to two different webservices. have added the sample code of the two clients. For both the clients i am using almost the same bit of code, just the endpoint differs. For both cases, i am building the body part of the request using xslt and passing the generated xml as input to the soapclientLamarckian
I have updated the answer. See in the first case how to configure MessageFactory.newInstance() for Soap 1.1 or 1.2Unrepair
i was doing the same earlier, but i was getting unsupported version error while parsing the response. the default value of javax.xml.xoap.messageFactory was set to SOAP1.1 and the response received was of soap1_2, so i added System.setProperty("javax.xml.soap.MessageFactory","com.sun.xml.internal.messaging.saaj.soap.ver1_2.SOAPMessageFactory1_2Impl"); to the code and it resolved the issue, i am yet to test the other interface which is of soap1.1 but i believe i will get the same unsupported errorLamarckian
Maybe is a namespace issue because you are writting directly the XML content. See diferences between SOAP11 and SOAP12 here herongyang.com/Web-Services/…. Please, set soapEnvelope.addNamespaceDeclaration("soap","http://schemas.xmlsoap.org/soap/envelope/"); for soap11 and soapEnvelope.addNamespaceDeclaration("soap","http://www.w3.org/2003/05/soap-envelope"); for soap12Unrepair
do you mean, i should set the namespace explicitly even after setting the binding type?Lamarckian
Setting the binding type will add the namespace, but the soap body you add should reference to the correct namespace. And the are different in 1.1 and 1.2. Could you check if they match?Unrepair
the soap body has the proper namespace and all the body elements belong to one namespace defined by the webserviceLamarckian
I have executed the code configuring MessageFactory.newInstance(protocol) with SOAPConstants.SOAP_1_2_PROTOCOL or SOAPConstants.SOAP_1_1_PROTOCOL and generates the SOAP message properly in each case. May be you have a different issue. Could you post an example soap message for each protocol?Unrepair
i found something on google related to this issue theholyjava.wordpress.com/2010/11/19/…Lamarckian
Are you using axis1.2 with java 1.6? I suppose you were using JDK's built in support for soapUnrepair
yes i am using the built in soap support. Just curious what are the default values for the below system properties. i feel i messed up with these values. javax.xml.soap.SOAPFactory javax.xml.soap.MessageFactory javax.xml.soap.SOAPConnectionFactoryLamarckian
i have set the system property javax.xml.soap.MessageFactory to default value which is "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl" and tried to generate the soap request of version 1.2. getting "java.security.PrivilegedActionException: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to internalize message" error adding the request generatedLamarckian
I really think that on the client there is nothing special that has to be done. JAX-WS runtime can look into the WSDL to determine the binding being used and configures itself accordingly. If you really want to change the binding on the fly you could try to use reflectionOneupmanship
@Oneupmanship OP is not using jax-ws client and is not configuring the client using the WSDL bindings. He is bulding the SOAP message manually so it is needed a client configuration to specify different headers according the protocol supported by serverUnrepair
then he could use reflection to change the bindings on the flyOneupmanship
@Tom, really changing MessageFactory.newInstance() with soap_1_1 or soap1_2 parameter should do the work. But for some reason it is not working for OPUnrepair
@Oneupmanship can you give sample code on how to use reflection for binding on the fly.Lamarckian

© 2022 - 2024 — McMap. All rights reserved.