【问题标题】:Is there an JSTL EL (Expression Language) Equivalent to <c:url/>是否有等效于 <c:url/> 的 JSTL EL(表达式语言)
【发布时间】:2012-05-31 19:49:47
【问题描述】:

我们使用 tomcat urlrewrite 插件来重写出站 URL 以及入站 URL。为此,您需要使用 JSTL 标记。

这对于干净的 url 和 i18n 非常有用,但是它会产生丑陋的代码,包括标签内的标签,如下所示:

<link href='<c:url value="/content/bootstrap/css/bootstrap.css" />' rel="stylesheet" />

或:

<a href='<c:url value="/nextPage.jsp"/>' />Next Page</a>

另一种方法是使用变量,如下所示:

<c:url value="/nextPage.jsp" var="nextPageUrl"/>
<a href='${nextPageUrl}' />Next Page</a>

这真的很干净,但是很冗长。

有没有一种表达语言友好的方式来做到这一点?

我有点希望:

<a href='${url "/nextPage.jsp}' />Next Page</a>

谢谢。

【问题讨论】:

  • ${pageContext.request.contextPath}/nextPage.jsp ?不适用于出站,但它使应用程序的链接非常干净。
  • 这并没有解决目标。关键是通过Tomcat提供的整个出站链接格式化逻辑以及您安装的任何过滤器(如urlrewrite)运行url。在这种情况下,我们正在做一些比绝对路径更复杂的事情,我们正在重写 js 文件以包含用于缓存清除的构建版本。

标签: jsp jstl el


【解决方案1】:

没有什么是开箱即用的,但没有什么能阻止您编写自己的 EL 函数,因此可以使用类似的东西:

<a href='${myFn:url("/nextPage.jsp")}' />Next Page</a>

我不觉得它比标准的 c:url 标记更具可读性,但如果它必须接受参数名称和值,那就更糟了。

请参阅http://docs.oracle.com/javaee/1.4/tutorial/doc/JSPIntro7.html 了解如何定义和使用 EL 函数。

【讨论】:

  • 谢谢。我的目标是避免嵌套标签。嵌套标签会使 IDE 感到困惑,并且读起来非常讨厌。我同意上述内容也不是很清楚,但它比标签更好。我会调查一下,谢谢。
【解决方案2】:

有几种方法。

1) 将 base 绑定到公共片段中的变量

common.jspf:

<%@tag language="java" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:url value="/" var="base"/>

或喜欢:

<c:set var="base" value="${pageContext.request.contextPath}"/>

在每个页面中包含片段

<%@include file="base.jspf"%>
<script src="${base}/js/jquery.js"></script>
<link href="${base}/css/bootstrap.css" rel="stylesheet" type="text/css">
<a href="${base}/index.html">Home</a>

2) 在任何地方使用 ${pageContext.request.contextPath}

<script src="${pageContext.request.contextPath}/js/jquery.js"></script>
<link href="${pageContext.request.contextPath}/css/bootstrap.css" rel="stylesheet" type="text/css">
<a href="${pageContext.request.contextPath}/index.html">Home</a>

3) 是我最喜欢的:添加包含属性基础的过滤器

/src/java/company/project/web/filter/BaseFilter.java

import java.io.IOException;
import javax.servlet.*;

/**
 * Make sane JSP, instead of:
 *   <pre>&lt;a href="&lt;c:url value='/my/path/${id}.html'/&gt;"&gt;Title&lt;/a&gt;</pre>
 * allow to use:
 *   <pre>&lt;a href="${ctx}/my/path/${id}.html"&gt;Title&lt;/a&gt;</pre>
 */
public class BaseFilter implements Filter {

    @Override
    public void init(FilterConfig fc) {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setAttribute("base", request.getServletContext().getContextPath());
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() { }

}

并在web.xml注册该过滤器

<filter>
    <filter-name>BaseFilter</filter-name>
    <filter-class>company.project.web.filter.BaseFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>BaseFilter</filter-name>
    <url-pattern>*.htm</url-pattern>
    <url-pattern>*.json</url-pattern>
</filter-mapping>

并使用简洁的语法(如上,但不需要包含样板片段):

<script src="${base}/js/jquery.js"></script>
<link href="${base}/css/bootstrap.css" rel="stylesheet" type="text/css">
<a href="${base}/index.html">Home</a>

注意我在该过滤器中设置了其他属性,例如在 CSS/JS 的开发版本和缩小版本之间切换:

private String min;

@Override
public void init(FilterConfig fc) {
    min = fc.getServletContext().getInitParameter("min");
    if (min == null)
        min = fc.getInitParameter("min");
    if (min == null)
        min = "min";
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    request.setAttribute("ctx", request.getServletContext().getContextPath());
    request.setAttribute("min", min);
    chain.doFilter(request, response);
}

及对应的JSP代码:

<script src="${base}/js/jquery.${min}.js"></script>
<link href="${base}/css/bootstrap.${min}.css" rel="stylesheet" type="text/css">

初始参数min 可以在外部设置为devmin 在contex 部署描述符中的WAR 文件中,未设置时回退到缩小版本。

4) 使用脚本

<a href="<%=request.getContextPath()%>/index.html">Home</a>

【讨论】:

    【解决方案3】:

    我最终想出的解决方案是使用自定义标签来解决 CSS 和 JS 的问题。当然,类似的解决方案也可以应用于标签,尽管我还没有需要。

    <my:csslink url="/css/custom.css" />
    <my:script url="/script/myscript.js" />
    

    CSS 标签看起来像这样,Javascript 的标签显然很相似:

    <%@tag language="java" pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    
    <%@attribute name="url" required="true" type="java.lang.String" description="the absolute (to the webapp) path of the css file"%>
    <c:url var="encUrl" value='${url}' />
    <link href='${encUrl}' rel='stylesheet' />
    

    别忘了在你的jsp中导入标签:

    <%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
    

    在某些情况下,自定义 EL 解决方案会更简洁,但如果您想添加对其他参数或属性的支持,标签可能是要走的路。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      • 2012-02-16
      • 2012-01-25
      • 2012-05-06
      • 2018-09-15
      • 1970-01-01
      相关资源
      最近更新 更多