在Web应用程序中处理上下文的任何聪明方法?

Wil*_*ung 39 java jsp servlets contextpath

在Java中,Web应用程序捆绑在WAR中.默认情况下,许多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(没有特别优雅的方法).

对于编码人员来说,跳出何时使用"App Relative"网址与绝对网址是一个很小的问题.

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

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

你是做什么?

小智 24

您可以使用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>
Run Code Online (Sandbox Code Playgroud)

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

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


Bal*_*usC 8

对于HTML页面,我只是设置HTML <base>标记.每个相对链接(即不以方案或开头/)将变得相对于它.没有干净的方法可以立即抓住它 HttpServletRequest,所以我们在这里需要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="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>
Run Code Online (Sandbox Code Playgroud)

然而,这又是一个警告:锚点(#identifierURL)也将相对于基本路径.如果您有任何一个,则希望相对于请求URL(URI).所以,改变就好

<a href="#identifier">jump</a>
Run Code Online (Sandbox Code Playgroud)

<a href="${uri}#identifier">jump</a>
Run Code Online (Sandbox Code Playgroud)

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

var base = document.getElementsByTagName("base")[0].href;
Run Code Online (Sandbox Code Playgroud)

或者如果你做jQuery

var base = $("base").attr("href");
Run Code Online (Sandbox Code Playgroud)

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

/css/style.css
/css/images/foo.png
Run Code Online (Sandbox Code Playgroud)

并参考如下

background-image: url('images/foo.png');
Run Code Online (Sandbox Code Playgroud)

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

/css/style.css
/images/foo.png
Run Code Online (Sandbox Code Playgroud)

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

background-image: url('../images/foo.png');
Run Code Online (Sandbox Code Playgroud)

也可以看看: