我们使用tomcat urlrewrite插件重写出站URL和入站URL。为此,您需要使用JSTL标记。
这对于干净的网址和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>
感谢。
答案 0 :(得分:2)
没有任何开箱即用,但没有什么能阻止你编写自己的EL函数,因此使用类似的东西:
<a href='${myFn:url("/nextPage.jsp")}' />Next Page</a>
我觉得它比标准的c:url标签更具可读性,但如果必须接受参数名称和值,它会更糟糕。
有关如何定义和使用EL函数的信息,请参阅http://docs.oracle.com/javaee/1.4/tutorial/doc/JSPIntro7.html。
答案 1 :(得分:1)
几种方法在哪里。
1)将基数绑定到常见片段中的变量:
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><a href="<c:url value='/my/path/${id}.html'/>">Title</a></pre>
* allow to use:
* <pre><a href="${ctx}/my/path/${id}.html">Title</a></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
可以在上下文部署描述符中的WAR文件外部设置为dev
或min
,并且在未设置时回退到缩小版本。
4)使用scriplets :
<a href="<%=request.getContextPath()%>/index.html">Home</a>
答案 2 :(得分:0)
我最终提出的解决方案是使用自定义标签来解决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解决方案会更清晰,但如果您想添加对其他参数或属性的支持,则可能需要使用标记。