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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3655316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 22:43:27  来源:igfitidea点击:

Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP

cssimagejspservlets

提问by Brian DiCasa

I'm having trouble with loading CSS and images and creating links to other pages when I have a servlet forward to a JSP. Specifically, when I set my <welcome-file>to index.jsp, the CSS is being loaded and my images are being displayed. However, if I set my <welcome-file>to HomeServletwhich forwards control to index.jsp, the CSS is not being applied and my images are not being displayed.

当我将 servlet 转发到 JSP 时,我在加载 CSS 和图像以及创建指向其他页面的链接时遇到问题。具体来说,当我将 my 设置<welcome-file>为 时index.jsp,正在加载 CSS 并显示我的图像。但是,如果我将 my <welcome-file>to HomeServletwhich forwards control 设置为index.jsp,则不会应用 CSS,也不会显示我的图像。

My CSS file is in web/styles/default.css.
My images are in web/images/.

我的 CSS 文件在web/styles/default.css.
我的图像在web/images/.

I'm linking to my CSS like so:

我像这样链接到我的 CSS:

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

I'm displaying my images as follows:

我显示我的图像如下:

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

How is this problem caused and how can I solve it?

这个问题是如何引起的,我该如何解决?



Update 1: I've added the structure of the application, as well as some other information that might help.

更新 1:我已经添加了应用程序的结构,以及一些可能有帮助的其他信息。

alt text

替代文字

The header.jspfile is the file that contains the link tag for the CSS. The HomeServletis set as my welcome-filein web.xml:

header.jsp文件是包含 CSS 链接标记的文件。该HomeServlet设置为我welcome-fileweb.xml

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

The servlet is declared and mapped as followes in the web.xml:

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>


Update 2: I found the problem finally - my servlet was mapped incorrectly. Apparently when setting a Servlet as your <welcome-file>it can't have a URL pattern of /, which I find sort of weird, because wouldn't that stand for the root directory of the site?

更新 2:我终于找到了问题 - 我的 servlet 被错误地映射。显然,当将 Servlet 设置为您<welcome-file>的 URL 模式时/,它不能具有.

The new mapping is as follows:

新映射如下:

<servlet-mapping>
    <servlet-name>HomeServlet</servlet-name>
    <url-pattern>/HomeServlet</url-pattern>
</servlet-mapping>

回答by BalusC

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 notto 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.

JSP 文件生成的 HTML 页面中的所有相对 URL 都相对于当前请求 URL(您在浏览器地址栏中看到的 URL),而不是您所期望的 JSP 文件在服务器端的位置。即网络浏览器必须通过 URL 单独下载这些资源,而不是网络服务器必须以某种方式从磁盘中包含它们。

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.

除了更改相对 URL 使它们相对于 servlet 的 URL 而不是 JSP 文件的位置之外,另一种解决此问题的方法是使它们相对于域根(即以 开头/)。这样,当您更改 servlet 的 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>

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}.

但是,您可能不希望对上下文路径进行硬编码。非常合理。您可以通过 获取 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>

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

(可以很容易地缩短<c:set var="root" value="${pageContext.request.contextPath}" />并用作${root}其他地方)

Or, if you don't fear unreadable XML and broken XML syntax highlighting, use JSTL<c:url>:

或者,如果您不担心不可读的 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>

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 JSTLhere.

无论哪种方式,如果您有很多相对 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>

This has in turn (again) some caveats. Anchors (the #identifierURL'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

这反过来(再次)有一些警告。锚点(#identifierURL 的)也将变得相对于基本路径!您想让它相对于请求 URL (URI) 来代替。所以,改变像

<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:

也可以看看:

回答by Ashwini Patil

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

我在 Spring MVC 应用程序中遇到了类似的问题。我使用< mvc:resources >标签来解决这个问题。

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/

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

回答by Adeel Ansari

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

您必须分析实际的 HTML 输出以获取提示。

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".

通过给出这样的路径意味着“来自当前位置”,另一方面,如果您以 a 开头,则/意味着“来自上下文”。

回答by GoodSp33d

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 ?

您的欢迎页面设置为 That Servlet 。所以所有的 css、图像路径都应该相对于那个 servlet DIR 给出。这是个坏主意!为什么需要 servlet 作为主页?将 .jsp 设置为索引页面并从那里重定向到任何页面?

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

您是否试图从 db 填充任何字段,这就是您使用 servlet 的原因吗?

回答by AjayP

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.

如果您使用的是 Spring MVC,那么您需要为静态内容声明默认操作 servlet。在 spring-action-servlet.xml 中添加以下条目。它对我有用。

NOTE: keep all the static contents outside WEB-INF.

注意:将所有静态内容保留在 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"/>

回答by Justin Cuaresma

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.
  • yoursite.com 成为 yoursite.com/
  • yoursite.com/ 是一个目录,所以欢迎文件列表被扫描
  • yoursite.com/CMS 是第一个欢迎文件(欢迎文件列表中的“CMS”),并且有 /CMS 到 MyCMS servlet 的映射,以便访问该 servlet。

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

来源: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!

现在可以自由地使用 ${pageContext.request.contextPath}/path/ 作为相对链接的 src/href !

回答by Ankit Pandoh

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

简短回答 - 在 jsp 中添加以下行,这将定义基本的
base href="/{您的应用程序的根}/"

回答by Chamika Ravinda

Below code worked for me.

下面的代码对我有用。

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

而不是使用 <%@ include file="styles/default.css"%>

回答by Dulya Perera

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>