Results 1 to 3 of 3

Thread: Simple XML Binding in Spring MVC

  1. #1
    Join Date
    Oct 2010
    Posts
    2

    Default Simple XML Binding in Spring MVC

    I am using ContentNegotiatingViewResolver in my spring config to setup json, xml, xls, and html (via jstl) outputs from a RESTful service using MVC.

    All of these outputs are functioning, but the XML output is very verbose.

    In the MVC, I have this:

    Code:
    @Secured({"ROLE_USER"})
    @RequestMapping(value = "/api/person/{personid}", method = RequestMethod.GET)
    public ModelAndView GetPerson(@PathVariable("personid") long personid)
    {
       // some code here
       return mav;
    }
    and when I go to someserver/someapp/api/person/1.json its perfect, 1.html works great going to the view I return in the MAV.

    However, when I select XML, I get > 100kb of what appears to be complete state information, with pages/pages/pages of serialization stuff. Here is a snippet:

    Code:
    <org.springframework.validation.BeanPropertyBindingResult>
    <nestedPath/>
    <nestedPathStack serialization="custom">
    <unserializable-parents/>
    <vector>
    <default>
    <capacityIncrement>0</capacityIncrement>
    <elementCount>0</elementCount>
    
    thousands of lines omitted for brevity
    then at the very bottom, I see this:

    Code:
    <target class="PersonOutput">
    <code>100</code>
    <message>Success</message>
    <person>
    <Person>
    <personid>6335</personid>
    <Events class="org.hibernate.collection.PersistentBag">
    <initialized>true</initialized>
    
    dozen of lines omitted for brevity
    which is a reasonable representation of what I actually want (notice I am using hibernate).

    I am using this View in my spring config:

    Code:
    <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
    <constructor-arg>
    <bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
    </constructor-arg>
    </bean>
    What I really want is a very simplistic xml representation without all of the serialization or rpc type output which is suitable for another application to use as a data file (not to re-instate the object somewhere else).

    This is how the json output works, what can I do to get the XML to work as well?

    Thanks in advance,

    Tim

  2. #2
    Join Date
    Dec 2010
    Posts
    2

    Default

    Hi Tim!

    I had the same problem - the spring model map will have two entries, the BeanPropertyBindingResult and your own model. As XStreamMarshaller by default will handle any class, it unfortunately just marshalls the first thing it finds in this map, which may be the BeanPropertyBindingResult.

    There are different solutions:

    1) Explicitly name the supported classes - in my case combined with the annotatedClasses (for support of e.g. @XStreamAlias). XStreamMarshaller now refuses to render BeanPropertyBindingResult:
    Code:
    <bean id="xStreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller" >
    		<property name="supportedClasses">
    			<list>
    				<value>foo.bar.MyModel</value>
    				...
    			</list>
    		</property>
    		<property name="annotatedClasses">
    			<list>
    				<value>foo.bar.MyModel</value>
    				...
    			</list>
    		</property>
    </bean>
    2) Another possible way is to let the marshaller know whats the key for your model:
    Code:
    @Controller
    public class MyController {
    	...
    	@RequestMapping(...)
    	public ModelAndView myMethod(...) {
    			...
    			return new ModelAndView("viewName", "my_model_key", myModel);
    	}
    }
    Code:
    <bean id="xStreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller" >
    		<property name="modelKey">my_model_key</property>
    </bean>
    3) You may also try using the @ModelAttribute annotation as suggested in this thread

    Hope this helps!
    Regards
    Slowpoke

  3. #3
    Join Date
    Oct 2010
    Posts
    2

    Default

    Thanks a lot for your reply.

    This solution works great:

    Code:
    <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
    	<constructor-arg>
            	<bean class="org.springframework.oxm.xstream.XStreamMarshaller">
    			<property name="autodetectAnnotations" value="true"/>
              		<property name="supportedClasses">
    	  			<list>
    	    				<value>java.util.List</value>
    	    				<value>api.interchange.PersonOutput</value>
    	  			</list>
    			</property>
              			
              	</bean>
            </constructor-arg>
    </bean>
    And that worked great. I am not sure why XStream requires this while Jackson just works...

    Thanks for your reply, I appreciate the alternative methods.

    Tim

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •