как маршалировать объект и возвращать его как представление (а не как страницу JSP) в spring + xstream

Я пытаюсь следовать этому руководству и создать службу RESTful, которая может не/маршалировать объект в/из XML. http://www.stupidjavatricks.com/?p=54

В статье выбран маршаллер xStream (я обнаружил, что его очень легко использовать и настраивать).

Дело в том, что, используя STS — собственный вариант Eclipse Spring в комплекте с tcServer — я создал проект на основе шаблона STS MVC. Это устаревший проект, начатый с Spring версии 2.4, и я перенес его на версию 3.0. Итак, шаблон создал всю необходимую XML-разметку, и я добавил свою конфигурацию, чтобы направить представление на правильное преобразование объекта (в маршалер xstream).

Вот часть моего bean-компонента, который отправляет объект в новое представление (скопировано из ссылки):

<bean id="bookXmlView" class="org.springframework.web.servlet.view.xml.MarshallingView">  
     <constructor-arg>  
         <bean class="org.springframework.oxm.xstream.XStreamMarshaller">  
             <property name="autodetectAnnotations" value="true"/>  
         </bean>  
     </constructor-arg>  
</bean>

Все работало хорошо, пока я не установил последнюю версию STS 2.5.2.RELEASE и не создал новый проект MVC из шаблона. (Новый шаблон больше не использует urlrewrite.xml среди некоторых других изменений).

Я установил правильную конфигурацию 1 на 1, как предлагает учебник, но теперь, несмотря ни на что, представление всегда направлено на JSP, поэтому, если мой контроллер выглядит так:

@RequestMapping(value = "/authors/{authorId}")  
public ModelAndView getAuthorById(@PathVariable String authorId) {  
    Author author = bookService.getAuthorById(authorId);  
    ModelAndView mav =new ModelAndView("bookXmlView", BindingResult.MODEL_KEY_PREFIX+"author", author);  
    return mav;  
}

Он всегда будет пытаться вернуться к представлению author.jsp, а не к объекту в виде XML. Я пробовал много вещей без успеха. Любые идеи, почему это происходит и как это исправить?


ОБНОВЛЕНИЕ ------------------- Как уже отмечалось, я добавил журналы:

Я установил его как уровень DEBUG и кое-что обнаружил:

ОТЛАДКА: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping — отклоненное имя компонента «org.springframework.context.annotation.internalConfigurationAnnotationProcessor»: URL-пути не определены
DEBUG< /strong>: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping — отклоненное имя компонента 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor': URL-пути не определены
DEBUG: org .springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping — отклоненное имя компонента «org.springframework.context.annotation.internalRequiredAnnotationProcessor»: пути URL-адресов не определены
DEBUG: org.springframework.web. servlet.mvc.annotation.DefaultAnnotationHandlerMapping — Отклонено имя компонента 'org.springframework.context.annotation.internalCommonAnnotationProcessor': URL-пути не определены
DEBUG: org.springframework.web.servlet.mvc.annotation.Defaul tAnnotationHandlerMapping — отклоненное имя компонента «bookXmlView»: URL-адреса не определены


Обратите внимание на эту строку: Отклоненное имя компонента 'bookXmlView': пути URL не определены. Поиск показал, что может возникнуть конфликт между <mvc:annotation-driven /> и моими автодетектированными аннотациями в настройках xstream?

В любом случае, после вызова ссылки я получил следующую запись в журнале. Обратите внимание, что представление перенаправляется в /WEB-INF/views/bookXmlView.jsp:

ОТЛАДКА: org.springframework.web.servlet.DispatcherServlet — DispatcherServlet с именем «appServlet», обрабатывающий запрос GET для [/test/page_init]
ОТЛАДКА: org.springframework .web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping — сопоставление [/page_init] с HandlerExecutionChain с обработчиком [test.test.test.HomeController@a087de] и двумя перехватчиками
DEBUG: org.springframework. web.servlet.DispatcherServlet — значение Last-Modified для [/test/page_init]: -1
DEBUG: org.springframework.web.bind.annotation.support.HandlerMethodInvoker — запуск обработчика запросов метод: public org.springframework.web.servlet.ModelAndView test.test.test.HomeController.getObject()
DEBUG: org.springframework.beans.factory.support.DefaultListableBeanFactory — вызов afterPropertiesSet( ) в bean-компоненте с именем bookXmlView
DEBUG: org.springframework.web.servlet.DispatcherServlet — Render ing view [org.springframework.web.servlet.view.JstlView: name 'bookXmlView'; URL-адрес [/WEB-INF/views/xmlView.jsp]] в DispatcherServlet с именем «appServlet»
DEBUG: org.springframework.web.servlet.view.JstlView — добавлено объект модели 'org.springframework.validation.BindingResult.books' типа [test.test.test.ObjectTest] для запроса представления с именем 'bookXmlView'
DEBUG: org.springframework.web .servlet.view.JstlView — переадресация на ресурс [/WEB-INF/views/xmlView.jsp] в InternalResourceView 'bookXmlView'
DEBUG: org.springframework.web.servlet.DispatcherServlet — успешно завершенный запрос


person jazzcool    schedule 18.01.2011    source источник
comment
Что говорят ваши журналы? Попробуйте изменить уровни журнала на ALL или DEBUG, чтобы вы могли видеть все выходные данные. Проблема, скорее всего, будет найдена там.   -  person jmort253    schedule 18.01.2011


Ответы (1)


Получил наконец! Сначала я попробовал другой маршаллер - JAXB2, но xstream тоже должен работать.

Далее идет определение - оказывается, конфигурация почему-то использует это (неверно):

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

используя только InternalResourceViewResolver

в то время как определение для org.springframework.web.servlet.view.BeanNameViewResolver игнорируется. Решение для этого состоит в том, чтобы определить их обоих в одном bean-компоненте с именем ContentNegotiatingViewResolver следующим образом:

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="viewResolvers">
            <list>
                    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
                    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                            <property name="prefix" value="/WEB-INF/jsp/" />
                            <property name="suffix" value=".jsp" />
                    </bean>
            </list>
    </property>
</bean>
<oxm:jaxb2-marshaller id="marshaller">
        <oxm:class-to-be-bound name="com.mycompany.dashboard.Person" />
</oxm:jaxb2-marshaller>

<bean name="person" class="org.springframework.web.servlet.view.xml.MarshallingView">
        <constructor-arg ref="marshaller" />
</bean>

Эта конфигурация решила мои проблемы, и объект person, с которым я играл, не был направлен на представление JSP, а маршаллер обратился к XML:

    @RequestMapping(value = "/person", method = RequestMethod.GET)
public ModelAndView addPerson() {
    Person person = new Person();
    person.setAddress("address 123");
    person.setAge(50);
    person.setName("Andrew");
    System.out.println("new person: " + person);
    ModelAndView mav = new ModelAndView("person",BindingResult.MODEL_KEY_PREFIX + "person",person);
    return mav;

Надеюсь, это поможет и другим в будущем.

person jazzcool    schedule 20.01.2011
comment
JAXB — лучший выбор: bdoughan.blogspot. ком/2010/10/ - person bdoughan; 21.01.2011