Skip to content

Instantly share code, notes, and snippets.

@danbev
Created January 4, 2013 10:56
Show Gist options
  • Save danbev/4451648 to your computer and use it in GitHub Desktop.
Save danbev/4451648 to your computer and use it in GitHub Desktop.
Path param issue in AeroGear Controller Demo

Path Param with include issue

This gist concerns AEROGEAR-732.

Problem Description

The problem was discovered by Sebastian how needed to use a path parameter for a view in AeroGear Controller. The view in question was simple jsp page that displayed information about a user which is part of an admin section of aerogear-controller-demo. The idea is that when logged in as an administrator you can register and manage users.

To access information about a user you follow a link, for example:

<div class="sixteen columns">
    <table style="border: 1;border-color: gray; border-style: solid">
        <c:forEach var="user" items="${arrayList}">
            <tr><td><a href="show/${user.id}">${user.id}</a></td></tr>
        </c:forEach>
    </table>
</div>

This is a list of users which are links. So if you have a user named fletch the link would be show/fletch. The Route for this looks like this:

route()
       .from("/show/{id}").roles("admin")
       .on(RequestMethod.GET)
       .to(Admin.class).show(pathParam("id"));

So, by the mapping conventions in AeroGear Controller the view for this Route will be WEB-INF/Pages/Admin/show.jsp.
Like the other jsp pages show.jsp includes a header.jsp and a footer.jsp like this:

<jsp:include page="../../template/header.jsp" />

When AeroGear Controller has routed to show.jsp the following error will be displayed in the browsers console:

GET http://localhost:8080/aerogear-controller-demo/show/stylesheets/base.css 404 (Not Found) 
GET http://localhost:8080/aerogear-controller-demo/show/stylesheets/layout.css 404 (Not Found) 
GET http://localhost:8080/aerogear-controller-demo/show/stylesheets/skeleton.css 404 (Not Found)

The above stylesheets are include in header.jsp:

    <link rel="stylesheet" href="stylesheets/base.css">
    <link rel="stylesheet" href="stylesheets/skeleton.css">
    <link rel="stylesheet" href="stylesheets/layout.css">

Why does this page not work when all the other do?

Lets looks at the register.jsp page and see if we can spot a difference:

request.context_path=/aerogear-controller-demo 
forward.request_uri=/aerogear-controller-demo/admin 
forward.context_path=/aerogear-controller-demo 
forward.servlet_path=/admin 
forward.path_info= 
forward.query_string= 
include.request_uri= 
include.context_path= 
include.servlet_path= 
include.path_info= 
include.query_string= 

And the same attributes when accessing show.jsp:

request.context_path=/aerogear-controller-demo 
forward.request_uri=/aerogear-controller-demo/show/beve 
forward.context_path=/aerogear-controller-demo 
forward.servlet_path=/show/beve 
forward.path_info= 
forward.query_string= 
include.request_uri= 
include.context_path= 
include.servlet_path= 
include.path_info= 
include.query_string=

Just to remind myself about the actual error, look at the path:

http://localhost:8080/aerogear-controller-demo/show/stylesheets/base.css

Compare this with the path for base.css from register.jsp:

http://localhost:8080/aerogear-controller-demo/stylesheets/base.css

If we take a look at the generated jsp page for header.jsp:

out.write("<link rel=\"stylesheet\" href=\"stylesheets/base.css\">\n");

So it is the browser that will determine try to resolve this relative to the current context. Since the current page is http://localhost:8080/aerogear-controller-demo/show/beve, the browser will look for stylesheets/base.css in the same "directory": http://localhost:8080/aerogear-controller-demo/show/stylesheets/base.css.

The reason that the other pages work is that they do now use path parameters, take http://localhost:8080/aerogear-controller-demo/admin for example, when the browser tries to resolve the stylesheets it will try using path relative to the current "directory" which will be http://localhost:8080/aerogear-controller-demo/stylesheets/base.css.

Conclusion

I think the proper way to handle this is indeed to add ${pageContext.request.contextPath} to header.jsp:

<link rel="stylesheet" href="${pageContext.request.contextPath}/stylesheets/base.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/stylesheets/skeleton.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/stylesheets/layout.css">
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment