2010-01-25 14 views
29

Lo que intento hacer es mapear las solicitudes a la raíz del servlet (¿terminología correcta?). Estoy en el punto donde las direcciones URL se asignan a la vista correcta, pero no se puede encontrar todo el contenido estático (css, javascript, imágenes) que forma parte de la página.Usando Spring, mapeando a la raíz en web.xml, no se encuentran los recursos estáticos

Así que en mi web.xml mi etiqueta de servlet se parece a esto

<servlet-mapping> 
    <servlet-name>springapp</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

Mi controlador es como la siguiente:

@RequestMapping("/shop") 
public class TheShopController extends MyBaseController { 

    public static String VIEW = "Tile.Shop"; 

    @Override 
    @RequestMapping(method = RequestMethod.GET) 
    protected ModelAndView processRequest(HttpServletRequest req, HttpServletResponse resp) { 
     ModelAndView mav = new ModelAndView(VIEW); 
     return mav; 
    } 

} 

MyBaseController es muy simple. Se ve así:

public abstract class MyBaseController extends AbstractController { 

    protected Logger log = Logger.getLogger(getClass()); 

    @Override 
    protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) 
     throws Exception { 

     ModelAndView mav = processRequest(req, resp); 
     return mav; 
    } 

    protected abstract ModelAndView processRequest(HttpServletRequest req, HttpServletResponse resp); 
} 

Estoy usando la capa Tiles in my view. Mi configuración es la siguiente:

/WEB-INF/tiles-defs.xml

Como ya he mencionado, se encuentran los puntos de vista, pero los recursos estáticos que son un puerto de la página no se puede encontrar. Aquí hay alguna típica registro hacia fuera puesto:

2010-01-24 17: 25: 01,777 DEBUG [http-8080-7] servlet.DispatcherServlet (DispatcherServlet.java:690) - DispatcherServlet con el nombre 'springapp' solicitud GET de procesamiento para [/springapp/static/css/account.css] 2010-01-24 17: 25: 01,778 WARN [http-8080-4] servlet.DispatcherServlet (DispatcherServlet.java:962) - Sin asignación encontrado para la solicitud HTTP con URI [/ springsepp/sitetic/css/shop.css] en DispatcherServlet con el nombre 'springapp' 2010-01-24 17: 25: 01,778 DEPURACIÓN [http-8080-6] servlet.FrameworkServlet (FrameworkServlet.java:677) - Exitosamente solicitud completada 2010-01-24 17: 25: 01,778 WARN [http-8080-5] servlet.DispatcherServlet (DispatcherServlet.java:962) - No se encontró la asignación para la solicitud HTTP con URI [/ springapp/static/css/offers.css] en DispatcherServlet con el nombre 'springapp' 2010-01-24 17: 25: 01,778 WARN [http-8080-3] servlet.DispatcherServlet (DispatcherServlet.java:962) - No se ha encontrado ninguna correspondencia para la solicitud HTTP con URI [/springapp/static/css/scrollable-buttons.css] en DispatcherServlet con el nombre 'springapp'

ir a http://localhost:8080/springapp/shop funciona bien, pero el CSS y las imágenes son missi ng.

Creo que el uso de Tiles complica las cosas pero soy reacio a deshacerme de él. Me pregunto si necesito ajustar la configuración de resolución de mi vista para modificarla. ¿Podría encadenar los resolvedores de vistas? simplemente no tengo experiencia en hacerlo.

Respuesta

61

El problema es que las solicitudes para el contenido estático van al dispatcherServlet, porque está correlacionado como <url-pattern>/</url-pattern>. Es un problema muy común en las aplicaciones con URL "RESTful" (es decir, sin cualquier prefijo en el mapeo DispatcherServlet).

Hay varias maneras posibles para resolver este problema:


desde la primavera 3.x la mejor forma de acceder a los recursos estáticos es utilizar <mvc:resources>: web.xml:

<servlet-mapping> 
    <servlet-name>springapp</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

Spring config:

<!-- Handles GET requests for /resources/** by efficiently serving static content 
    in the ${webappRoot}/resources dir --> 
<mvc:resources mapping="/resources/**" location="/resources/" /> 

Ver también MVC Simplifications in Spring 3


1. Uso del filtro de reescritura de URL
Ver mvc-basic ejemplo here

2. Establecer un prefijo para el default servlet:

<servlet-mapping> 
    <servlet-name>default</servlet-name> 
    <url-pattern>/static/*</url-pattern> 
</servlet-mapping> 

Eso es, solicitud de /static/images/image.png devolverá el archivo con el nombre /images/image.png Sin embargo, esta forma es incompatible a través de diferentes contenedores de servlets (que no funciona en el embarcadero), ver soluciones here

3. Establecer extensiones de contenido estático para el default servlet:

<servlet-mapping> 
    <servlet-name>default</servlet-name> 
    <url-pattern>*.png</url-pattern> 
    <url-pattern>*.js</url-pattern> 
    <url-pattern>*.css</url-pattern> 
</servlet-mapping> 

4. no utilice direcciones URL REST, utilizar las URL con el prefijo:

<servlet-mapping> 
    <servlet-name>springapp</servlet-name> 
    <url-pattern>/app</url-pattern> 
</servlet-mapping> 

5. No utilice URLs REST, utilizar URL con extensión:

<servlet-mapping> 
    <servlet-name>springapp</servlet-name> 
    <url-pattern>*.do</url-pattern> 
</servlet-mapping> 
+0

Lo que realmente quiero hacer es utilizar el @ Asignación de la aplicación de solicitud con la anotación @PathVariable para lograr el uso de las URL RESTful. Eventualmente, todos los recursos estáticos serán servidos por apache pero estarán en un entorno de producción. Necesito recursos estáticos servidos por tomcat cuando se ejecutan localmente, como en desarrollo. He usado el filtro urlrewrite antes, y me ha gustado, pero me gustaría encontrar otra forma. – richever

+0

Fui con una combinación de filtro org.tuckey.urlrewrite y # 4 desde arriba. ¡Gracias! – richever

+0

Eres rockero FYI Probé # 2 y funcionó en mi entorno local, que se ejecutaba en el sitio web raíz en tomcat. Tan pronto como lo implementé en un servidor de prueba, en un sitio no raíz llamado "prueba", dejó de funcionar. Por algún motivo, el/test/before/static/arrojaba la asignación de servlets predeterminada. Acabo de cambiar al n. ° 3 y funciona como un hechizo. He estado luchando con esto por mucho tiempo. ¡Gracias! +1 – kmehta

4

Como alternativa al número propuesto de solución (2, servlet predeterminado que se comporta de manera diferente de contenedor de servlets para contenedor servlet), lo haría recomendamos echar un vistazo al Servlet de Recursos (org.springframework.js.resource.ResourceServlet) del proyecto Spring Webflow.

Para más detalles por favor, eche un vistazo a How to handle static content in Spring MVC?

1

Tengo el mismo problema, pero en lugar de utilizar la primavera, yo mysefl un pequeño filtro que redirigir la raíz a mi página de inicio así:

HttpServletRequest req = (HttpServletRequest) request; 
    HttpServletResponse res = (HttpServletResponse) response; 

    String pageName = req.getServletPath(); 

    if(pageName.equals("/")) { 
     res.sendRedirect(req.getContextPath() + "/start"); 
    } else { 
     chain.doFilter(request, response); 
    } 

Es quizás un truco, pero parece que funciona bien con un código pequeño. Ir aquí para obtener más información de los filtros http://www.oracle.com/technetwork/java/filters-137243.html

Cuestiones relacionadas