Браузер не может получать/находить относительные ресурсы, такие как CSS, изображения и ссылки при вызове сервлета, который пересылает JSP
У меня возникают проблемы с загрузкой CSS и изображений и созданием ссылок на другие страницы, когда у меня есть сервлет в JSP. В частности, когда я устанавливаю свой <welcome-file>
в index.jsp
, CSS загружается и отображаются мои изображения. Однако, если я установил <welcome-file>
> HomeServlet
, который переводит элемент управления в index.jsp
, CSS не применяется, и мои изображения не отображаются.
Мой CSS файл находится в web/styles/default.css
.
Мои изображения находятся в web/images/
.
Я привязываюсь к своим CSS следующим образом:
<link href="styles/default.css" rel="stylesheet" type="text/css" />
Я показываю свои изображения следующим образом:
<img src="images/image1.png" alt="Image1" />
Как эта проблема возникает и как ее решить?
Обновление 1. Я добавил структуру приложения, а также другую информацию, которая может помочь.
Файл header.jsp
- это файл, содержащий тег ссылки для CSS. HomeServlet
устанавливается как my welcome-file
в web.xml
:
<welcome-file-list>
<welcome-file>HomeServlet</welcome-file>
</welcome-file-list>
Сервлет объявляется и отображается следующим образом в 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>
Обновление 2. Наконец-то я нашел проблему - мой сервлет был неправильно отображен. По-видимому, при установке сервлета в качестве <welcome-file>
он не может иметь шаблон URL-адреса /
, который я нахожу довольно странным, потому что это не будет означать корневой каталог сайта?
Новое отображение выглядит следующим образом:
<servlet-mapping>
<servlet-name>HomeServlet</servlet-name>
<url-pattern>/HomeServlet</url-pattern>
</servlet-mapping>
Ответы
Ответ 1
Все относительные URL-адреса на странице HTML, сгенерированные JSP файлом, относятся к текущему URL-адресу запроса (URL-адрес, который вы видите в адресной строке браузера) и не, к местоположению файла JSP на стороне сервера, как вы, кажется, ожидаете. Это именно веб-браузер, который должен загружать эти ресурсы по URL-адресу, а не веб-серверу, который должен каким-то образом включить их с диска.
Помимо изменения относительных URL-адресов, чтобы сделать их относительно URL-адреса сервлета вместо местоположения JSP файла, другой способ исправить эту проблему - сделать их относительно корня домена (т.е. начать с /
). Таким образом, вам не нужно беспокоиться об изменении относительных путей еще раз при изменении URL-адреса сервлета.
<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>
Однако вам, скорее всего, не понадобится жестко указывать путь контекста. Очень разумно. Вы можете получить путь контекста в EL с помощью ${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>
(который может быть легко сокращен на <c:set var="root" value="${pageContext.request.contextPath}" />
и использован как ${root}
в другом месте)
Или, если вы не боитесь нечитаемого XML и разбитого синтаксиса XML, используйте 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>
В любом случае, это в свою очередь довольно громоздко, если у вас много относительных URL-адресов. Для этого вы можете использовать тег <base>
. Весь относительный URL-адрес мгновенно станет относительным. Однако он должен начинаться со схемы (http://
, https://
и т.д.). Нет простого способа получить базовый контекстный путь в обычном EL, поэтому нам нужна небольшая помощь JSTL здесь.
<%@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>
Это в свою очередь (опять же) некоторые предостережения. Якоря (URL #identifier
) также будут относиться к базовому пути! Вы хотели бы сделать это относительно URL-адреса запроса (URI). Итак, измените, например,
<a href="#identifier">jump</a>
к
<a href="${uri}#identifier">jump</a>
Каждый путь имеет свои плюсы и минусы. Это вам решать. По крайней мере, теперь вы должны понять, как эта проблема возникает и как ее решить:)
См. также:
Ответ 2
Я столкнулся с аналогичной проблемой с приложением Spring MVC. Я использовал тег < mvc:resources >
, чтобы решить эту проблему.
Пожалуйста, найдите следующую ссылку, содержащую более подробную информацию.
http://www.mkyong.com/spring-mvc/spring-mvc-how-to-include-js-or-css-files-in-a-jsp-page/
Ответ 3
Вы должны проанализировать фактический вывод HTML для подсказки.
Давая путь, как это, означает "из текущего местоположения", с другой стороны, если вы начинаете с /
, что означает "из контекста".
Ответ 4
Ваша страница приветствия установлена в качестве этого сервлета. Таким образом, все css, путь изображения следует указывать относительно DIR сервлета. это плохая идея! зачем вам сервлет в качестве домашней страницы? установить .jsp в качестве индексной страницы и перенаправить на любую страницу оттуда?
Вы пытаетесь заполнить любые поля из db, поэтому вы используете сервлет?
Ответ 5
Если вы используете Spring MVC, вам нужно объявить сервлет действия по умолчанию для статического содержимого. Добавьте следующие записи в spring -action-servlet.xml. Это сработало для меня.
ПРИМЕЧАНИЕ: сохраняйте все статическое содержимое вне 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"/>
Ответ 6
Что касается вашего обновления, я был в замешательстве за рассуждения. Глубоко углубился и нашел этот камень:
- yoursite.com становится вашим сайтом /
- yoursite.com/- это каталог, поэтому проверяется список приветственных файлов
- yoursite.com/CMS - это первый приветственный файл ( "CMS" в списке приветственных файлов), и есть сопоставление /CMS с сервлетом MyCMS, так что к сервлету обращаются.
Источник: http://wiki.metawerx.net/wiki/HowToUseAServletAsYourMainWebPage
Итак, отображение тогда имеет смысл.
И теперь можно свободно использовать ${pageContext.request.contextPath}/путь/как src/href для относительных ссылок!
Ответ 7
короткий ответ - добавьте следующую строку в jsp, которая определит базу
base href= "/{корень вашего приложения}/"