Создание представления XML с помощью XStreamMarshaller Spring

Я использую Spring Framework 3.1 (с Hibernate), и я пытаюсь создать представление XML, как:

<user>
<iduser>1</iduser>
<email>bla@hello.com</email>
<firstName>bob</firstName>
</user>

из этого Java-класса:

@Entity
public class User {

    @GenericGenerator(name = "table-hilo-generator", strategy = "org.hibernate.id.IncrementGenerator")
    @GeneratedValue(generator = "table-hilo-generator")
    @Id
    @Column(name = "iduser", unique = true, nullable = false)
    private int iduser;

    @NotBlank
    @NotNull
    @NotEmpty
    @Length(max = EMAIL_MAX_SIZE)
    @Column(name = "email", nullable = false)
    private String email;

    @NotBlank
    @NotNull
    @NotEmpty
    @Length(max = FIRST_NAME_MAX_SIZE)
    @Column(name = "firstName", nullable = false)
    private String firstName;
}

мой servlet-conf.xml содержит это представление в ContentNegotiatingViewResolver:

<!-- XML View -->
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
  <constructor-arg>
    <bean class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="aliases">
        <map>
                <entry key="user123" value="com.....entities.User" />
        </map>
        </property>
    </bean>
   </constructor-arg>
</bean>

Но я не понимаю, почему в результате получается странный xml с сотнями элементов, таких что:

<org.springframework.validation.BeanPropertyBindingResult>
<nestedPath/>
<nestedPathStack serialization="custom">
<unserializable-parents/>
<vector>
<default>
<capacityIncrement>0</capacityIncrement>
<elementCount>0</elementCount>
<elementData>
<null/>
<null/>
<null/>
<null/>
<null/>
<null/>
<null/>
<null/>
<null/>
<null/>
</elementData>
</default>
</vector>
</nestedPathStack>
<objectName>user</objectName>
<messageCodesResolver class="org.springframework.validation.DefaultMessageCodesResolver">
<prefix/>

1-Вероятно, маршаллер слишком много играет с отражением, как я могу получить ожидаемый результат, который я хочу? ( 2-я заинтересован также в создании XML-файла со списком пользователей) Как я могу это сделать?

2 ответа

Решение

Как вы уже заметили, происходит то, что, поскольку вы не указали явный ключ модели, который нужно сериализовать, он сериализует первый ненулевой объект модели, который в этом случае будет BindingResult(используется для хранения ошибок привязки / проверки в вашей модели). Есть несколько исправлений, которые вы можете сделать:

а. Укажите точный modelKey для вашего представления о маршаллинге это должно сработать и установить модель для конкретного ключа модели:

<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller">
...
</property>
<property name="modelKey" value="command"/>
</bean>

model.addAttribute("command", mymodel);

б. Лучшим решением, IMHO, может быть использование http-конвертеров в Spring, таким образом вы можете вернуть свой объект из метода сопоставленного запроса, аннотировать его @ResponseBody а Spring позаботится о преобразовании объекта в проводное представление (xml или json и т. д.), вам просто нужно зарегистрировать правильный преобразователь:

@RequestMapping(...)
public @ResponseBody User myMethod(Model model){
    return user;
}

<mvc:annotation-driven conversion-service="conversionService"> 
   <mvc:message-converters register-defaults="false"> <!-- you may have to explicitly register other converters though-->
       <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
           <property name="marshaller">
               <bean class="org.springframework.oxm.xstream.XStreamMarshaller"/>
           </property>
       </bean>
   </mvc:message-converters>

У меня была та же ошибка с XStream, и она была решена путем применения следующего изменения:

Вместо того, чтобы добавить modelKey, вы можете добавить свойство "selectedClasses" к бину Marshaller:


<bean class="org.springframework.oxm.xstream.XStreamMarshaller">
    <property name="autodetectAnnotations" value="true"/>
    <property name="supportedClasses">
        <list>
            <value>com.rest.example.model.User</value>
        </list>
    </property>
</bean>

Во-вторых, класс User должен быть аннотирован псевдонимом XStream, в противном случае вы получите полное имя пакета в XML - например: <com.rest.example.model.User> вместо <user> - способ исправить это:

@XStreamAlias("user")
public class User {
...
Другие вопросы по тегам