使用"<%=request.getContextPath()%>"相比于"../"有什么优势?

29

我曾在多个J2EE项目中工作,其中视图层是JSP。 在大多数项目中,我们使用上下文路径(contextPath)在脚本中引用外部资源,例如图片、JavaScript、JSP文件和CSS。

以下为代码:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>GC Demo Using HandlebarsJS</title>
    <script type="text/javascript" src="<%=request.getContextPath()%>/js/jqueryUI-AutoComplete/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="<%=request.getContextPath()%>/js/jqueryUI-AutoComplete/jquery-ui-1.10.3.custom.js"></script>
    <script type="text/javascript" src="<%=request.getContextPath()%>/js/handlebarsJS/handlebars.js"></script>
    <link rel="stylesheet" type="text/css" href="${pageContext.servletContext.contextPath}/js/jqueryUI-AutoComplete/jquery-ui-1.10.3.custom.css">

从上面的jsp文件中,我在导入同一项目束(即war)中的外部资源。

现在,同样的JSP可以编写成以下代码:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>GC Demo Using HandlebarsJS</title>
    <script type="text/javascript" src="../js/jqueryUI-AutoComplete/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="../js/jqueryUI-AutoComplete/jquery-ui-1.10.3.custom.js"></script>
    <script type="text/javascript" src="../js/handlebarsJS/handlebars.js"></script>
    <link rel="stylesheet" type="text/css" href="../js/jqueryUI-AutoComplete/jquery-ui-1.10.3.custom.css">

在第二个示例中,我也引用了我的war文件中存在的资源。

现在考虑以上两种情况,第一种情况被认为是最佳实践,给予更多重视。

为什么?

使用第二种情况有哪些缺点?

使用第二种情况是否会使我们的项目与上下文路径更加紧密耦合?

请解释一下。


第二种情况中上下文路径在哪里? - Abdullah Shaikh
1个回答

62

request.getContextPath() 返回您的应用程序的根路径,而 ../ 返回文件的父目录。

使用 request.getContextPath() 可以始终指向您的应用程序的根目录。如果您将 jsp 文件从一个目录移动到另一个目录,无需更改任何内容。 现在考虑第二种方法。如果您将 jsp 文件从一个文件夹移动到另一个文件夹,则必须在每个引用文件的位置进行更改。

此外,更好的方法是使用 request.getContextPath() 设置一个变量,并使用该变量来引用您的路径。

<c:set var="context" value="${pageContext.request.contextPath}" />
<script src="${context}/themes/js/jquery.js"></script>

PS-这是我能想到的唯一原因。不知道它是否还有其他重要性。


1
"${pageContext.servletContext.contextPath}"和您建议的不同吗?应该使用哪一个?为什么? - Koray Tugay
2
@DhruvPal 访问局部变量比访问实例变量更快(可以忽略不计),因此我们可以节省一些时间(https://dev59.com/yWEi5IYBdhLWcg3wIJJH)。 此外,这种方法可以使您的链接看起来更干净。当页面上有很多链接时,这很有帮助。 如果您只引用contextPath一次,则不必担心将其设置为变量。但是,当您使用它们多个时,它会有所帮助。在原始帖子中,OP使用了<%=request.getContextPath()%>即scriplet。当然,使用EL标签而不是scriplet是更好的方法。 - Sudarshan_SMD
1
@DhruvPal 是的,如果您正在使用Tiles,则可以将变量放在common.jsp或默认布局中。 是的,这不是一个繁重的方法。如果有任何性能差异,那么差异将是可以忽略不计的。 - Sudarshan_SMD
我想到你可以使用HTML的<base>标签来帮助解决这个问题。 - Powerlord
@Powerlord,是的,使用<base>标签确实有效。您不必在每个URL中显式指定${context}。但是,<base>标签将定义的基本URL前缀添加到每个URL中,如果您使用命名锚点,则会导致问题。https://dev59.com/enI-5IYBdhLWcg3wYXL8 对<base>标签的使用进行了一些很好的讨论。我更喜欢不使用<base>标签来控制事物。但是,如果您认为使用<base>标签更合适,我将编辑答案以包括其用法。谢谢。 - Sudarshan_SMD
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接