调用转发到 JSP 的 Servlet 时,浏览器无法访问/查找 CSS、图像和链接等相关资源 [英] Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP

查看:22
本文介绍了调用转发到 JSP 的 Servlet 时,浏览器无法访问/查找 CSS、图像和链接等相关资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 HomeServlet which forwards control to index.jsp, the CSS is not being applied and my images are not being displayed.

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

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

我像这样链接到我的 CSS:

I'm linking to my CSS like so:

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

我的图片显示如下:

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

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

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

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

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

header.jsp 文件是包含 CSS 链接标记的文件.HomeServletweb.xml 中设置为我的 welcome-file:

The header.jsp file is the file that contains the link tag for the CSS. The HomeServlet is set as my welcome-file in web.xml:

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

servlet 在 web.xml 中声明和映射如下:

The servlet is declared and mapped as followes in the 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 模式,我觉得这有点奇怪,因为不会代表网站的根目录?


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?

新的映射如下:

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

推荐答案

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

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.

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

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

但是,您可能不希望对上下文路径进行硬编码.非常合理.您可以通过${pageContext.request.contextPath}获取EL中的上下文路径.

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>

(可以很容易地通过 缩短并使用如 ${root} 其他地方)

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

或者,如果您不担心不可读的 XML 和损坏的 XML 语法突出显示,请使用 JSTL :

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>

无论哪种方式,如果您有很多相对 URL,这又会非常麻烦.为此,您可以使用 标签.所有相对 URL 将立即变得相对于它.然而,它必须从方案开始(http://https:// 等).在普通 EL 中没有获得基本上下文路径的简洁方法,因此我们需要 JSTL 的帮助.>

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>

这反过来又(再次)提出了一些警告.锚点(#identifier URL)也将相对于基本路径!您想让它相对于请求 URL (URI) 来代替.所以,改变像

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>

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

这篇关于调用转发到 JSP 的 Servlet 时,浏览器无法访问/查找 CSS、图像和链接等相关资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆