users@jersey.java.net

Appropriate Response Code for URI param errors

From: Rabick, Mark A (MS) <"Rabick,>
Date: Wed, 11 Mar 2009 09:56:48 -0500

In the code below, Javi throws a
WebApplicationException(Response.Status.PRECONDITION_FAILED) in the
event a required query param value is not specified in a URI:
 
@GET
    public String getParamA(@QueryParam("paramA") String paramA) {
        
        if (paramA == null) {
            throw new
WebApplicationException(Response.Status.PRECONDITION_FAILED);
<...>
 
I currently have code that checks query param bound variables for null
on 'required' URI params and throws a 400 (BadRequest)
 
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

public Node getNodeById(@QueryParam("nodeid") String nodeId) {

    if (nodeId == null)

        throw new BadRequestException("parameter [nodeid] required.");

<...>

The BadRequestException wraps a Status.BAD_REQUEST
 
 public class BadRequestException extends WebApplicationException {

    /**
         *
         */
        private static final long serialVersionUID =
5052247111383429632L;

        /**
     * Create a HTTP 400 (Bad Request) exception.
     */
    public BadRequestException() {
        super(Response.status(Status.BAD_REQUEST).build());
    }

    /**
     * Create a HTTP 400 (Bad Request) exception.
     * @param message the String that is the entity of the 400 response.
     */
    public BadRequestException(String message) {
        super(Response.status(Status.BAD_REQUEST)
                        .entity(String.format("BAD REQUEST: %s", message
))
                        .type("text/plain")
                        .build());
    }

}

Is it more appropriate to use a 400 (BAD REQUEST) or 412 (PRECONDITION
FAILED)? It seems that 400 is more appropriate given the HTTP 1.1
Status Code Defintions:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

10.4.1 400 Bad Request

The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without modifications.
 
10.4.13 412 Precondition Failed

The precondition given in one or more of the request-header fields
evaluated to false when it was tested on the server. This response code
allows the client to place preconditions on the current resource
metainformation (header field data) and thus prevent the requested
method from being applied to a resource other than the one intended.

412 seems to be only concerned with request-header conditions, not URL
query parameter values.

--mark
_______________________________________________
Mark A. Rabick - Software Engineer
Em: mark.rabick_at_ngc.com

 


________________________________

        From: Javi Moran [mailto:fjmoranrua_at_gmail.com]
        Sent: Tuesday, March 10, 2009 11:52 AM
        To: users_at_jersey.dev.java.net
        Subject: [Jersey] ambiguous resource method for HTTP method
        
        
        Hello,
        
        I am a newcomer to the jersey project, I am playing with the
resources
        and I have the following question/problem.
        
        I have a class which is a resource and I added to it two methods
with
        the annotation @GET. I wanted one of them was the one invoked
when in
        the http request URL I had a paramater paramA and a second
method to be
        invoked when the http request I received had a parameter paramB.
The
        code is:
        
        "
         @GET
            public String getParamA(@QueryParam("paramA") String paramA)
{
                
                if (paramA == null) {
                    throw new
        WebApplicationException(Response.Status.PRECONDITION_FAILED);
                }
                
                return "Echo " + paramA;
            }
            
            @GET
            public String getParamB(@QueryParam("paramB") String paramB)
{
                
                
                if (paramB == null) {
                    throw new
        WebApplicationException(Response.Status.PRECONDITION_FAILED);
                }
                return "Echo " + paramB;
                
            }
        "
        
        When I run this I get the runtime error:
        
        GRAVE: A resource, class org.masterswl.rest.HelloWorldResource,
has
        ambiguous resource method for HTTP method GET and output
mime-type:
        text/plain. The problematic mime-type sets (as defined by
@Produces
        annotation at Java methods getParamA and getParamB) are
[text/plain] and
        [text/plain]
        10-mar-2009 17:40:47
        com.sun.jersey.server.impl.application.WebApplicationImpl
        newResourceClass
        
        com.sun.jersey.api.container.ContainerException: Fatal issues
found at
        class org.masterswl.rest.HelloWorldResource. See logs for more
details.
                at
        
com.sun.jersey.server.impl.application.WebApplicationImpl.newResourceCla
ss(WebApplicationImpl.java:286)
        
        So, the question is ?
        
           (*) Is there an error in jersey or in my installation or
isn't
        there ?
           (*) If there isn't an error, cannot you design the things in
the way
        I did ?
        
        ---
        Javier Moran Rua