Rule of thumb: Avoid to use {variables} as the first path of a Jersey's @Path

I am working on the Arena PUJ Project, a RESTful web-service to support PUJ competitions. We are in the early stages of the project but we already got some resources published on the web. Let me show you a few URL samples:

  1. An insecure GET method to read all competitions promoted by a JUG:

    GET /{competition_id}/homework

    Sample URL: http://fgaucho.dyndns.org:8080/arena-http/institution/cejug/competition

    curl -v -H "Accept: application/json" -XGET http://fgaucho.dyndns.org:8080/arena-http/institution/cejug/competition

  2. An insecure GET method to read all homeworks from a competition name:

    GET /{competition_id}/homework

    Sample URL: http://fgaucho.dyndns.org:8080/arena-http/PUJCE-08/homework

    curl -v -H "Accept: application/json" -XGET http://fgaucho.dyndns.org:8080/arena-http/PUJCE-08/homework

  3. A secure method for creating a new homework. In the PUJ business model, only professors can submit a homework.

    POST /{competition_id}/homework/{homework_id}

    Sample URL: http://fgaucho.dyndns.org:8080/arena-http/PUJCE-08/homework/newHomework

    curl -v -H "Accept: application/json" -XPOST http://fgaucho.dyndns.org:8080/arena-http/PUJCE-08/homework/newHomework

The problem: you cannot map variables in the beggining of the path in the web.xml

In Jersey, all the above URLs are valid, actually Jersey can also use regular expressions to map URLs to resources. A cool feature that looses its beauty in the web.xml file.

Observe the third example, it is a URL that starts with a variable, in Jersey it is declared like this:

@Path("{puj}/homework") <-- Avoid to use {variables} as the first path of a resource
public class PujHomeworkResource {
    @POST
    @Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
    @Path("{acronym}")
    public PujHomeworkEntity create(@PathParam("puj") String name, @PathParam("acronym") String acronym) {
        // click here to see the full code.
    }
}

And the simple problem is: web.xml does not support dynamic patterns in the same way Jersey do. So, you just cannot declare a url-pattern like /*/homework/*:

    <security-constraint>
        <display-name>Restrict advertisement pages to
            customers</display-name>
        <web-resource-collection>
            <web-resource-name>To create Homework is privileged to Professors</web-resource-name>
            <description />
            <url-pattern>/*/homework/*</url-pattern> <-- This is valid but useless :(
            <http-method>POST</http-method>
            <http-method>GET</http-method>
        </web-resource-collection>
        <auth-constraint>
            <description>PUJ Homeworks.</description>
            <role-name>professor</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

Such url-pattern /*/homework/* will not map URLs like /PUJCE-09/homework or/GOJAVA-09/homework. It is yet possible to use the variables from Jersey, but it would required a static mapping for each possible value in the web.xml file - useless.

Workarounds

    
There is no much I can see as alternative other than to refactor my code and do include a static path in the beginning of my URLs. An alternative proposed by Dr. Hadley is to use the@RolesAllowed annotation, what can fix the problem but eventually creates another problem (IMO). If you declare the security of your application by annotations, you need to recompile and re-deploy the whole application on every security constraints update. In case you know in advance that your application will have seldom updates, ok - go ahead and use the annotations. For now, I will include the static names in the beginning of all paths. Once I finish that task, I will continue my REST trip and perhaps come back here with more details. I included some references below in case you are looking for what the specs say about that :)http://jersey.dev.java.net/images/Jersey_yellow.png

The Mappings in the Servlet 2.5 specification

From the section 11.2 of the Servlet 2.5 Specification, you read:

  • In the Web application deployment descriptor, the following syntax is used to define mappings:

    • A string beginning with a