Браузер не может получить доступ / найти относительные ресурсы, такие как CSS, изображения и ссылки, при вызове сервлета, который пересылает в JSP

У меня проблемы с загрузкой CSS и изображений и созданием ссылок на другие страницы, когда у меня сервлет пересылается в JSP. В частности, когда я установил свой <welcome-file> в index.jsp, CSS загружается и мои изображения отображаются. Однако, если я установлю свой <welcome-file> в HomeServlet который передает контроль index.jspCSS не применяется и мои изображения не отображаются.

Мой файл 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 установлен как мой 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>

10 ответов

Решение

Все относительные 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>

Это в свою очередь (опять же) некоторые предостережения. Якоря (#identifier URL) также станет относительным к базовому пути! Вместо этого вы хотели бы сделать это относительно URL запроса (URI). Итак, изменить как

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

в

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

У каждого способа есть свои плюсы и минусы. Вам решать, что выбрать. По крайней мере, теперь вы должны понимать, как эта проблема вызвана и как ее решить:)

Смотрите также:

Я столкнулся с подобной проблемой в приложении Spring MVC. я использовал < mvc:resources > тег, чтобы решить эту проблему.

Пожалуйста, найдите следующую ссылку с более подробной информацией.

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

Вы должны проанализировать фактический вывод HTML, для подсказки.

Если указывать такой путь, значит "из текущего местоположения", с другой стороны, если вы начнете с / это будет означать "из контекста".

Вы можете попробовать и этот. Потому что это сработало для меня, и это просто.

<style>
    <%@ include file="/css/style.css" %>
</style>

Если вы используете 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"/>

Ниже код работал для меня.

вместо использования <% @ include file = "styles / default.css"%>

Ваша страница приветствия установлена ​​как That Servlet . Таким образом, все пути css, images должны быть указаны относительно DIR этого сервлета. что плохая идея! зачем вам сервлет как домашняя страница? установить.jsp в качестве индексной страницы и перенаправить на любую страницу оттуда?

Вы пытаетесь заполнить какие-либо поля из БД, поэтому вы используете сервлет?

Что касается вашего обновления, я был сбит с толку из-за рассуждений. Вырыл немного глубже и нашел этот драгоценный камень:

  • yoursite.com становится yoursite.com/
  • yoursite.com/ является каталогом, поэтому проверяется список файлов приветствия
  • yoursite.com/CMS - это первый файл приветствия ("CMS" в списке файлов приветствия), и существует сопоставление / CMS с сервлетом MyCMS, что обеспечивает доступ к сервлету.

Источник: http://wiki.metawerx.net/wiki/HowToUseAServletAsYourMainWebPage

Таким образом, отображение имеет смысл.

И теперь можно свободно использовать ${pageContext.request.contextPath}/path/ в качестве src / href для относительных ссылок!

Краткий ответ - добавьте следующую строку в JSP, которая будет определять базу
base href="/{корень вашего приложения}/"

Просто и понятно

Структура каталогов:

      webapp/
  css/
    bootstrap.min.css
index.jsp
      <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel='stylesheet' type='text/css' href='css/bootstrap.min.css'>
</head>
<body>
<h4>Testing JSP Form</h4>

<form action="firstServlet" method="post">
<label for="firstname"> First Name</label><input type="text" name="firstname"> <br>
<input type="submit" value="Submit" >
</form>

</body>
</html>

Для размещения внутри контроллера сервлета

      writer.println("<!DOCTYPE html>\n"
                + "<html lang=\"en\">\n"
                + "<head>\n"
                + "<meta charset=\"UTF-8\">\n"
                + "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n"
                + "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
                + "<link rel=\'stylesheet\' type=\'text/css\' href=\'css/bootstrap.min.css\'>\n"
                + "<title>Document</title>\n"
                + "</head>\n"
                + "<body>\n"
                + "<h3>Hello " + firstName + "</h3>"
                + "</body>\n"
                + "</html>\n");
        writer.close();

Другие вопросы по тегам