当前位置 : 主页 > 编程语言 > java >

在JSP中添加外部资源(CSS/JavaScript /图像等)

来源:互联网 收集:自由互联 发布时间:2021-06-25
我在我的项目中添加了一个外部CSS样式表,并放置在Eclipse中的项目的WEB-CONTENTS文件夹中。当我将它部署在Tomcat上时,样式表未被应用。当我在Chrome中调试它并打开它,它给我404文件找不
我在我的项目中添加了一个外部CSS样式表,并放置在Eclipse中的项目的WEB-CONTENTS文件夹中。当我将它部署在Tomcat上时,样式表未被应用。当我在Chrome中调试它并打开它,它给我404文件找不到错误。为什么这样和如何解决它?

这是代码:

<%@ 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>
您获得404 File Not Found错误的原因是,您作为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)使用< c:url>标签从JSTL

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

如果你说,你的CSS位于WebContent文件夹内,那么这应该是有效的:

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

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

7.5 <c:url>
Builds a URL with the proper rewriting rules applied.

The URL must be either an absolute URL
starting with a scheme (e.g. “http:// server/context/page.jsp”) or a
relative URL as defined by JSP 1.2 in JSP.2.2.1 “Relative URL
Specification”. As a consequence, an implementation must prepend the
context path to a URL that starts with a slash
(e.g. “/page2.jsp”) so
that such URLs can be properly interpreted by a client browser.

注意
不要忘记在JSP中使用Taglib指令,以便能够参考JSTL tags.另请参见JSP第here页的示例。

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

另一种解决方案是使用Expression Language (EL)来添加应用程序上下文:

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

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

3)使用< c:set>标签从JSTL

免责声明
这个解决方案的想法是从here开始的。

要使访问上下文路径比解决方案№2更紧凑,您可以先使用JSTL <c:set>标签,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必须至少访问一次(包括在使用scope属性设置应用程序范围内的值的情况下,如< c:set var =在使用此新变量之前,“foo”value =“bar”scope =“application”/>)。例如,您可以有几个需要此变量的JSP文件。所以你必须以太网a)在应用程序范围内设置新的变量保存上下文路径并首先访问此JSP,然后在其他JSP文件中使用此变量,或者b)在需要的任何JSP文件中设置此上下文路径保存变量访问它。

4)使用ServletContextListener

使访问上下文路径更紧凑的更有效的方法是设置一个变量,该变量将保存上下文路径并将其存储在应用程序scope中,使用Listener.该解决方案类似于解决方案№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" />

注意
从Servlet 3.0版起,可以使用@WebListener注解。如果您使用支持较早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)使用scriptlet

作为suggested由用户@gavenkoa您也可以使用scriptlets像这样:

<%= request.getContextPath() %>

对于这么小的事情,可能还可以,请注意generally the use of scriptlets in JSP is discouraged。

结论

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

其他想法

您可以将Web应用程序部署为默认应用程序(即,默认根上下文),因此可以在不指定上下文路径的情况下访问它。欲了解更多信息,请阅读“更新”部分here。

网友评论