Announcement Announcement Module
Collapse
No announcement yet.
issue with JAXB marshalling Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • issue with JAXB marshalling

    I'm trying a very simple service using Jaxb marshalling but am having a slight issue.

    When the request hits the service method it is of type JABXElement rather than the type that has been compiled from the xml schema. I have a very minimal application context:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
    	<bean id="describeInstancesHandler" class="com.bt.koala.clustercontroller.DescribeInstancesHandler">
    		<property name="marshaller" ref="marshaller" />
    		<property name="unmarshaller" ref="marshaller" />
    	</bean>
    
    	<bean id="endpointMapping"
    		class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
    		<property name="mappings">
    			<props>
    				<prop key="{http://eucalyptus.ucsb.edu/}DescribeInstances">describeInstancesHandler</prop>
    			</props>
    		</property>
    		<property name="interceptors">
    			<list>
    				<bean
    					class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
    			</list>
    		</property>
    	</bean>
    
    	<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    		<property name="classesToBeBound">
    			<list>
    				<value>edu.ucsb.eucalyptus.DescribeInstancesType</value>
    				<value>edu.ucsb.eucalyptus.DescribeInstancesResponseType</value>
    				<value>edu.ucsb.eucalyptus.EucalyptusMessage</value>
    			</list>
    		</property>
    	</bean>
    </beans>
    and a simple service class:

    Code:
    package com.bt.koala.clustercontroller;
    
    import javax.xml.bind.JAXBElement;
    
    import org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint;
    
    public class DescribeInstancesHandler extends AbstractMarshallingPayloadEndpoint {
    
    	public DescribeInstancesHandler(){}
    	
    	@Override
    	protected Object invokeInternal(Object request) throws Exception {
    		System.out.println(request.getClass().getName());
    		System.out.println(((JAXBElement)request).getDeclaredType());
    		return "OK";
    	}
    }
    When invoked, the service prints:

    [java] javax.xml.bind.JAXBElement
    [java] class edu.ucsb.eucalyptus.DescribeInstancesType

    Please can you help me? I'm sure I'm missing something simple here!

    Thanks.

  • #2
    The parameters and the return types of the spring web services (when using JAXB marshalling) should always be JAXBElement<SCHEMATYPE>.

    If you want to obtain the actual object that was passed to you, use request.getValue() to obtain the SCHEMATYPE object you've been passed.

    Also, remember to wrap your result in a JAXBElement before returning it.

    Comment


    • #3
      OK, thanks. This is not quite as nice as the airline example suggests, perhaps jaxb1 was a better interface?

      I have reverted to using xmlbeans which is a neater spring-ws, although the xmlbeans api takes a bit of getting used to!

      Thanks for the reply.

      Comment


      • #4
        This is a side affect of JAXB and the way your schema is structured.

        If your request/response types are also declared as elements, rather than just types, JAXB generates this type of binding

        Comment


        • #5
          can you try setting the schema property to the Jaxb2Marshaller.

          DescribeInstances is that your top element?

          Or you could always do something like this to see your Jaxb elements are all good

          your class implements PayloadEndpoint

          public Source invoke(Source src) throws Exception {
          SOAPEnvelope envelope = soapMessage.getSOAPPart().getEnvelope();
          Transformer transformer = TransformerFactory.newInstance().newTransformer();
          Result outputResult = new StringResult();
          transformer.transform(source, outputResult);

          String marshalled = outputResult.toString();
          JAXBContext context = ...

          Object mysterious = context.createUnmarshaller().unmarshal(marshalled) ;

          System.out.printf("Object type %s", mysterious.getClass().getName());

          Source resultSource = new StringSource("<response>xml");
          return resultSource ;
          }

          Comment

          Working...
          X