Search code examples
spring-mvcxstream

Spring MVC 3.2 - XStreamAlias Ignored


Person.java:

@XStreamAlias("person")
public class Person {
    @XStreamAlias("id")
    private Long personProfileId;
    private String lastName;
    private String firstName;
    private String middleName;
    private String nameSuffix;
    private String namePrefix;

    // etc ...
}

Spring configuration:

<bean id="contentNegotiationManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="true" />
    <property name="ignoreAcceptHeader" value="true" />
    <property name="useJaf" value="false" />
    <property name="defaultContentType" value="application/xml" />

    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
        </map>
    </property>
</bean>

<bean
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1" />
    <property name="contentNegotiationManager" ref="contentNegotiationManager" />

    <property name="defaultViews">
        <list>
            <bean
            class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />

            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <constructor-arg>
                    <bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
                </constructor-arg>
            </bean>
        </list>
    </property>
</bean>

<mvc:annotation-driven
    content-negotiation-manager="contentNegotiationManager" />

A call to http://mycompany.com:8080/myapp/persons?format=xml returns:

<?xml version="1.0" encoding="UTF-8"?>
<list>
<com.example.myapp.model.Person>
    <personProfileId>1</personProfileId>
    <lastName>McCartney</lastName>
    <firstName>James</firstName>
    <middleName>Paul</middleName>
</com.example.myapp.model.Person>
<com.example.myapp.model.Person>
    <personProfileId>2</personProfileId>
    <lastName>Lennon</lastName>
    <firstName>John</firstName>
    <middleName>Winston</middleName>
</com.example.myapp.model.Person>
<com.example.myapp.model.Person>
    <personProfileId>3</personProfileId>
    <lastName>Starkey</lastName>
    <firstName>Richard</firstName>
</com.example.myapp.model.Person>
<com.example.myapp.model.Person>
    <personProfileId>4</personProfileId>
    <lastName>Harrison</lastName>
    <firstName>George</firstName>
</com.example.myapp.model.Person>
</list>

I would expect it to return:

<?xml version="1.0" encoding="UTF-8"?>
<list>
<Person>
    <id>1</id>
    <lastName>McCartney</lastName>
    <firstName>James</firstName>
    <middleName>Paul</middleName>
</Person>
<Person>
    <id>2</id>
    <lastName>Lennon</lastName>
    <firstName>John</firstName>
    <middleName>Winston</middleName>
</Person>
<Person>
    <id>3</id>
    <lastName>Starkey</lastName>
    <firstName>Richard</firstName>
</Person>
<Person>
    <id>4</id>
    <lastName>Harrison</lastName>
    <firstName>George</firstName>
</Person>
</list>

It seems like XStream is correctly being called to marshall the object to XML, but that the @XStreamAlias annotations are being ignored. Is there some further configuration needed to get this to work?


Solution

  • Figured it out. The annotated classes need to be explicitly identified to the XStreamMarshaller.

    <property name="defaultViews">
        <list>
            <bean
            class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
    
            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <constructor-arg>
                    <bean class="org.springframework.oxm.xstream.XStreamMarshaller">
                        <property name="annotatedClasses">
                            <array>
                                <value>com.example.myapp.model.Person</value>
                            </array>
                        </property></bean>
                </constructor-arg>
            </bean>
        </list>
    </property>