users@jersey.java.net

Re: [Jersey] 400 Bad Request (bug?)

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Tue, 22 Sep 2009 18:07:00 -0700

Jordi Domingo wrote:
> Hi Craig,
>
> I just expected a null value in the Long field when the field is
> empty. 0 is not the same as null for me.
>
> Thanks for your reply,
>
Ah ... it's not a null problem because you are actually including the
field in your query parameters. The problem is that you are trying to
convert a zero length string to a Long, and that will fail. To test
this, try the following program:

    public class Foo {

        public static void main(String args[]) {
            System.out.println("Attempting to convert zero length string
to Long");
            Long value = new Long("");
            System.out.println(" Value was " + value.toString());
        }

    }

and you'll find that it returns an exception:

    Exception in thread "main" java.lang.NumberFormatException: For
input string: ""
        at
java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
        at java.lang.Long.parseLong(Long.java:431)
        at java.lang.Long.<init>(Long.java:678)
        at Foo.main(Foo.java:5)

which means you are going to need to do one of two things:

* Convince your client not to send this value (if it is a browser, maybe
run some Javascript
   to set the input field to disabled so it will not be included in the
form submit).

* Use a String for the method parameter, and only attempt the conversion
if the
   string is both not-null and not-zero-length.

If you use the first technique, you're still going to get conversion
errors if there are invalid characters in the input value coming from
the browser, so I stand by my suggestion to accept string parameters and
validate them yourself if you want to manage what kind of error gets
returned to the client.

Craig


> Jordi
>
> ------------------------------------------------------------------------
> Date: Tue, 22 Sep 2009 16:29:31 -0700
> From: Craig.McClanahan_at_Sun.COM
> To: users_at_jersey.dev.java.net
> Subject: Re: [Jersey] 400 Bad Request (bug?)
>
> Jordi Domingo wrote:
>
> Thanks for answering Greg.
>
> Its true what you say, java speaking but I disagree. I think this
> is a bug. Having a parameter with no value must be translated to a
> null. I've been working many years with java servers and i've
> never seen something like this.
>
> I cant give a 0 to a null value, its not valid for me. Anyway its
> easy to overcome this problem, but i preferred not doing that.
>
> If you test a form in a browser, you'll see that all param names
> are encoded, with or without value.
>
> Thanks again for your interest Greg,
>
> If some of your numeric values are optional, you can use the
> @DefaultValue("0") annotation to tell JAX-RS to assume if no value was
> specified by the user:
>
> @FormParam("standardProvidersCodesId") @DefaultValue("0") Long
> standardProviderCodesId
>
> However, your overall approach is still subject to a huge problem ...
> if the user types "abc" instead of "123" into a field that you have
> mapped to an Integer or a Long (or whatever), you are going to get
> conversion exceptions. The only way to reliably avoid that is to
> accept the form parameter values as strings and convert them yourself
> (sending back a 400 response if any of the conversions fail).
>
> Craig
>
> Jordi
>
> ------------------------------------------------------------------------
> From: ggiacovelli_at_ea.com <mailto:ggiacovelli_at_ea.com>
> To: users_at_jersey.dev.java.net <mailto:users_at_jersey.dev.java.net>
> Date: Tue, 22 Sep 2009 13:28:36 -0700
> Subject: RE: [Jersey] 400 Bad Request (bug?)
>
> Yes, but that’s the point.
>
>
>
> Since your request payload was in the form
>
> identifier=identifier&usersId=1&statusId=1&weaknessesId=4&name=name&description=description&visibility=I&*standardProvidersCodesId=*&severity=2&difficulty=2&risk=1
>
>
>
> the string value “” (empty string) will be passed to the
> constructor or static function of Long. This is an invalid value
> for a long and will probably throw a runtime exception.
>
>
>
> Something like the following would be triggered for it.
>
> Exception in thread "main" java.lang.NumberFormatException: For
> input string: ""
>
> at
> java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
>
> at java.lang.Long.parseLong(Long.java:424)
>
> at java.lang.Long.valueOf(Long.java:518)
>
>
>
> So again I still don’t think this is a bug, more so that you are
> sending the request with an empty string rather than a null.
>
>
>
> You might be able to try using a Long instance still in the
> parameter list of the method and just not specifying the
> standardProviderCodesId at all on the form payload. And then just
> making sure to specify a default value, @DefaultValue(0)(I assume
> you are trying to get a 0 value if none specified). Not sure if
> that will work for what you are trying to achieve.
>
>
>
> Hope it helps.
>
>
>
> -Greg
>
>
>
> *From:* Jordi Domingo [mailto:noseya_at_hotmail.com]
> *Sent:* Tuesday, September 22, 2009 10:48 AM
> *To:* users_at_jersey.dev.java.net <mailto:users_at_jersey.dev.java.net>
> *Subject:* RE: [Jersey] 400 Bad Request (bug?)
>
>
>
> Thats exactly what you said but.. Long has a constructor that
> accepts a single String
> argument http://java.sun.com/javase/6/docs/api/java/lang/Long.html#Long(java.lang.String)
> <http://java.sun.com/javase/6/docs/api/java/lang/Long.html#Long%28java.lang.String%29>
> but also has a static valueOf so it should work fine.
>
>
>
> Thanks,
>
>
>
> Jordi
>
>
>
> ------------------------------------------------------------------------
>
> From: ggiacovelli_at_ea.com <mailto:ggiacovelli_at_ea.com>
> To: users_at_jersey.dev.java.net <mailto:users_at_jersey.dev.java.net>
> Date: Tue, 22 Sep 2009 10:17:25 -0700
> Subject: RE: [Jersey] 400 Bad Request (bug?)
>
> I think this is just the way the spec is written.
>
>
>
> 1. Primitive types 19
>
> 2. Types that have a constructor that accepts a single String
> argument 20
>
> 3. Types that have a static method named valueOf with a single
> String argument 21
>
> 4. List<T>, Set<T>, or SortedSet<T>, where T satisfies 2 or 3 above.
>
>
>
> FormParam is said to be similar to the constructs which bind the
> others (QueryParam,PathParam, etc).
>
>
>
> The other examples you mention use String.ValueOf(“”) which is
> valid as “”;
>
>
>
>
>
> @FormParam("standardProvidersCodesId") Long standardProvidersCodesId
>
> By default this should do Long.valueOf(“”). This does not seem to
> be valid, and results in the 400 I presume.
>
>
>
>
>
> This does not seem like a bug.
>
>
>
> -Greg
>
>
>
>
>
> *From:* Jordi Domingo [mailto:noseya_at_hotmail.com]
> *Sent:* Tuesday, September 22, 2009 8:09 AM
> *To:* users_at_jersey.dev.java.net <mailto:users_at_jersey.dev.java.net>
> *Subject:* RE: [Jersey] 400 Bad Request (bug?)
>
>
>
> Hi again.
>
>
>
> Im quite sure this is a bug. This happens when the param is a
> number, but never when it is a String.
>
>
>
> Let's see what Jersey people say :)
>
> Thanks
>
>
>
> Jordi
>
> ------------------------------------------------------------------------
>
> From: noseya_at_hotmail.com <mailto:noseya_at_hotmail.com>
> To: users_at_jersey.dev.java.net <mailto:users_at_jersey.dev.java.net>
> Date: Tue, 22 Sep 2009 16:30:18 +0200
> Subject: RE: [Jersey] 400 Bad Request (bug?)
>
> Thanks for replying Herak.
>
>
>
> The class is annotated:
>
>
>
> @Path("/projects/{projectId: [0-9]{1,8}}/vulnerabilities")
>
> public class VulnerabilitiesResource{
>
>
>
> ..
>
>
>
> @POST
>
> @Produces({"application/json"})
>
> public Response post(@Context UriInfo uriInfo,
> @PathParam("projectId") int projectId, @FormParam("identifier")
> String identifier,
>
>
> @FormParam("usersId") Long usersId, @FormParam("statusId") Integer
> statusId, @FormParam("weaknessesId") Integer weaknessesId,
>
>
> @FormParam("name") String name, @FormParam("description") String
> description, @FormParam("consequences") String consequences,
>
>
> @FormParam("mitigations") String mitigations,
> @FormParam("cvssBase") java.math.BigDecimal cvssBase,
>
>
> @FormParam("cvssTemporal") java.math.BigDecimal cvssTemporal,
> @FormParam("cvssEnvironment") java.math.BigDecimal cvssEnvironment,
>
>
> @FormParam("standardProvidersCodesId") Long
> standardProvidersCodesId, @FormParam("visibility") String visibility,
>
>
> @FormParam("severity") Integer severity, @FormParam("difficulty")
> Integer difficulty, @FormParam("probability") Integer probability,
>
>
> @FormParam("risk") Integer risk) throws SystemException{
>
> ...
>
> }
>
>
>
>
>
> The same way like assets, assets works fine, this one no. Anything
> else to check?
>
>
>
> Thanks,
>
>
>
> Jordi
>
>
>
> ------------------------------------------------------------------------
>
> From: HSen_at_vertrax.com <mailto:HSen_at_vertrax.com>
> To: users_at_jersey.dev.java.net <mailto:users_at_jersey.dev.java.net>
> Date: Tue, 22 Sep 2009 10:12:54 -0400
> Subject: RE: [Jersey] 400 Bad Request (bug?)
>
> Can you double check the path?
>
> If ‘/project’ is the root resource then the ‘/vulnerabilities/new’
> is the sub resource, therefore the method (‘post’) will need
> @Path(“{projectId}/vulnerabilities/new”) annotation
>
>
>
> Herak
>
>
>
> *From:* Jordi Domingo [mailto:noseya_at_hotmail.com]
> *Sent:* Tuesday, September 22, 2009 8:57 AM
> *To:* users_at_jersey.dev.java.net <mailto:users_at_jersey.dev.java.net>
> *Subject:* RE: [Jersey] 400 Bad Request (bug?)
>
>
>
> I cant understand why its happening this.. in other places i make
> requests like the one that fails and work fine
>
>
>
> POST /projects/1/assets HTTP/1.1
>
> Host: localhost
>
> User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; es-ES;
> rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
>
> Accept: application/json, text/javascript, */*
>
> Accept-Language: ca,en-us;q=0.7,it;q=0.3
>
> Accept-Encoding: gzip,deflate
>
> Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
>
> Keep-Alive: 300
>
> Proxy-Connection: keep-alive
>
> Content-Type: application/x-www-form-urlencoded; charset=UTF-8
>
> X-Requested-With: XMLHttpRequest
>
> Referer: http://localhost/projects/1/assets/new
>
> Cookie: JSESSIONID=1bb45c8173eba1145cf57e0ed37e
>
> Pragma: no-cache
>
> Cache-Control: no-cache
>
> Content-Length: 31
>
>
>
> environment=&url=&ip=&hostname=
>
>
>
> Response is 200 OK
>
>
>
> My Java method is declared this way (but the request didnt reach
> my code):
>
> @POST
>
> @Produces({"application/json"})
>
> public Response post(@Context UriInfo uriInfo,
> @PathParam("projectId") int projectId, @FormParam("identifier")
> String identifier,
>
>
> @FormParam("usersId") Long usersId, @FormParam("statusId") Integer
> statusId, @FormParam("weaknessesId") Integer weaknessesId,
>
>
> @FormParam("name") String name, @FormParam("description") String
> description, @FormParam("consequences") String consequences,
>
>
> @FormParam("mitigations") String mitigations,
> @FormParam("cvssBase") java.math.BigDecimal cvssBase,
>
>
> @FormParam("cvssTemporal") java.math.BigDecimal cvssTemporal,
> @FormParam("cvssEnvironment") java.math.BigDecimal cvssEnvironment,
>
>
> @FormParam("standardProvidersCodesId") Long
> standardProvidersCodesId, @FormParam("visibility") String visibility,
>
>
> @FormParam("severity") Integer severity, @FormParam("difficulty")
> Integer difficulty, @FormParam("probability") Integer probability,
>
>
> @FormParam("risk") Integer risk) throws SystemException{
>
> ....
>
> }
>
>
>
> Any help is appreciated.
>
>
>
> ------------------------------------------------------------------------
>
> From: noseya_at_hotmail.com <mailto:noseya_at_hotmail.com>
> To: users_at_jersey.dev.java.net <mailto:users_at_jersey.dev.java.net>
> Date: Tue, 22 Sep 2009 13:50:08 +0200
> Subject: [Jersey] 400 Bad Request (bug?)
>
> Hi all :)
>
>
>
> I'm getting this error, and i think that is a bug. This is my request:
>
>
>
> POST /projects/1/vulnerabilities HTTP/1.1
>
> Host: localhost
>
> User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; es-ES;
> rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
>
> Accept: application/json, text/javascript, */*
>
> Accept-Language: ca,en-us;q=0.7,it;q=0.3
>
> Accept-Encoding: gzip,deflate
>
> Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
>
> Keep-Alive: 300
>
> Proxy-Connection: keep-alive
>
> Content-Type: application/x-www-form-urlencoded; charset=UTF-8
>
> X-Requested-With: XMLHttpRequest
>
> Referer: http://localhost/projects/1/vulnerabilities/new
>
> Cookie: JSESSIONID=16f95e59d3b1b0e954310c190c60
>
> Content-Length: 161
>
>
>
> identifier=identifier&usersId=1&statusId=1&weaknessesId=4&name=name&description=description&visibility=I&*standardProvidersCodesId=*&severity=2&difficulty=2&risk=1
>
>
>
> THe response is 400 Bad Request.
>
>
>
> What you see in bold is causing the bad request. Take it out and
> works fine.
>
>
>
> Thanks,
>
>
>
> Jordi
>
>
>
> ------------------------------------------------------------------------
>
> Charlas más divertidas con el nuevo Windows Live Messenger
> <http://download.live.com>
>
>
>
> ------------------------------------------------------------------------
>
> Comparte tus fotos con tus amigos. Más fácil con Windows Live
> <http://download.live.com>
>
>
>
> ------------------------------------------------------------------------
>
> Diferentes formas de estar en contacto con amigos y familiares.
> Descúbrelas. Descúbrelas.
> <http://www.microsoft.com/windows/windowslive/default.aspx>
>
>
>
> ------------------------------------------------------------------------
>
> Nuevo Windows Live, un mundo lleno de posibilidades Descúbrelo.
> <http://www.microsoft.com/windows/windowslive/default.aspx>
>
>
>
> ------------------------------------------------------------------------
>
> Diferentes formas de estar en contacto con amigos y familiares.
> Descúbrelas. Descúbrelas.
> <http://www.microsoft.com/windows/windowslive/default.aspx>
>
>
> ------------------------------------------------------------------------
> Diferentes formas de estar en contacto con amigos y familiares.
> Descúbrelas. Descúbrelas.
> <http://www.microsoft.com/windows/windowslive/default.aspx>
>
>
>
> ------------------------------------------------------------------------
> Nuevo Windows Live, un mundo lleno de posibilidades Descúbrelo.
> <http://www.microsoft.com/windows/windowslive/default.aspx>