Какова минимальная конфигурация для полностью аннотированной службы REST, построенной на Spring 3 (m3)? - PullRequest
5 голосов
/ 12 мая 2009

Я пытаюсь предоставить REST-полный сервис (размещенный на Tomcat) и не могу понять, какая конфигурация требуется для Spring 3 (M3).

Так выглядит (пример) служба:

@Controller
@Scope("prototype")
public class UsersController
{
    @RequestMapping(value="/users/hello", method=RequestMethod.GET)
    public String hello()
    {
        return "hello, user!";
    }
}

Конфигурация Spring, которая у меня есть, выглядит следующим образом (для простоты я опускаю полные имена классов):

<beans ...>
    <context:annotation-config />
    <bean class="...AutowiredAnnotationBeanPostProcessor"/>
    <bean class="...DefaultAnnotationHandlerMapping">
    <context:component-scan base-package="com.mycompany.myserver"/>
</beans>

Вот так я подключил свою конфигурацию Spring в web.xml:

    <listener>
            <listener-class>...RequestContextListener</listener-class>
    </listener>
    <!-- Servlets -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>...DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:*:dispatcher-servlet.xml</param-value>  
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

Обратите внимание, что я пытаюсь создать минимальную конфигурацию (без дополнительных файлов servlet-config.xml). Вот почему я указываю Диспетчеру на встроенную конфигурацию.

Это правильно?

После того, как я запустил Tomcat и все бины загружены, я перехожу на следующий URL:

http://localhost:8080/myserver/services/users/hello

И вместо "привет, пользователь!" ответьте, к моему ужасу, я вижу следующие ошибки в файле журнала:

09:54:45,140 DEBUG RequestContextListener:69 - Bound request context to thread: org.apache.catalina.connector.RequestFacade@19299f5
09:54:45,140 DEBUG DispatcherServlet:834 - DispatcherServlet with name 'dispatcher' determining Last-Modified value for [/myserver/services/users/hello]
09:54:45,156 DEBUG DefaultAnnotationHandlerMapping:178 - Mapping [/users/hello] to handler 'com.symantec.repserver.myserver.UsersController@21447f'
09:54:45,171 DEBUG DispatcherServlet:850 - Last-Modified value for [/myserver/services/users/hello] is: -1
09:54:45,171 DEBUG DispatcherServlet:683 - DispatcherServlet with name 'dispatcher' processing GET request for [/myserver/services/users/hello]
09:54:45,218 DEBUG HandlerMethodInvoker:148 - Invoking request handler method: public java.lang.String com.symantec.repserver.myserver.UsersController.hello()
09:54:45,218 DEBUG DefaultListableBeanFactory:1366 - Invoking afterPropertiesSet() on bean with name 'hello, user!'
09:54:45,218 DEBUG DispatcherServlet:1060 - Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'hello, user!'; URL [hello, user!]] in DispatcherServlet with name 'dispatcher'
09:54:45,234 DEBUG InternalResourceView:237 - Forwarding to resource [hello, user!] in InternalResourceView 'hello, user!'
09:54:45,250 DEBUG DispatcherServlet:834 - DispatcherServlet with name 'dispatcher' determining Last-Modified value for [/myserver/services/users/hello, user!]
09:54:45,250 DEBUG DispatcherServlet:842 - No handler found in getLastModified
09:54:45,250 DEBUG DispatcherServlet:683 - DispatcherServlet with name 'dispatcher' processing GET request for [/myserver/services/users/hello, user!]
09:54:45,250  WARN PageNotFound:959 - No mapping found for HTTP request with URI [/myserver/services/users/hello, user!] in DispatcherServlet with name 'dispatcher'
09:54:45,250 DEBUG DispatcherServlet:643 - Successfully completed request
09:54:45,250 DEBUG DispatcherServlet:643 - Successfully completed request
09:54:45,250 DEBUG RequestContextListener:89 - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@19299f5

Как вы заметили, моя текущая конфигурация пытается перенаправить этот запрос как новый запрос:

/myserver/services/users/hello, user!

Есть идеи, что не так? Чего мне не хватает?

1 Ответ

1 голос
/ 13 мая 2009

Проблема в том, что ваш метод hello () аннотирован как метод handlerMethod для Spring и согласно документации @RequestMapping, методы-обработчики могут возвращать любое количество объектов, но если он возвращает String, то:

@ Запросить документацию

Строковое значение, которое интерпретируется как имя представления, при этом модель неявно определяется с помощью объектов команд и методов доступа к аннотированным ссылочным данным ModelAttribute. Метод-обработчик также может программно обогащать модель, объявляя аргумент ModelMap (см. Выше)

Таким образом, он в основном ищет отображение для той строки, которую вы возвращаете 'hello, user' - которой не существует. Вы можете сделать так, чтобы ваш метод возвращал void, а внутри метода выписать HttpServletResponse самостоятельно.

Дальнейший ответ:

@RequestMapping(value="/users/hello", method=RequestMethod.GET) 
public void hello(Writer w) { 
   w.write("hello, user!"); 
   w.flush(); 
   return; 
} 

Возможно, вы захотите получить весь HttpServletResponse, а не только Writer, чтобы вы могли установить соответствующие заголовки Http.

Извините, мой комментарий ниже перемешан, я новичок в этом сайте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...