2011-07-13 28 views
7

Estoy desarrollando un servicio RESTful utilizando Spring 3.0 ejecutándose en el entorno Apache 6.0 de Tomcat. Spring DispatcherServlet está configurado en "/ spring/*". El servlet Spring maneja múltiples clientes y tiene muchos controladores en la aplicación. Estoy agregando un nuevo Controlador para el servicio REST. Quiero que todos mis clases de controlador para tener un prefijo de identificación como "WS" (servicios web) para que la URL completa a un recurso se ve así:
http://<server>:<port>/<context>/spring/ws/service1Agregar prefijo a las URL de todas las clases de controlador en el paquete

La única manera que encontré con la anotación de la primavera es @RequestMapping utilizar como esto:

@Controller 
@RequestMapping("/ws/service1") 
public class Service1 { 

@RequestMapping(method=RequestMethod.GET) 
@ResponseBody 
public String getHtml() { ... } 

.... 
} 

Pero ya que tengo docenas de clases, no quiero poner el prefijo "/ WS" en cada clase. De modo que si otro desarrollador agrega un nuevo servicio, no tiene que recordar poner este prefijo y también si decidimos cambiar el nombre del prefijo de "/ ws" a otra cosa, no tengo que cambiar todos los archivos. Descubrí que la anotación @RequestMapping solo se aplica a Métodos o Clases y no a nivel de paquete.

¿Hay alguna manera de configurar que todos mis controladores REST sean accedidos con el prefijo?

Tenga en cuenta que no puedo cambiar la asignación de URL web.xml del servlet de Spring ya que hay otros controladores que se ejecutan con esa URL.

+0

Su última oración es crucial: ¿podría ampliar lo que quiere decir con "otros controladores"? – skaffman

+0

El servlet My Spring sirve un cliente Flex y yo uso el controlador BlazeDS para eso. El servidor Tomcat también tiene que servir contenido estático. El controlador RESTful se suma a eso. Por lo tanto, no puedo asignar la URL del servlet de Spring a "/ *" o "/ ws/*". – Shreerang

Respuesta

5

Es posible que desee ver el soporte convention over configuration de Spring 3, específicamente ControllerClassNameHandlerMapping. Efectivamente, no define la ubicación de la URL en un @RequestMapping, pero está definida por la ubicación del paquete del controlador.

Si desea que las URL asignadas reflejen el nombre del paquete del controlador, debe establecer la propiedad basePackage del ControllerClassNameHandlerMapping. El documentation dice

Set the base package to be used for generating path mappings, including all subpackages underneath this packages as path elements. Default is null, using the short class name for the generated path, with the controller's package not represented in the path. Specify a base package like "com.mycompany.myapp" to include subpackages within that base package as path elements, e.g. generating the path "/mymodule/buyform" for the class name "com.mycompany.myapp.mymodule.BuyForm". Subpackage hierarchies are represented as individual path elements, e.g. "/mymodule/mysubmodule/buyform" for the class name "com.mycompany.myapp.mymodule.mysubmodule.BuyForm".

Así, un ejemplo de definición de los granos podría ser

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"> 
    <property name="basePackage" value="com.company.project"/> 
</bean> 
<context:component-scan base-package="com.company.project.ws"/> 

Y los controladores podría parecerse a

package com.company.project.ws; 
@Controller 
public class Service1 { 
    // your controller methods 
} 
+0

Sí, de hecho he investigado eso. ¿Puede decirme si es posible tener un mapeo de URL que tenga en cuenta los nombres de los paquetes?Por ejemplo, si el nombre completo de la clase es "com.ws.Service1", ¿se correlacionaría con la URL "/ ws/service1" y así sucesivamente? – Shreerang

+0

Sí, eso es posible. No se explica en la referencia, pero JavaDoc tiene los punteros necesarios. He actualizado la respuesta para reflejar cómo lograr esto. También es posible que desee ver la propiedad pathPrefix para ControllerClassNameHandlerMapping, si desea agregar un prefijo a su ruta. – ptomli

+0

Esto se ve muy bien, lo intenté pero estoy obteniendo el siguiente error: javax.servlet.ServletException: Sin adaptador para el controlador [[email protected]]: ¿Su controlador implementa una interfaz compatible como Controller ? Aunque he definido bean ¿Alguna sugerencia? – Shreerang

0

Otro enfoque (muy básico y sencillo) que he implementado fue para definir múltiples servlets de Dispatcher y luego mapear diferentes URL para cada servlet. Los servlets comparten el contexto de Spring raíz y, además de eso, tienen sus propias definiciones de bean. Lea más en este Java doc.

Así que mi web.xml se parece a:

<servlet> 
    <servlet-name>flex</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<!-- Mappings for BlazeDS requests --> 
<servlet-mapping> 
    <servlet-name>flex</servlet-name> 
    <url-pattern>/spring/messagebroker/*</url-pattern> 
</servlet-mapping> 

<!-- Second dispatcher servlet for Web Services API --> 
<servlet> 
    <servlet-name>wsapi</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>2</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>wsapi</servlet-name> 
    <url-pattern>/spring/ws/*</url-pattern> 
</servlet-mapping> 

Básicamente, lo que dejó el servlet despachador existente tal como es y añade un nuevo servlet sólo para los controladores REST con diferente asignación de dirección URL. Entonces puedo controlar la URL de estos servlets por separado. Después de esto, ya no necesito poner el prefijo de URL en cada controlador.

Cuestiones relacionadas