当我将 servlet 转发到 JSP 时,我无法加载 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:我添加了应用程序的结构,以及其他一些可能有帮助的信息。
https://i.stack.imgur.com/nf0zO.png
header.jsp
文件是包含 CSS 链接标记的文件。 HomeServlet
在 web.xml
中设置为我的 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>
JSP 文件生成的 HTML 页面中的所有相对 URL 都相对于当前请求 URL(您在浏览器地址栏中看到的 URL),而不是您似乎期望的 JSP 文件在服务器端的位置。即必须通过 URL 单独下载这些资源的网络浏览器,而不是必须以某种方式从磁盘包含它们的网络服务器。
除了更改相对 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>
但是,您可能不希望对上下文路径进行硬编码。很合理。您可以通过 ${pageContext.request.contextPath}
获取 EL 中的上下文路径。
<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 输出以获取提示。
通过给出这样的路径意味着“从当前位置”,另一方面,如果您以 /
开头,则意味着“从上下文”。
index.jsp
与您的 styles
和 images
目录位于同一位置/级别。因此,当您直接使用 index.jsp
作为欢迎文件时,一切看起来都像魅力。另一方面,当您通过 servlet 转发相同的资源时,情况就不同了。 [未完待续...]
context path
。正如您在文档中看到的那样,/
在我们要转发请求或重定向请求的路径中使用时具有某些特定含义。如果没有斜线,它将取自当前位置,而不是上下文路径。我希望你现在得到我。
您的欢迎页面设置为 That Servlet 。所以所有的 css ,图像路径都应该相对于那个 servlet DIR 给出。这是个坏主意!为什么需要 servlet 作为主页?将.jsp 设置为索引页面并从那里重定向到任何页面?
您是否尝试从 db 填充任何字段,这就是您使用 servlet 的原因吗?
如果您使用的是 Spring MVC,那么您需要为静态内容声明默认操作 servlet。在 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"/>
至于您的更新,我对背后的原因感到困惑。深入挖掘并发现了这个宝石:
yoursite.com 变成 yoursite.com/
yoursite.com/ 是一个目录,所以会扫描welcome-file-list
yoursite.com/CMS 是第一个欢迎文件(欢迎文件列表中的“CMS”),并且有 /CMS 到 MyCMS servlet 的映射,以便访问 servlet。
来源:http://wiki.metawerx.net/wiki/HowToUseAServletAsYourMainWebPage
因此,映射确实有意义。
现在可以自由地使用 ${pageContext.request.contextPath}/path/ 作为相对链接的 src/href!
简短的回答 - 在 jsp 中添加以下行,它将定义基本的 base href="/{root of your application}/"
下面的代码对我有用。
而不是使用 <%@ include file="styles/default.css"%>
你也可以试试这个。因为这对我有用,而且很简单。
<style>
<%@ include file="/css/style.css" %>
</style>
不定期副业成功案例分享
/
(气味,气味;))。所以它也会拦截 CSS 文件(实际上是每个 HTTP 请求)。是否正确处理它们?即您可以通过 localhost:8080/context/styles/default.css 直接在 webbrowser 中访问 CSS 文件吗?/*
,但如果您尝试创建某种前端控制器,我建议您通过 this answer,也许还可以通过 this answer。