2

I found this code VERY ugly:

<a href="<c:url value='/my/path/${id}.html'/>">Title</a>

in:

href="<c:url value=

and:

'/>">

parts. Are there any standard function available from JSP EL, which do same job as JSTL c:out, but look like:

<a href="${f:context('/my/path/'.concat(id).concat('.html'))">Title</a>

or better:

<a href="${f:context}/my/path/${id}.html">Title</a>
gavenkoa
  • 45,285
  • 19
  • 251
  • 303
  • 1
    Related: http://stackoverflow.com/questions/3655316/browser-cant-access-find-relative-resources-like-css-images-and-links-when-cal/3658735#3658735 – BalusC Jul 04 '13 at 11:43
  • @BalusC Thanks for great link! I study question about using **base** HTML tag but found that it have a lot of pitfall as according to W3C spec it require *absolute* path which un-excepted as we use load balance proxy... +1 – gavenkoa Jul 04 '13 at 11:52
  • That answer also shows how to generate the right one. – BalusC Jul 04 '13 at 11:53
  • Thanks! I see **req.requestURL** in **base** tag )) – gavenkoa Jul 04 '13 at 11:55

3 Answers3

2

You can do:

<c:url value='/my/path/${id}.html' var="myUrl"/>
<a href="${myUrl}">My Url</a>

This will store the URL in the variable myUrl, which can be used as expression in the a tag.

Uooo
  • 6,204
  • 8
  • 36
  • 63
  • thanks for answer, look to my answer, where I put a bit more options. One drawback - you must put **c:url var= value=** at the beginning of each JSP files... +1 – gavenkoa Jul 04 '13 at 11:02
2

Or better:

<a href="${f:context}/my/path/${id}.html">Title</a>

This is possible:

<a href="${pageContext.request.contextPath}/my/path/${id}.html">Title</a>

If you find it lengthy, just alias it with a <c:set> elsewhere in top of your master template like so

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

so that you can use it anywhere else like

<a href="${ctx}/my/path/${id}.html">Title</a>

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

My study on this field shown me that I can put ctx parameter in own EE filter in web.xml:

<filter>
    <filter-name>ctxFilter</filter-name>
    <filter-class>org.my.web.filter.CtxFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ctxFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

and:

public class CtxFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) { }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setAttribute("CTX", request.getServletContext().getContextPath());
        chain.doFilter(request, response);
    }
    @Override
    public void destroy() { }
}

or in Spring interceptor (based on my project framework stack). Also this can be done by:

<spring:url value="/" var="ctx" htmlEncoding="true"/>
<a href="${ctx}/path/...">...</a>

or as:

<c:url value="/" var="ctx"/>
<a href="${ctx}/path/...">...</a>

but fist line of these examples must be duplicated across JSP files.

And finally you can implement TDL file with appropriate function WEB-INF/tlds/ctx.tld:

<function>
    <name>ctx</name>
    <function-class>org.my.web.Ctx</function-class>
    <function-signature>java.lang.String getCtx()</function-signature>
</function>

Reference:

gavenkoa
  • 45,285
  • 19
  • 251
  • 303