2009-05-12 9 views
5

Próbuję udostępnić pełną usługę REST (hostowaną przez Tomcat) i nie mogę określić, jaka jest wymagana konfiguracja dla Spring 3 (M3).Jaka jest minimalna konfiguracja usługi w pełni przypisanej do REST zbudowanej na Spring 3 (m3)?

ten sposób (przykład) usługa wygląda następująco:

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

Konfiguracja Wiosna, że ​​mam wygląda następująco (Pomijam pełne nazwy klasy dla uproszczenia):

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

This jest sposób, w jaki podłączyłem moją konfigurację Spring do pliku 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> 

Uwaga, próbuję stworzyć minimalną konfigurację (bez dodatkowych plików servlet-config.xml). Właśnie dlatego kieruję Dispatchera do wbudowanej konfiguracji.

Czy to prawda?

Po zacznę Tomcat, a wszystkie ziarna są ładowane ja przechodząc do następującego adresu URL: „Witaj, użytkownik”

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

I zamiast odpowiadać, do mojej konsternacji, widzę następujące błędy w pliku dziennika:

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] 

Jak można zauważyć, moja obecna konfiguracja próbuje przekierować tę prośbę jako nowe żądanie:

/myserver/services/users/hello, user! 

Każdy pomysł co jest nie tak? czego mi brakuje?

Odpowiedz

1

Zagadnienie to cześć() metoda jest odnotowany jako handlerMethod na wiosnę i na dokumentacji @RequestMapping metody Wózek może zwrócić dowolną liczbę przedmiotów, ale jeśli zwraca String następnie:

@Request Documentation

Wartość ciągu, która jest interpretowana jako nazwa widoku, z modelem niejawnie ustalonym za pomocą obiektów komend i metody Aplated Adnotated Reference accessor. Sposób obsługi można również programowo wzbogacić model deklarując argument ModelMap (patrz wyżej)

Więc to w zasadzie patrząc na mapowaniu na ten ciąg return „witaj” - dla użytkownika, który nie istnieje. Możesz odzyskać swoją metodę, a wewnątrz metody wypisać ją samemu HttpServletResponse.

Dalsze odpowiedź:

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

Możesz dostać całą HttpServletResponse a potem po prostu Writer, w ten sposób można ustawić odpowiednie nagłówki HTTP.

Niestety mój komentarz poniżej jest pomieszany, jestem nowy na tej stronie.

+0

Hmm ... Ale wtedy łamie cały pomysł JAX-RS, który twierdzi, że zwracana wartość metody jest wysyłana do strony żądającej. Czy istnieje sposób opisania moich metod, aby powyższe wymaganie było prawdziwe? – IgorM

+1

W przypadku javadoc twoja metoda pobiera argument OutputStream lub Writer, a RequestMapper przechodzi do ServletOutputStream/Writer, z którego możesz pisać. Nie jestem pewien, czy to naprawdę najlepszy sposób, aby to osiągnąć, ale zadziała. @RequestMapping (wartość = "/ users/hello", method = RequestMethod.GET) publiczny void hello (Writer w) { w.write ("cześć, użytkownik!"); w.flush(); return; } Możesz chcieć uzyskać całe HttpServletResponse, a nie tylko Writer, w ten sposób możesz ustawić odpowiednie nagłówki Http. – Gandalf

+0

Możesz napisać odpowiedź bezpośrednio do strumienia, jak zasugerowano powyżej, lub możesz zwrócić obiekt ModelAndView, który to robi. Efekt jest bardzo podobny. Dobrze byłoby, gdyby Spring 3 używał nowego wzorca HttpMessageConverter do obsługi wartości zwracanych przez metodę, ale ssdly mają zastosowanie tylko do @RequestBody. Wartości zwracane przez metodę są nadal interpretowane tak, jak były na wiosnę 2.5 Pamiętaj, że Spring REST MVC jest * nie * zgodny z JAX-RS, to był wyraźny wybór, który wykonali. JAX-RS po prostu nie pasował do Spring MVC. – skaffman