jspservletsresourcesrelative-pathcontextpath

How to use relative paths without including the context root name?


To working my static file (CSS, JS) I have to write absolute path like /AppName/templates/style/main.css. Is there any solution, that I could write relative path like style/main.css?


Solution

  • If your actual concern is the dynamicness of the webapp context (the "AppName" part), then just retrieve it dynamically by HttpServletRequest#getContextPath().

    <head>
        <link rel="stylesheet" href="${pageContext.request.contextPath}/templates/style/main.css" />
        <script src="${pageContext.request.contextPath}/templates/js/main.js"></script>
        <script>var base = "${pageContext.request.contextPath}";</script>
    </head>
    <body>
        <a href="${pageContext.request.contextPath}/pages/foo.jsp">link</a>
    </body>
    

    If you want to set a base path for all relative links so that you don't need to repeat ${pageContext.request.contextPath} in every relative link, use the <base> tag. Here's an example with help of JSTL functions.

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    ...
    <head>
        <c:set var="url">${pageContext.request.requestURL}</c:set>
        <base href="${fn:substring(url, 0, fn:length(url) - fn:length(pageContext.request.requestURI))}${pageContext.request.contextPath}/" />
        <link rel="stylesheet" href="templates/style/main.css" />
        <script src="templates/js/main.js"></script>
        <script>var base = document.getElementsByTagName("base")[0].href;</script>
    </head>
    <body>
        <a href="pages/foo.jsp">link</a>
    </body>
    

    This way every relative link (i.e. not starting with / or a scheme) will become relative to the <base>.

    This is by the way not specifically related to Tomcat in any way. It's just related to HTTP/HTML basics. You would have the same problem in every other webserver.

    See also: