Tengo problemas para cargar CSS e imágenes y crear enlaces a otras páginas cuando tengo un servlet que reenvía a un JSP. Específicamente, cuando configuro mi <welcome-file>
en index.jsp
, el CSS se carga y mis imágenes se muestran. Sin embargo, si configuro mi control <welcome-file>
a HomeServlet
qué reenvíos 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/
.
Me 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.
El header.jsp
archivo es el archivo que contiene la etiqueta de enlace para CSS. El HomeServlet
está configurado como mi welcome-file
en web.xml
:
<welcome-file-list>
<welcome-file>HomeServlet</welcome-file>
</welcome-file-list>
El servlet se declara y se 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 se asignó incorrectamente. Aparentemente, al configurar un Servlet como suyo, <welcome-file>
no puede tener un patrón de URL /
, lo cual me parece un poco extraño, porque ¿no representaría 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>
Respuestas:
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 esperar. Es decir, es 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.
Aparte de cambiar las URL relativas para que sean relativas a la URL del servlet en lugar de 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 cambie 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 le gustaría no 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 en${root}
cualquier otro lugar)O, si no le teme al XML ilegible y al resaltado de sintaxis XML roto, use 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 a su vez bastante engorroso si tiene muchas URL relativas. Para eso puedes usar la
<base>
etiqueta. Todas las URL relativas se convertirán instantáneamente en relativas a él. Sin embargo, tiene que comenzar con el esquema (http://
,https://
, etc.). No hay una forma clara 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 tiene a su vez (nuevamente) algunas advertencias. ¡Los anclajes (las
#identifier
URL) también se volverá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 debe comprender cómo se causa este problema y cómo resolverlo :)
Ver también:
<base>
etiqueta html?fuente
/
(olor, olor;)). Por lo tanto, también intercepta archivos CSS (de hecho, todas las solicitudes HTTP). ¿Los está manejando correctamente? Es decir, ¿puede acceder al archivo CSS directamente en el navegador web mediante localhost: 8080 / context / styles / default.css ?/*
, pero si está tratando de crear una especie de controlador frontal, le sugiero que lea esta respuesta y tal vez también esta respuesta .Enfrenté un problema similar con la aplicación Spring MVC. Usé la
< mvc:resources >
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/
fuente
Debe analizar la salida HTML real, para la pista.
Al dar la ruta de esta manera significa "desde la ubicación actual", por otro lado, si comienza con,
/
eso significaría "desde el contexto".fuente
index.jsp
está en la misma ubicación / nivel que tus directoriosstyles
yimages
. Por lo tanto, cuando lo usa directamenteindex.jsp
como archivo de bienvenida, todo parece como un encanto. Por otro lado, cuando reenvía el mismo recurso a través del servlet, el asunto ya no es el mismo. [continuará ...]context path
aquí. Como ha visto en los documentos,/
tiene un significado específico cuando se usa en la ruta que queremos reenviar la solicitud o redirigir la solicitud. Sin la barra, se tomará de la ubicación actual, no de la ruta de contexto. Espero que me entiendas ahora.Su página de bienvenida está configurada como That Servlet. Por lo tanto, todas las rutas de acceso de imágenes y css deben proporcionarse en relación con ese servlet DIR. que es una mala idea! ¿Por qué necesita el servlet como página de inicio? establecer .jsp como página de índice y redirigir a cualquier página desde allí?
¿Está tratando de completar algún campo de db? ¿Es por eso que está usando servlet?
fuente
Si está utilizando Spring MVC, debe declarar el servlet de acción predeterminado para los contenidos estáticos. Agregue las siguientes entradas en spring-action-servlet.xml. Funcionó para mí.
NOTA: mantenga todos los contenidos estáticos fuera de WEB-INF.
<!-- Enable annotation-based controllers using @Controller annotations --> <bean id="annotationUrlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="order" value="0" /> </bean> <bean id="controllerClassNameHandlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"> <property name="order" value="1" /> </bean> <bean id="annotationMethodHandlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
fuente
En cuanto a su actualización, estaba confundido por el razonamiento detrás. Cavé un poco más y encontré esta joya:
Fuente: http://wiki.metawerx.net/wiki/HowToUseAServletAsYourMainWebPage
Entonces, el mapeo tiene sentido.
¡Y ahora se puede usar libremente $ {pageContext.request.contextPath} / path / as src / href para enlaces relativos!
fuente
respuesta corta: agregue la siguiente línea en el jsp que definirá la base
base href = "/ {raíz de su aplicación} /"
fuente
El siguiente código funcionó para mí.
en lugar de utilizar <% @ include file = "styles / default.css"%>
fuente
Puedes probar este también. Porque esto funcionó para mí y es simple.
<style> <%@ include file="/css/style.css" %> </style>
fuente