当调用转发到 JSP 的 Servlet 时,浏览器无法访问/找到相关资源,如 CSS、图像和链接

当我有一个转发到 JSP 的 servlet 时,我在加载 CSS 和图像以及创建到其他页面的链接方面遇到了麻烦。具体来说,当我将我的 <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 : 我已经添加了应用程序的结构,以及一些可能有帮助的其他信息。

alt text

header.jsp文件是包含 CSS 的 link 标记的文件。在 web.xml中,HomeServlet被设置为我的 welcome-file:

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

Servlet 在 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 : 我最终发现了问题-我的 servlet 映射错误。显然,当把 Servlet 设置为 <welcome-file>时,它不能有 /的 URL 模式,我觉得这有点奇怪,因为这不是代表站点的根目录吗?

新的地图如下:

<servlet-mapping>
<servlet-name>HomeServlet</servlet-name>
<url-pattern>/HomeServlet</url-pattern>
</servlet-mapping>
109905 次浏览

You must analyse the actual HTML output, for the hint.

By giving the path like this means "from current location", on the other hand if you start with a / that would mean "from the context".

Your welcome page is set as That Servlet . So all css , images path should be given relative to that servlet DIR . which is a bad idea ! why do you need the servlet as a home page ? set .jsp as index page and redirect to any page from there ?

are you trying to populate any fields from db is that why you are using servlet ?

All relative URLs in the HTML page generated by the JSP file are relative to the current request URL (the URL as you see in the browser address bar) and not to the location of the JSP file in the server side as you seem to expect. It's namely the webbrowser who has to download those resources individually by URL, not the webserver who has to include them from disk somehow.

Apart from changing the relative URLs to make them relative to the URL of the servlet instead of the location of the JSP file, another way to fix this problem is to make them relative to the domain root (i.e. start with a /). This way you don't need to worry about changing the relative paths once again when you change the URL of the 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>

However, you would probably like not to hardcode the context path. Very reasonable. You can obtain the context path in EL by ${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>

(which can easily be shortened by <c:set var="root" value="${pageContext.request.contextPath}" /> and used as ${root} elsewhere)

Or, if you don't fear unreadable XML and broken XML syntax highlighting, 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>

Either way, this is in turn pretty cumbersome if you have a lot of relative URLs. For that you can use the <base> tag. All relative URL's will instantly become relative to it. It has however to start with the scheme (http://, https://, etc). There's no neat way to obtain the base context path in plain EL, so we need a little help of JSTL here.

<%@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>

This has in turn (again) some caveats. Anchors (the #identifier URL's) will become relative to the base path as well! You would like to make it relative to the request URL (URI) instead. So, change like

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

to

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

Each way has its own pros and cons. It's up to you which to choose. At least, you should now understand how this problem is caused and how to solve it :)

See also:

If you are using Spring MVC, then you need to declare default action servlet for static contents. Add the following entries in spring-action-servlet.xml. It worked for me.

NOTE: keep all the static contents outside 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"/>

I faced similar issue with Spring MVC application. I used < mvc:resources > tag to resolve this issue.

Please find the following link having more details.

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

As for your update, I was confused for the reasoning behind in. Dug a little deeper and found this gem:

  • yoursite.com becomes yoursite.com/
  • yoursite.com/ is a directory, so the welcome-file-list is scanned
  • yoursite.com/CMS is the first welcome-file ("CMS" in the welcome-file-list), and there is a mapping of /CMS to the MyCMS servlet, so that servlet is accessed.

Source: http://wiki.metawerx.net/wiki/HowToUseAServletAsYourMainWebPage

So, the mapping then does make sense.

And one can now freely use ${pageContext.request.contextPath}/path/ as src/href for relative links!

short answer - add following line in the jsp which will define the base
base href="/{root of your application}/"

Below code worked for me.

instead of use <%@ include file="styles/default.css"%>

You can try out this one as well as. Because this worked for me and it's simple.

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