Есть ли JSTL EL (язык выражений), эквивалентный <c: url/">
Мы используем плагин tomcat urlrewrite для перезаписи исходящих 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>
Спасибо.
Ответы
Ответ 1
В конечном итоге я решил использовать пользовательские теги для решения проблемы для 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 было бы чище - это некоторые обстоятельства, но если вы хотите добавить поддержку дополнительных параметров или атрибутов, то, вероятно, будет тег.
Ответ 2
Нет ничего из коробки, но ничто не мешает вам писать свои собственные функции EL и, таким образом, использовать что-то вроде этого:
<a href='${myFn:url("/nextPage.jsp")}' />Next Page</a>
Я не чувствую, что он более читабельен, чем стандартный тег c: url, и было бы еще хуже, если он должен принимать имена и значения параметров, однако.
См. http://docs.oracle.com/javaee/1.4/tutorial/doc/JSPIntro7.html для определения и использования функций EL.
Ответ 3
Где несколько подходов.
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
может быть установлен в dev
или min
извне в файл WAR в дескрипторе развертывания contex с отбрасыванием на уменьшенную версию, если не установлен.
4) Используйте скрипты:
<a href="<%=request.getContextPath()%>/index.html">Home</a>