【问题标题】:Adding external resources (CSS/JavaScript/images etc) in JSP在 JSP 中添加外部资源(CSS/JavaScript/图像等)
【发布时间】:2013-01-11 00:31:38
【问题描述】:

我在我的项目中添加了一个外部 CSS 样式表,并放置在 Eclipse 中我的项目的 WEB-CONTENTS 文件夹中。当我在 Tomcat 上部署它时,没有应用样式表。当我在 Chrome 中调试它并打开它时,它给了我404 file not found 错误。为什么会这样以及如何解决?

代码如下:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>joined now </title>

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

</head>
<body>
<div>this is at the top</div>
<c:import url="header.jsp" />
<c:import url="navigationBar.jsp" />  
<c:import url="leftpane.jsp" /> 
<c:import url="mainContent.jsp" /> 
<c:import url="rightpane.jsp" />
<c:import url="footer.jsp" />  
</body>
</html>

【问题讨论】:

  • 你用来加载 CSS 文件的 URL 显然不正确。发布您的 HTML 代码并告诉我们用于显示 HTML 页面的 URL。
  • 工作空间项目中所有这些的路径是什么?
  • css 与访问它的 jsp 页面位于同一文件夹中,即 WEB-CONTENTS。所以我不认为这条路径是这里的问题。

标签: jsp jstl assets el


【解决方案1】:

您收到404 File Not Found 错误的原因是您的CSS 路径作为href 属性的值缺少上下文路径

一个 HTTP 请求 URL 包含以下部分:

http://[host]:[port][request-path]?[query-string]

请求路径进一步由以下元素组成:

  • 上下文路径:正斜杠 (/) 与 servlet 的 Web 应用程序的 context root 的串联。示例:http://host[:port]/context-root[/url-pattern]

  • Servlet 路径:组件对应的路径部分 激活此请求的别名。这条路从前锋开始 斜线 (/)。

  • 路径信息:请求路径中不属于 上下文路径或 servlet 路径。

阅读更多here


解决方案

您的问题有多种解决方案,以下是其中的一些:

1) 使用来自 JSTL 的 &lt;c:url&gt; 标签

在我的 Java Web 应用程序中,我通常在定义 CSS/JavaScript/image 和其他静态资源的路径时使用来自 JSTL&lt;c:url&gt; 标记。通过这样做,您可以确保引用这些资源始终相对于应用程序上下文(上下文路径)。

如果您说您的 CSS 位于 WebContent 文件夹中,那么这应该可以:

<link type="text/css" rel="stylesheet" href="<c:url value="/globalCSS.css" />" />

JavaServer Pages™ 标准标签库”版本 1.2 specification 第 7.5 章(强调我的)中解释了它的工作原理:

7.5
构建一个应用了正确重写规则的 URL。
...
URL 必须是绝对 URL 以方案开头(例如“http://server/context/page.jsp”)或 JSP 1.2 在 JSP.2.2.1 中定义的相对 URL “相对 URL 规范”。因此,实现必须在 以斜杠开头的 URL 的上下文路径(例如“/page2.jsp”)所以 客户端浏览器可以正确解释此类 URL。

注意
不要忘记在您的 JSP 中使用 Taglib 指令 以便能够引用 JSTL tags。另请参阅示例 JSP 页面 here


2) 使用 JSP 表达式语言和隐式对象

替代解决方案是使用Expression Language (EL) 添加应用程序上下文:

<link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/globalCSS.css" />

在这里,我们从 request 对象中检索了上下文路径。为了访问请求对象,我们使用了 pageContext implicit object


3) 使用来自 JSTL 的&lt;c:set&gt; 标签

免责声明
这个解决方案的想法来自here

要使访问上下文路径比在解决方案 №2 中更紧凑,您可以首先使用 JSTL &lt;c:set&gt; 标记,即 EL 变量的 sets the value 或任何 JSP 范围内的 EL 变量的属性(页面、请求、会话或应用程序)供以后访问。

<c:set var="root" value="${pageContext.request.contextPath}"/>
...
<link type="text/css" rel="stylesheet" href="${root}/globalCSS.css" />

重要提示
默认情况下,为了以这种方式设置变量,包含此 set 标签的 JSP 必须至少访问一次(包括在application 范围使用 scope 属性,例如 &lt;c:set var="foo" value="bar" scope="application" /&gt;),之前 使用这个新变量。例如,您可以在需要此变量的地方拥有 几个 JSP 文件。因此,您必须 a) bothapplication 范围内设置新变量保存上下文路径并首先访问此 JSP,然后在其他 JSP 文件中使用此变量,或 b)在每个 JSP 文件中设置此上下文路径保存变量,您需要在其中访问它。


4) 使用 ServletContextListener

使访问上下文路径更紧凑的更有效方法是设置一个变量,该变量将保存上下文路径,并使用Listener 将其存储在应用程序scope中。此解决方案类似于解决方案 №3,但好处是现在变量保存上下文路径设置在 Web 应用程序的开始处,并且在应用程序范围内可用,无需额外步骤。

我们需要一个实现ServletContextListener 接口的类。这是此类的一个示例:

package com.example.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class AppContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        ServletContext sc = event.getServletContext();
        sc.setAttribute("ctx", sc.getContextPath());
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {}

}

现在在 JSP 中,我们可以使用 EL 访问这个全局变量:

<link type="text/css" rel="stylesheet" href="${ctx}/globalCSS.css" />

注意
@WebListener 注释自 Servlet 版本 3.0 起可用。如果您使用支持旧 Servlet 规范的 servlet 容器或应用程序服务器,请删除 @WebServlet 注释,并改为在 部署描述符 (web.xml) 中配置侦听器。以下是支持最大 Servlet 版本 2.5 的容器的 web.xml 文件示例(为简洁起见,省略其他配置):

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    ...  
    <listener>
        <listener-class>com.example.listener.AppContextListener</listener-class>
    </listener>
    ...
</webapp>


5) 使用脚本

作为suggested 用户@gavenkoa 你也可以像这样使用scriptlets

<%= request.getContextPath() %>

这么小的东西应该没问题,注意generally the use of scriptlets in JSP is discouraged


结论

我个人更喜欢第一种解决方案(大部分时间在我以前的项目中使用它)或第二种解决方案,因为它们最清晰、直观和明确(恕我直言)。但你选择最适合你的。


其他想法

您可以将您的网络应用程序部署为默认应用程序(即在默认根上下文中),以便无需指定上下文路径即可访问它强>。更多信息请阅读“更新”部分here

【讨论】:

    【解决方案2】:

    使用以下代码解决此问题.... >

    <style type="text/css">
        <%@include file="css/style.css" %>
    </style>
    <script type="text/javascript">
        <%@include file="js/script.js" %>
    </script>
    

    【讨论】:

      猜你喜欢
      • 2014-12-27
      • 1970-01-01
      • 2018-07-16
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多