Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: jazzcoolОтветов: 1

Я пытаюсь следовать этому руководству и создать службу 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: 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 - успешно завершенный запрос

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

spring-mvcmarshallingxstream

Ответы

Ответ 1 · рейтинг 2 · jazzcool

Получил наконец! Сначала я попробовал другой маршаллер - 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;

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы