在 Web 应用中处理上下文有什么聪明的方法吗?

2022-09-01 03:54:57

在Java中,Web应用程序被捆绑到VAR中。默认情况下,许多 Servlet 容器将使用 WAR 名称作为应用程序的上下文名称。

因此,myapp.war被部署到 http://example.com/myapp

问题在于,Webapp认为它的“root”是“root”,或者简称为“/”,而HTML会认为应用程序的根是“/myapp”。

Servlet API 和 JSP 具有帮助管理此功能的功能。例如,如果在 servlet 中,您执行了:response.sendRedirect(“/mypage.jsp”),容器将在上下文前面附加并创建 url:http://example.com/myapp/mypage.jsp”。

但是,你不能用HTML中的IMG标签来做到这一点。如果你<img src=“/myimage.gif”/>你可能会得到404,因为你真正想要的是“/myapp/myimage.gif”。

许多框架也具有上下文感知的 JSP 标记,并且在 JSP 中有不同的方法来制作正确的 URL(没有一种特别优雅)。

对于编码人员来说,跳出何时使用“应用程序相对”URL而不是绝对URL是一个细节问题。

最后,还有一个Javascript代码的问题,它需要动态创建URL,以及在CSS中嵌入URL(用于背景图像等)。

我很好奇其他人使用什么技术来缓解和解决此问题。许多人只是简单地将其平底船和硬编码,要么到服务器根目录,要么到他们碰巧使用的任何上下文。我已经知道这个答案,这不是我想要的。

你是做什么工作的?


答案 1

您可以使用 JSTL 创建 url。

例如,将为上下文根添加前缀。<c:url value="/images/header.jpg" />

对于CSS,这对我来说通常不是问题。

我有一个这样的Web根结构:

/css
/images

在 CSS 文件中,您只需要使用相对 URL (../images/header.jpg),它不需要知道上下文根。

至于JavaScript,对我来说有效的是在页面标题中包含一些常见的JavaScript,如下所示:

<script type="text/javascript">
var CONTEXT_ROOT = '<%= request.getContextPath() %>';
</script>

然后,您可以在所有脚本中使用上下文根(或者,您可以定义一个函数来构建路径 - 可能更灵活一些)。

显然,这一切都取决于您使用JSP和JSTL,但是我将JSF与Facelets一起使用,并且所涉及的技术是相似的 - 唯一真正的区别是以不同的方式获取上下文根。


答案 2

对于HTML页面,我只是设置了HTML标签。每个相对链接(即不以方案或开头)都将变得相对它。没有干净的方法可以立即抓住它,所以我们在这里不需要JSTL的帮助。<base>/HttpServletRequest

<%@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="url">${req.requestURL}</c:set>
<c:set var="uri">${req.requestURI}</c:set>

<!DOCTYPE html>
<html lang="en">
  <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="other.jsp">link</a>
  </body>
</html>

然而,这反过来又有一个警告:锚点(URL)也将相对于基本路径。如果您有其中任何一个,则希望将其设置为相对于请求 URL (URI)。所以,改变像#identifier

<a href="#identifier">jump</a>

<a href="${uri}#identifier">jump</a>

在JS中,只要你想将相对URL转换为绝对URL,就可以从DOM访问元素。<base>

var base = document.getElementsByTagName("base")[0].href;

或者如果你做jQuery

var base = $("base").attr("href");

在 CSS 中,图像 URL 相对于样式表本身的 URL。因此,只需将图像放在相对于样式表本身的某个文件夹中即可。例如:

/css/style.css
/css/images/foo.png

并按如下方式引用它们

background-image: url('images/foo.png');

如果您更喜欢将图像放在与CSS文件夹相同级别的某个文件夹中

/css/style.css
/images/foo.png

然后用于转到公共父文件夹../

background-image: url('../images/foo.png');

另请参阅: