model-view-controller - mvc - @requestmapping ejemplo
Con Spring, mapeo a la raíz en web.xml, no se encuentran los recursos estáticos (4)
Lo que trato de hacer es asignar 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.
Entonces en mi web.xml mi etiqueta de servlet se ve así
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Mi controlador se ve así:
@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 parece a esto:
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 Tiles en mi capa de vista. Mi configuración es la siguiente:
/WEB-INF/tiles-defs.xml
Como mencioné, las vistas se encuentran pero los recursos estáticos que son un puerto de la página no se pueden encontrar. Aquí hay algunos ejemplos típicos de cierre de sesión:
2010-01-24 17: 25: 01,777 DEPURACIÓN [http-8080-7] servlet.DispatcherServlet (DispatcherServlet.java:690) - DispatcherServlet con el nombre ''springapp'' procesando la solicitud GET para [/springapp/static/css/account.css ] 2010-01-24 17: 25: 01,778 WARN [http-8080-4] servlet.DispatcherServlet (DispatcherServlet.java:962) - No se ha encontrado ninguna correspondencia para la solicitud HTTP con URI [/springapp/static/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) - Solicitud completada con éxito 2010-01-24 17: 25: 01,778 WARN [http-8080-5] servlet.DispatcherServlet (DispatcherServlet.java:962) - No se encontró una asignación para la solicitud HTTP con URI [/ springsepp / 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 nombre ''spri ngapp ''
Ir a http://localhost:8080/springapp/shop funciona bien, pero faltan el CSS y las imágenes.
Creo que usar Tiles complica las cosas de alguna manera, pero me resisto a deshacerme de ella. Me pregunto si necesito ajustar la configuración de resolución de mi vista para que sea modificada de alguna manera. ¿Podría encadenar los resolutores de vistas? No soy tan bueno. experimentado en hacer eso.
¿Alguien consideró usar esto?
<!-- Allows for mapping the DispatcherServlet to "/" by forwarding static resource requests to the container''s default Servlet -->
<mvc:default-servlet-handler/>
Aquí están los últimos documentos de primavera: http://static.springsource.org/spring/docs/3.1.2.RELEASE/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-default-servlet-handler
Como alternativa al número de solución propuesto (2, servlet predeterminado que se comporta de forma diferente desde el contenedor de servlets al contenedor de servlets), recomendaría echar un vistazo al Servlet de recursos ( org.springframework.js.resource.ResourceServlet
) del proyecto Spring Webflow .
Para obtener más información, consulte ¿Cómo manejar contenido estático en Spring MVC?
El problema es que las solicitudes para el contenido estático van al dispatcherServlet, porque está mapeado como <url-pattern>/</url-pattern>
. Es un problema muy común en aplicaciones con URL "RESTful" (es decir, sin ningún prefijo en la asignación DispatcherServlet
).
Hay varias formas posibles de resolver este problema:
Desde Spring 3.x, la forma preferida de acceder a los recursos estáticos es usar <mvc:resources>
: web.xml
:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Configuración de primavera:
<!-- 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 en Spring 3
1. Utilice el filtro de reescritura de URL
Vea el ejemplo de mvc-basic
aquí
2. Establezca un prefijo para el servlet default
:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
Es decir, la solicitud de /static/images/image.png
devolverá el archivo llamado /images/image.png
Sin embargo, de esta manera es incompatible entre diferentes contenedores de servlets (no funciona en Jetty), consulte soluciones provisionales here
3. Establezca extensiones de contenido estático para el servlet default
:
<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 use URL RESTful, use URLs con prefijo:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
5. No use URL RESTful, use URLs con extensión:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
Tengo el mismo problema, pero en vez de usar Spring, hago mysefl un pequeño filtro que redirige la raíz a mi página de inicio de esa manera:
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 tal vez un truco, pero parece que funciona bien con un código pequeño. Vaya aquí para obtener más información sobre filtros http://www.oracle.com/technetwork/java/filters-137243.html