Announcement Announcement Module
Collapse
No announcement yet.
Soap 1.2: content type is application/soap+xml Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Soap 1.2: content type is application/soap+xml

    Hello,

    I run into a problem when using spring-ws together with Flickr. Looks like their respons HTTP header follows the Soap 1.2 standard by sending a content type of application/soap+xml.

    I followed the client demo from the doc and when running it, I got the exception:

    Code:
    Caused by: com.sun.xml.internal.messaging.saaj.soap.SOAPVersionMismatchException: Cannot create message: incorrect content-type for SOAP version. Got: application/soap+xml; charset=utf-8 Expected: text/xml
    	at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.init(MessageImpl.java:356)
    	... 11 more
    Obviously, content type text/xml, according to Soap spec 1.0 is expected...

    Here is my spring setup and my class:

    Code:
    	<bean id="flickrService" class="org.springframework.ws.client.core.WebServiceTemplate" lazy-init="false">
    		<property name="messageFactory">
    			<bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
    			</bean>
    		</property>
    		<property name="messageSender" ref="messageSender" />
    	</bean>
    	
    	<bean id="messageSender" class="org.springframework.ws.transport.http.HttpUrlConnectionMessageSender" />
    	
    	<bean id="myClient" class="xxx.xxx.soap.DemoSOAPClient" lazy-init="false">
    		<property name="defaultUri" value="http://api.flickr.com/services/soap/" />
    	</bean>
    Code:
    public class DemoSOAPClient {
    
    	private WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    	
    	private static final String MESSAGE = "<message xmlns=\"x\">Hello Web Service World</message>";
    
        public void setDefaultUri(String defaultUri) {
            webServiceTemplate.setDefaultUri(defaultUri);
        }
    
        // send to the configured default URI
        public void simpleSendAndReceive() {
            StreamSource source = new StreamSource(new StringReader(MESSAGE));
            StreamResult result = new StreamResult(System.out);
            webServiceTemplate.sendSourceAndReceiveToResult(source, result);
        }
    
        // send to an explicit URI
        public void customSendAndReceive() {
            StreamSource source = new StreamSource(new StringReader(MESSAGE));
            StreamResult result = new StreamResult(System.out);
            webServiceTemplate.sendSourceAndReceiveToResult("http://api.flickr.com/services/soap/", source, result);
        }
    	
    }
    Note: I am aware, that this request will not result in a successful response from Flickr. But at least I should get back an error response... not an exception.

    Any suggestion on how to set the expected content type?

    Thanks, Regards raoul

  • #2
    Try setting the soapVersion property on the message factory bean, like so:

    Code:
    <bean id="flickrService" class="org.springframework.ws.client.core.WebServiceTemplate">
      <property name="messageFactory">
        <bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
          <property name="soapVersion">
            <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_12"/>
          </property>
        </bean>
      </property>
      <property name="messageSender" ref="messageSender" />
    </bean>

    Comment


    • #3
      Hi Arjen,

      thanks a lot for your help, I did not find anything on this on google or in the documentation. however, i still run into the same problem, it looks like spring creates four instances of SaajSoapMessageFactory, 3 for SOAP 1.1 and 1 for SOAP 1.2. It is unclear to me why this happens.

      Code:
      09:34:58 [main] INFO  Creating SAAJ 1.3 MessageFactory with SOAP 1.2 Protocol
      Code:
      09:34:58 [main] INFO  Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
      Here is the full startup log:

      Code:
      09:34:58 [main] DEBUG Loading bean definitions at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:84)
      09:34:58 [main] DEBUG Using generated bean name [util:constant#1ea5671] for nested custom element 'util:constant' at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseNestedCustomElement(BeanDefinitionParserDelegate.java:1307)
      09:34:58 [main] DEBUG Neither XML 'id' nor 'name' specified - using generated bean name [org.springframework.ws.soap.saaj.SaajSoapMessageFactory#1d15445] at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseBeanDefinitionElement(BeanDefinitionParserDelegate.java:403)
      09:34:58 [main] DEBUG Loaded 3 bean definitions from location pattern [spring.xml] at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:160)
      09:34:58 [main] INFO  Bean factory for application context [org[email protected]1050169]: org.s[email protected]704baa at org.springframework.context.support.ClassPathXmlApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:410)
      09:34:58 [main] DEBUG 3 beans defined in org[email protected]1050169: display name [org[email protected]1050169]; startup date [Mon Oct 01 09:34:57 CEST 2007]; root of context hierarchy at org.springframework.context.support.ClassPathXmlApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:414)
      09:34:58 [main] DEBUG Unable to locate MessageSource with name 'messageSource': using default [[email protected]4ed] at org.springframework.context.support.ClassPathXmlApplicationContext.initMessageSource(AbstractApplicationContext.java:631)
      09:34:58 [main] DEBUG Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.[email protected]27e353] at org.springframework.context.support.ClassPathXmlApplicationContext.initApplicationEventMulticaster(AbstractApplicationContext.java:655)
      09:34:58 [main] INFO  Pre-instantiating singletons in org.s[email protected]704baa: defining beans [flickrService,messageSender,myClient]; root of factory hierarchy at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:370)
      09:34:58 [main] DEBUG Creating shared instance of singleton bean 'flickrService' at org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton(DefaultSingletonBeanRegistry.java:159)
      09:34:58 [main] DEBUG Creating instance of bean 'flickrService' with merged definition [Root bean: class [org.springframework.ws.client.core.WebServiceTemplate]; scope=singleton; abstract=false; lazyInit=false; autowireCandidate=true; autowireMode=0; dependencyCheck=0; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [spring.xml]] at org.springframework.beans.factory.support.DefaultListableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:469)
      09:34:58 [main] INFO  Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.afterPropertiesSet(SaajSoapMessageFactory.java:107)
      09:34:58 [main] DEBUG Eagerly caching bean 'flickrService' to allow for resolving potential circular references at org.springframework.beans.factory.support.DefaultListableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520)
      09:34:58 [main] DEBUG Creating instance of bean 'org.springframework.ws.soap.saaj.SaajSoapMessageFactory#1d15445' with merged definition [Root bean: class [org.springframework.ws.soap.saaj.SaajSoapMessageFactory]; scope=singleton; abstract=false; lazyInit=false; autowireCandidate=true; autowireMode=0; dependencyCheck=0; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [spring.xml]] at org.springframework.beans.factory.support.DefaultListableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:469)
      09:34:58 [main] DEBUG Creating instance of bean 'util:constant#1ea5671' with merged definition [Root bean: class [org.springframework.beans.factory.config.FieldRetrievingFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireCandidate=true; autowireMode=0; dependencyCheck=0; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] at org.springframework.beans.factory.support.DefaultListableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:469)
      09:34:58 [main] INFO  Creating SAAJ 1.3 MessageFactory with SOAP 1.2 Protocol at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.afterPropertiesSet(SaajSoapMessageFactory.java:107)
      09:34:58 [main] DEBUG Creating shared instance of singleton bean 'messageSender' at org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton(DefaultSingletonBeanRegistry.java:159)
      09:34:58 [main] DEBUG Creating instance of bean 'messageSender' with merged definition [Root bean: class [org.springframework.ws.transport.http.HttpUrlConnectionMessageSender]; scope=singleton; abstract=false; lazyInit=false; autowireCandidate=true; autowireMode=0; dependencyCheck=0; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [spring.xml]] at org.springframework.beans.factory.support.DefaultListableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:469)
      09:34:58 [main] DEBUG Eagerly caching bean 'messageSender' to allow for resolving potential circular references at org.springframework.beans.factory.support.DefaultListableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520)
      09:34:58 [main] DEBUG Returning cached instance of singleton bean 'messageSender' at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(AbstractBeanFactory.java:200)
      09:34:58 [main] DEBUG Creating shared instance of singleton bean 'myClient' at org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton(DefaultSingletonBeanRegistry.java:159)
      09:34:58 [main] DEBUG Creating instance of bean 'myClient' with merged definition [Root bean: class [ch.efgfp.soap.DemoSOAPClient]; scope=singleton; abstract=false; lazyInit=false; autowireCandidate=true; autowireMode=0; dependencyCheck=0; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [spring.xml]] at org.springframework.beans.factory.support.DefaultListableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:469)
      09:34:58 [main] INFO  Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.afterPropertiesSet(SaajSoapMessageFactory.java:107)
      09:34:58 [main] DEBUG Eagerly caching bean 'myClient' to allow for resolving potential circular references at org.springframework.beans.factory.support.DefaultListableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520)
      09:34:58 [main] DEBUG Publishing event in context [org[email protected]1050169]: org.springframework.context.event.ContextRefreshedEvent[source=org[email protected]1050169: display name [org[email protected]1050169]; startup date [Mon Oct 01 09:34:57 CEST 2007]; root of context hierarchy] at org.springframework.context.support.ClassPathXmlApplicationContext.publishEvent(AbstractApplicationContext.java:258)
      When it then comes to parsing the response, it looks like an instance of the SOAP 1.1 flavour would be used...
      Maybe this is a more spring "general" question. Any ideas?

      Best regards raoul

      Comment


      • #4
        Well, you should inject the template created by Spring (which SOAP 1.2) into your DemoSOAPClient. Right now, you are creating one (named flickrService in the app context), and the DemoSOAPCLient is creating a default one (with default SOAP 1.1 settings). So that's why you end up with two entries in the log.

        So, do this:
        Code:
        public class DemoSOAPClient {
        
        	private WebServiceTemplate webServiceTemplate;
        	
        	private static final String MESSAGE = "<message xmlns=\"x\">Hello Web Service World</message>";
        
           public DemoSOAPClient(WebServiceTemplate template) {
             this.webServiceTemplate = template;
           }
        
            public void setDefaultUri(String defaultUri) {
                webServiceTemplate.setDefaultUri(defaultUri);
            }
        
            // send to the configured default URI
            public void simpleSendAndReceive() {
                StreamSource source = new StreamSource(new StringReader(MESSAGE));
                StreamResult result = new StreamResult(System.out);
                webServiceTemplate.sendSourceAndReceiveToResult(source, result);
            }
        
            // send to an explicit URI
            public void customSendAndReceive() {
                StreamSource source = new StreamSource(new StringReader(MESSAGE));
                StreamResult result = new StreamResult(System.out);
                webServiceTemplate.sendSourceAndReceiveToResult("http://api.flickr.com/services/soap/", source, result);
            }
        And then config, in addition to what I wrote above:

        Code:
        	<bean id="myClient" class="xxx.xxx.soap.DemoSOAPClient" lazy-init="false">
                         <constructor-arg ref="flickrService"/>
        		<property name="defaultUri" value="http://api.flickr.com/services/soap/" />
        	</bean>

        Comment


        • #5
          Works!

          Hi Arjen,

          Thanks a lot for your precise help. That was obviously the problem. Sorry I did not realize. Thank you!

          Regards Raoul

          Comment

          Working...
          X