24

What is the difference between @FormDataParam and @FormParam?

I was using multiple @FormDataParam in a method but it was throwing media unsupported type error. But when I used @FormParam, I got the values.

So, I need to know what is the difference between the two of them?

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
Partha Sarathi Ghosh
  • 10,936
  • 20
  • 59
  • 84
  • FormDataParam is used in conjunction with multipart/form-data. This is more efficient method to transfer binary data like attachment than using FormParam. Please the the documentation of [FormDataParam](https://jersey.java.net/nonav/apidocs/1.0.3/contribs/jersey-multipart/com/sun/jersey/multipart/FormDataParam.html) – Sangram Jadhav May 31 '16 at 05:46

2 Answers2

33
  • @FormDataParam is supposed to be used with Multipart type data (i.e. multipart/form-data or MediaType.MULTIPART_FORM_DATA), which in its raw form looks something like

      Content-Type: multipart/form-data; boundary=AaB03x
    
      --AaB03x
      Content-Disposition: form-data; name="submit-name"
    
      Larry
      --AaB03x
      Content-Disposition: form-data; name="files"; filename="file1.txt"
      Content-Type: text/plain
    
      ... contents of file1.txt ...
      --AaB03x--
    

    Multipart is mainly used for sending binary data, like non-text files, or sending arbitrary, meta, or related data along with files.

  • @FormParam is for url-encoded request parameters (i.e. application/x-www-form-urlencoded or MediaType.APPLICATION_FORM_URLENCODED), which in raw form looks like

      param1=value1&param2=value2
    

Both of these types are mainly used in client side forms. For example

<form method="POST" action="someUrl">
    <input name="gender" type="text">
    <input name="name" type="text">
</form>

the above would send the request parameters as application/x-www-form-urlencoded. It would get sent in raw form as

gender=male&name=peeskillet

On the server side, we can use a @FormParam for each named parameter in the form

@FormParam("gender") String gender, @FormParam("name") String name

But if we need to send say an image along with the parameters, application/x-form-url-encoded data type is not sufficient, as it only deals with text. So we need to use Multipart

<form method="POST" action="someUrl", enctype="multipart/form-data">
    <input name="gender" type="text">
    <input name="name" type="text">
    <input name="avatar" type="file">
</form>

Here the Multipart type is specified, now the browser will send out the request with something like

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="gender"

Male
--AaB03x
Content-Disposition: form-data; name="name"

Peskillet
--AaB03x
Content-Disposition: form-data; name="avatar"; filename="image.png"
Content-Type: image/png

... binary content of image file ...
--AaB03x--

On the server, similar with the application/x-www-form-urlencoded example above, for each Multipart parameter (or field to be more precise), we can use @FormDataParam to signify each parameter

@FormDataParam("gender") String gender,
@FormDataParam("name") String name,
@FormDataParam("avatar") InputStream avatar

See Also:

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • 1
    Yes, Now its clear. But Only thing I am not able to understand is that. My form was not using `multipart/form-data`. Still I was able to get the string as @FormDataParam when I had only one parameter. But when I changed to two parameter it stooped working. After changing it to @FormParam it is working now. – Partha Sarathi Ghosh May 31 '16 at 06:15
  • 1
    I think in your case, the `@FormDataParam` was completely ignored because the expected media type, is `application/x-www-form-urlencoded`. As for the incoming data, because the `@FormParam` is not used, it just gives you the data as the whole request string. – Paul Samsotha May 31 '16 at 06:21
  • As far as the "not working", its because a method can accept one body parameter, generally this parameter has no annotation, like when getting a JSON POJO. If you try to add one more parameter, Jersey has no idea which one is the body parameter, so it throws an error on startup. If you were to register the `MultiPartFeature` with your application, Jersey would not throw the error, as the feature recognizes the `@FormDataParam` annotations, so it thinks that's what you are expecting. Though I am not sure is the deserialization would succeed. – Paul Samsotha May 31 '16 at 06:24
  • You can see [this kind of related post](http://stackoverflow.com/a/30656345/2587435) – Paul Samsotha May 31 '16 at 06:26
3

From the documentation FormParam:

Binds the value(s) of a form parameter contained within a request entity body to a resource method parameter. Values are URL decoded unless this is disabled using the Encoded annotation. A default value can be specified using the DefaultValue annotation. If the request entity body is absent or is an unsupported media type, the default value is used.

and FormDataParam

Binds the named body part(s) of a "multipart/form-data" request entity body to a resource method parameter.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331