2009-05-12 9 views
5

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

Это как (пример) услуга выглядит следующим образом:

@Controller 
@Scope("prototype") 
public class UsersController 
{ 
    @RequestMapping(value="https://stackoverflow.com/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> 

This то, как я подключен в моей конфигурации Весна в 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 и все бобы загружаются я навигации по следующему адресу: «Привет, пользователь»

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

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

09:54:45,140 DEBUG RequestContextListener:69 - Bound request context to thread: [email protected] 
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 '[email protected]' 
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: [email protected] 

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

/myserver/services/users/hello, user! 

Любая идея что не так? Что мне не хватает?

ответ

1

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

@Request Documentation

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

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

Далее ответ:

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

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

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

+0

Хм ... Но тогда он разрушает всю идею JAX-RS, которая утверждает, что возвращаемое значение метода отправляется запрашивающей стороне. Есть ли способ аннотировать мои методы, чтобы вышеуказанное требование сохранилось? – IgorM

+1

На javadoc ваш метод принимает аргумент OutputStream или Writer, который RequestMapper будет передавать в ServletOutputStream/Writer для записи. Я не уверен, что это действительно лучший способ сделать это, но это сработает. @RequestMapping (value = "/ users/hello", method = RequestMethod.GET) public void hello (Writer w) { w.write ("hello, user!"); w.flush(); возвращение; } Возможно, вы захотите получить весь HttpServletResponse, а не только Writer, таким образом вы можете установить соответствующие заголовки Http. – Gandalf

+0

Вы можете либо написать ответ прямо в поток, как было предложено выше, либо вы можете вернуть объект ModelAndView, который это делает. Эффект почти такой же. Было бы здорово, если бы Spring 3 использовала новый шаблон HttpMessageConverter для обработки возвращаемых значений метода, но ssdly они применимы только к @RequestBody. Возвращаемые значения метода по-прежнему интерпретируются так, как они были весной 2.5 Помните, что Spring REST MVC является * не * совместимым с JAX-RS, это был явный выбор, который они сделали. JAX-RS просто не подходит с Spring MVC. – skaffman