El navegador no puede acceder/encontrar recursos relativos como CSS, imágenes y enlaces cuando llama a un servlet que reenvía a un JSP

Resuelto Brian DiCasa asked hace 14 años • 10 respuestas

Tengo problemas para cargar CSS e imágenes y crear enlaces a otras páginas cuando tengo un servlet reenviado a un JSP. Específicamente, cuando configuro mi <welcome-file>en index.jsp, el CSS se carga y se muestran mis imágenes. Sin embargo, si configuro mi <welcome-file>control HomeServletde reenvío en index.jsp, el CSS no se aplica y mis imágenes no se muestran.

Mi archivo CSS está en formato web/styles/default.css.
Mis imágenes están en web/images/.

Estoy vinculando a mi CSS así:

<link href="styles/default.css" rel="stylesheet" type="text/css" />

Estoy mostrando mis imágenes de la siguiente manera:

<img src="images/image1.png" alt="Image1" />

¿Cómo se produce este problema y cómo puedo solucionarlo?


Actualización 1 : agregué la estructura de la aplicación, así como otra información que podría ayudar.

texto alternativo

El header.jsparchivo es el archivo que contiene la etiqueta de enlace para el CSS. El HomeServletestá configurado como mi welcome-fileen web.xml:

<welcome-file-list>
    <welcome-file>HomeServlet</welcome-file>
</welcome-file-list>

El servlet se declara y asigna de la siguiente manera en web.xml:

<servlet>
    <servlet-name>HomeServlet</servlet-name>
    <servlet-class>com.brianblog.frontend.HomeServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HomeServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Actualización 2 : finalmente encontré el problema: mi servlet estaba asignado incorrectamente. Aparentemente, cuando se configura un Servlet como suyo, <welcome-file>no puede tener un patrón de URL de /, lo cual me parece un poco extraño, porque ¿no representaría eso el directorio raíz del sitio?

El nuevo mapeo es el siguiente:

<servlet-mapping>
    <servlet-name>HomeServlet</servlet-name>
    <url-pattern>/HomeServlet</url-pattern>
</servlet-mapping>
Brian DiCasa avatar Sep 07 '10 09:09 Brian DiCasa
Aceptado

Todas las URL relativas en la página HTML generada por el archivo JSP son relativas a la URL de solicitud actual (la URL como se ve en la barra de direcciones del navegador) y no a la ubicación del archivo JSP en el lado del servidor como parece esperarse. Es concretamente el navegador web quien tiene que descargar esos recursos individualmente por URL, no el servidor web quien tiene que incluirlos desde el disco de alguna manera.

Además de cambiar las URL relativas para que sean relativas a la URL del servlet en lugar de a la ubicación del archivo JSP, otra forma de solucionar este problema es hacerlas relativas a la raíz del dominio (es decir, comenzar con a /). De esta manera, no necesita preocuparse por cambiar las rutas relativas una vez más cuando cambia la URL del servlet.

<head>
    <link rel="stylesheet" href="/context/css/default.css" />
    <script src="/context/js/default.js"></script>
</head>
<body>
    <img src="/context/img/logo.png" />
    <a href="/context/page.jsp">link</a>
    <form action="/context/servlet"><input type="submit" /></form>
</body>

Sin embargo, probablemente no desee codificar la ruta de contexto. Muy razonable. Puede obtener la ruta de contexto en EL mediante ${pageContext.request.contextPath}.

<head>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/default.css" />
    <script src="${pageContext.request.contextPath}/js/default.js"></script>
</head>
<body>
    <img src="${pageContext.request.contextPath}/img/logo.png" />
    <a href="${pageContext.request.contextPath}/page.jsp">link</a>
    <form action="${pageContext.request.contextPath}/servlet"><input type="submit" /></form>
</body>

(que se puede acortar <c:set var="root" value="${pageContext.request.contextPath}" />y utilizar fácilmente como ${root}en otros lugares)

O, si no temes el XML ilegible y el resaltado de sintaxis XML roto, usa JSTL <c:url> :

<head>
    <link rel="stylesheet" href="<c:url value="/css/default.css" />" />
    <script src="<c:url value="/js/default.js" />"></script>
</head>
<body>
    <img src="<c:url value="/img/logo.png" />" />
    <a href="<c:url value="/page.jsp" />">link</a>
    <form action="<c:url value="/servlet" />"><input type="submit" /></form>
</body>

De cualquier manera, esto es bastante engorroso si tienes muchas URL relativas. Para eso puedes usar la <base>etiqueta. Todas las URL relativas se convertirán instantáneamente en relativas a ella. Sin embargo, debe comenzar con el esquema ( http://, https://, etc.). No existe una forma sencilla de obtener la ruta del contexto base en EL simple, por lo que necesitamos un poco de ayuda de JSTL aquí.

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="uri" value="${req.requestURI}" />
<c:set var="url">${req.requestURL}</c:set>
...
<head>
    <base href="${fn:substring(url, 0, fn:length(url) - fn:length(uri))}${req.contextPath}/" />
    <link rel="stylesheet" href="css/default.css" />
    <script src="js/default.js"></script>
</head>
<body>
    <img src="img/logo.png" />
    <a href="page.jsp">link</a>
    <form action="servlet"><input type="submit" /></form>
</body>

Esto a su vez tiene (de nuevo) algunas salvedades. ¡ Los anclajes (las #identifierURL) también serán relativos a la ruta base! En su lugar, le gustaría hacerlo relativo a la URL de solicitud (URI). Entonces, cambia como

<a href="#identifier">jump</a>

a

<a href="${uri}#identifier">jump</a>

Cada forma tiene sus pros y sus contras. Depende de usted cuál elegir. Al menos ahora deberías entender cómo se produce este problema y cómo solucionarlo :)

Ver también:

  • ¿Se recomienda utilizar la <base>etiqueta html?
BalusC avatar Sep 07 '2010 12:09 BalusC

Me enfrenté a un problema similar con la aplicación Spring MVC. Usé < mvc:resources >la etiqueta para resolver este problema.

Encuentre el siguiente enlace con más detalles.

http://www.mkyong.com/spring-mvc/spring-mvc-how-to-include-js-or-css-files-in-a-jsp-page/

Ashwini Patil avatar Nov 21 '2014 21:11 Ashwini Patil

Debe analizar la salida HTML real para obtener la pista.

Al dar la ruta de esta manera significa "desde la ubicación actual", por otro lado, si comienza con a, /eso significaría "desde el contexto".

Adeel Ansari avatar Sep 07 '2010 02:09 Adeel Ansari

Puedes probar este también. Porque esto funcionó para mí y es simple.

<style>
    <%@ include file="/css/style.css" %>
</style>
Dulya Perera avatar Apr 26 '2020 02:04 Dulya Perera