static image (e.g. car.png)
<table><tr><td><img src="http://<somehost>:<someport>/images/car.png" /></td></tr></table>
(e.g. lookup by id=123456 and fetched via a servlet from the database)
<table><tr><td><img src="http://<somehost>:<someport>/doc?id=123456"/></td></tr></table>
我们生成 HTML 代码片段(如上所述)并将它们存储在数据库中,该数据库用于以动态方式重新构建用户特定页面。
上述场景中的问题是 somehost/someport 是静态绑定(bind)并存储在数据库中的,我想避免这种情况,因为如果我必须升级到具有不同 IP 的不同机器,所有上述调用都将失败。
如何以通用方式解决此问题,以便我可以在稍后阶段绑定(bind)主机/端口。
最佳答案
首先,将 HTML 存储在数据库中并不是一个好主意。但是唉。
至于具体问题,您可以只定义一个 HTML <base>
标记,它会使文档中的所有相对 URL 成为它的相对 URL。
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<head>
<c:set var="r" value="${pageContext.request}" />
<base href="${fn:replace(r.requestURL, r.requestURI, '')}${r.contextPath}/" />
</head>
这样你就可以使用
<table><tr><td><img src="images/car.png" /></td></tr></table>
<table><tr><td><img src="doc?id=123456"/></td></tr></table>
如果没有基础,您将依赖于上下文路径。
如果您真的想要参数化它们,那么我会使用 java.text.MessageFormat
。您可以使用 {0}
、 {1}
、 {2}
等作为第一、第二、第三等参数的占位符。
<table><tr><td><img src="{0}/images/car.png" /></td></tr></table>
<table><tr><td><img src="{0}/doc?id=123456"/></td></tr></table>
您可以从 HttpServletRequest
中获取当前主机/端口(和上下文!),如下所示:
HttpServletRequest r = getItSomehow();
String base = r.getRequestURL().toString().replace(r.getRequestURI(), "") + r.getContextPath();
您可以按如下方式格式化来自数据库的 HTML:
String html = getItSomehow();
String formatted = MessageFormat.format(html, base);
然后在 JSP 中显示它。您甚至可以将其包装在自定义 EL 函数中。更重要的是,一些像 JSF 这样的 MVC 框架也有在幕后使用 MessageFormat
的标签。例如
<h:outputFormat value="#{bean.html}" escape="false">
<f:param value="#{bean.base}" />
</h:outputFormat>
关于java - 解决主机/端口查找的更好设计是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5350816/