Estoy tratando de exponer un servicio REST completo (alojado por Tomcat) y no puedo averiguar cuál es la configuración requerida para Spring 3 (M3).¿Cuál es la configuración mínima para el servicio REST-completamente anotado construido en Spring 3 (m3)?
Esta es la forma (ejemplo) el servicio será similar a:
@Controller
@Scope("prototype")
public class UsersController
{
@RequestMapping(value="https://stackoverflow.com/users/hello", method=RequestMethod.GET)
public String hello()
{
return "hello, user!";
}
}
La configuración de Spring que tengo es el siguiente (Omito los nombres de clase completos por simplicidad):
<beans ...>
<context:annotation-config />
<bean class="...AutowiredAnnotationBeanPostProcessor"/>
<bean class="...DefaultAnnotationHandlerMapping">
<context:component-scan base-package="com.mycompany.myserver"/>
</beans>
Este es cómo he enchufado mi configuración de Spring en 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>
Tenga en cuenta que estoy tratando de crea una configuración mínima (sin archivos servlet-config.xml adicionales). Es por eso que estoy señalando el Dispatcher a una configuración incorporada.
¿Es esto correcto?
Después de empezar Tomcat y todos los granos están cargados estoy dirigen a la siguiente URL: "¡Hola, el usuario"
http://localhost:8080/myserver/services/users/hello
Y, en lugar de la responder, a mi pesar, veo los errores siguientes en el archivo de registro:
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]
Como se observa, mi configuración actual está tratando de desviar esta solicitud como una nueva solicitud:
/myserver/services/users/hello, user!
Cualquier idea ¿qué está mal? ¿Qué me estoy perdiendo?
Hmm ... Pero está rompiendo toda la idea de JAX-RS, que afirma que el valor de retorno del método se envía a la parte solicitante. ¿Hay alguna manera de anotar mis métodos por lo que el requisito anterior será verdadero? – IgorM
Según el método javadoc, su método toma un argumento de OutputStream o Writer que RequestMapper pasará en ServletOutputStream/Writer para que usted escriba. No estoy seguro de si esta es realmente la mejor manera de hacerlo, pero funcionará. @RequestMapping (value = "/ users/hello", method = RequestMethod.GET) public void hello (Writer w) { w.write ("hola, usuario!"); w.flush(); devolución; } Es posible que desee obtener todo el HttpServletResponse en lugar de simplemente Writer, de esa manera puede establecer los encabezados Http apropiados. – Gandalf
Puede escribir la respuesta directamente a la secuencia tal como se sugirió anteriormente, o puede devolver un objeto ModelAndView que lo haga. El efecto es muy similar. Sería bueno si Spring 3 utilizara el nuevo patrón HttpMessageConverter para manejar valores de retorno de método, pero ssdly solo se aplica a @RequestBody. Los valores de retorno del método todavía se interpretan como en Spring 2.5 Recuerde que Spring REST MVC es * no * compatible con JAX-RS, eso fue una elección explícita que hicieron. JAX-RS simplemente no encajaba bien con Spring MVC. – skaffman