Announcement Announcement Module
Collapse
No announcement yet.
Using Spring-WS with JAXB2 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using Spring-WS with JAXB2

    Hi !

    I have a question concerning integration of spring-ws with JAXB2.

    I use :
    <dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-oxm</artifactId>
    <version>1.5.0</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-core</artifactId>
    <version>1.5.0</version>
    </dependency>
    <dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-xjc</artifactId>
    <version>2.1.2</version>
    </dependency>
    <dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.1</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-oxm-tiger</artifactId>
    <version>1.5.0</version>
    </dependency>
    <dependency>
    <groupId>javax.xml.soap</groupId>
    <artifactId>saaj-api</artifactId>
    <version>1.3</version>
    <scope>runtime</scope>
    </dependency>
    <dependency>
    <groupId>com.sun.xml.messaging.saaj</groupId>
    <artifactId>saaj-impl</artifactId>
    <version>1.3</version>
    <scope>runtime</scope>
    </dependency>

    My JAXB2 classes are generated by :
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>

    I have a problem with my endpoint. Here's the definition of my endpoint :

    public class LogEndPoint extends MarshallingMethodEndpointAdapter {

    public JAXBElement<LogResponseType> handlelogRequest(JAXBElement<LogRequestType> pRequest) {
    .....
    }

    }

    When I have this definition, Spring-ws says that there's no endpoint associated with my message because JAXBElement does not have the annotation @xmlRootElement

    When I change my definition to :

    public class LogEndPoint extends MarshallingMethodEndpointAdapter {

    public LogResponseType handlelogRequest(LogRequestType pRequest) {
    .....
    }

    }

    I have an exception when Spring-WS wants to invoke my endPoint because object unmarshalled by JAXB is not an LogRequestType but an JAXBElement<LogRequestType>

    So, what's wrong in a my configuration ? What is the good definition for my endPoint ?

    Thanks for all and Thanks for the quality of your product.

  • #2
    You should use define your method as:

    Code:
    public LogResponseType handlelogRequest(JAXBElement<LogRequestType> pRequest) {

    Comment


    • #3
      Thanks for your answer Arjen ! I will test this.

      Comment


      • #4
        Sorry but it doesn't work, I have this exception returned to my client :
        .LogResponseType com.cgi.test.spring.ws.LogEndPoint.handlelogReques t(javax.xml.bind.JAXBElement<com.cgi.test.spring.w s.log.LogRequestType>)]: Does your endpoint implement a supported interface like MessageHandler or PayloadEndpoint?
        at org.springframework.ws.soap.client.core.SoapFaultM essageResolver.resolveFault(SoapFaultMessageResolv er.java:37)
        at org.springframework.ws.client.core.WebServiceTempl ate.handleFault(WebServiceTemplate.java:668)
        at org.springframework.ws.client.core.WebServiceTempl ate.doSendAndReceive(WebServiceTemplate.java:502)
        at org.springframework.ws.client.core.WebServiceTempl ate.sendAndReceive(WebServiceTemplate.java:440)
        at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 289)
        at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 283)
        at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 275)
        at com.cgi.test.spring.ws.client.ClientTest.testAppel (ClientTest.java:36)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at junit.framework.TestCase.runTest(TestCase.java:154 )
        at junit.framework.TestCase.runBare(TestCase.java:127 )
        at junit.framework.TestResult$1.protect(TestResult.ja va:106)
        at junit.framework.TestResult.runProtected(TestResult .java:124)
        at junit.framework.TestResult.run(TestResult.java:109 )
        at junit.framework.TestCase.ruorg.springframework.ws. soap.client.SoapFaultClientException: No adapter for endpoint [public com.cgi.test.spring.ws.log.LogResponseType com.cgi.test.spring.ws.LogEndPoint.handlelogReques t(javax.xml.bind.JAXBElement<com.cgi.test.spring.w s.log.LogRequestType>)]: Does your endpoint implement a supported interface like MessageHandler or PayloadEndpoint?
        at org.springframework.ws.soap.client.core.SoapFaultM essageResolver.resolveFault(SoapFaultMessageResolv er.java:37)
        at org.springframework.ws.client.core.WebServiceTempl ate.handleFault(WebServiceTemplate.java:668)
        at org.springframework.ws.client.core.WebServiceTempl ate.doSendAndReceive(WebServiceTemplate.java:502)
        at org.springframework.ws.client.core.WebServiceTempl ate.sendAndReceive(WebServiceTemplate.java:440)
        at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 289)
        at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 283)
        at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 275)
        at com.cgi.test.spring.ws.client.ClientTest.testAppel (ClientTest.java:36)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at junit.framework.TestCase.runTest(TestCase.java:154 )
        at junit.framework.TestCase.runBare(TestCase.java:127 )
        at junit.framework.TestResult$1.protect(TestResult.ja va:106)
        at junit.framework.TestResult.runProtected(TestResult .java:124)
        at junit.framework.TestResult.run(TestResult.java:109 )
        at junit.framework.TestCase.run(TestCase.java:118)
        at org.eclipse.jdt.internal.junit.runner.junit3.JUnit 3TestReference.run(JUnit3TestReference.java:130)
        at org.eclipse.jdt.internal.junit.runner.TestExecutio n.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:460)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:673)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.run(RemoteTestRunner.java:386)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.main(RemoteTestRunner.java:196)

        It seems to problem is tied to JAXBElement<LogRequestType> parameter :
        MarshallingMethodEndpointAdapter.getUnmarshaller() .supports(method.getParameterTypes()[0]) return false
        because org.springframework.oxm.jaxb.Jaxb2Marshaller.suppo rtsInternal return false
        because clazz.getAnnotation(XmlRootElement.class) = null. clazz is JAXBElement<LogRequestType>

        Comment


        • #5
          OK, I found the problem which resides in the classes generated by JAXB2 and, in fact, in my xsd.

          My previous xsd looks like :

          <element name="logRequest" type="tns:logRequestType"></element>

          <complexType name="logRequestType">
          <sequence>
          <element name="header" type="tns:logHeaderType"></element>
          <element name="logs" type="tns:logType" minOccurs="1" maxOccurs="unbounded"></element>
          </sequence>
          </complexType>

          with this definition, JAXB2 does not generate the annotation @xmlRootElement, so when you unmarshall your xml, it generates a JAXBElement<logRequestType>.

          I change my xsd :

          <element name="logRequest">

          <complexType>
          <sequence>
          <element name="header" type="tns:logHeaderType"></element>
          <element name="logs" type="tns:logType" minOccurs="1" maxOccurs="unbounded"></element>
          </sequence>
          </complexType>
          </element>

          Now, JAXB2 generates a @xmllRootElement and when it unmarshall the xml, it generate a logRequest object, which is compatible with all spring-ws needs.

          conclusion : the xsd types for the request and the response element must be anonymous.

          Comment


          • #6
            Hep with spring ws + jaxb2

            hi,

            I'm trying to use spring ws with jaxb2 marshalling/unmarshalling.
            I have successfully created a webservice with xml parser, but its not what i need.

            I got this exception when I tried to use the service:
            Code:
            08:53:37,808 ERROR [[spring-ws]] Allocate exception for servlet spring-ws
            java.lang.IllegalArgumentException: Resource ServletContext resource [/classpath*:org/springframework/oxm/schema.xsd] does not exist
            	at org.springframework.util.Assert.isTrue(Assert.java:65)
            Here's my xsd file:

            Code:
            	<xs:element name="ServiceManagerActivateRequest">
            		<xs:complexType>
            			<xs:all>
            				<xs:element name="serviceName" type="xs:string" />
            				<xs:element name="parameters" type="xs:string" />
            			</xs:all>
            		</xs:complexType>
            	</xs:element>
            	<xs:element name="ServiceManagerIsActiveRequest">
            		<xs:complexType>
            			<xs:all>
            				<xs:element name="serviceName" type="xs:string" />
            				<xs:element name="parameters" type="xs:string" />
            			</xs:all>
            		</xs:complexType>
            	</xs:element>
            	<xs:element name="ServiceManagerDeactivateRequest">
            		<xs:complexType>
            			<xs:all>
            				<xs:element name="serviceName" type="xs:string" />
            				<xs:element name="parameters" type="xs:string" />
            			</xs:all>
            		</xs:complexType>
            	</xs:element>
            appContext file:

            Code:
            	<bean id="serviceManagerEndPoint"
            		class="br.ctbc.azzu.accounter.ws.ServiceManagerEndPoint">
            		<constructor-arg ref="marshaller" />
            	</bean>
            
            	<bean
            		class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
            		<property name="mappings">
            			<props>
            				<prop
            					key="{<schema>}ServiceManagerActivateRequest">
            					serviceManagerEndPoint
            				</prop>
            				<prop
            					key="{<schema>}ServiceManagerIsActiveRequest">
            					serviceManagerEndPoint
            				</prop>
            				<prop
            					key="{<schema>}ServiceManagerDeactivateRequest">
            					serviceManagerEndPoint
            				</prop>
            			</props>
            		</property>
            		<property name="interceptors">
            			<bean
            				class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
            		</property>
            	</bean>
            
            	<bean id="marshaller"
            		class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            		<property name="classesToBeBound">
            			<list>
            				<value>
            					br.ctbc.azzu.accounter.ws.pojo.ServiceRequest
            				</value>
            			</list>
            		</property>
            		<property name="schema" value="classpath*:org/springframework/oxm/schema.xsd" />
            	</bean>
            
            	<bean id="manager"
            		class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
            		<property name="schema" ref="schema" />
            		<property name="portTypeName" value="HumanResource" />
            		<property name="locationUri"
            			value="<serviceAddress>" />
            		<property name="targetNamespace"
            			value="<schema>/hr/definitions" />
            	</bean>
            
            	<bean id="schema"
            		class="org.springframework.xml.xsd.SimpleXsdSchema">
            		<property name="xsd" value="/WEB-INF/hr.xsd" />
            	</bean>
            </beans>
            Any help would be great.

            thanks,

            Andre

            Comment

            Working...
            X