{8.1.0-updated} @FormData

The {@link oaj.http.annotation.FormData @FormData} annotation is used to retrieve request form post entries.

The most typical scenario is to simply use the value field to define form data parameter names:

Example:

@RestMethod(name=POST) public void doPost( @FormData("p1") int p1, @FormData("p2") String p2, @FormData("p3") UUID p3) {...}

This is functionally equivalent to the following code:

@RestMethod(name=POST) public void doPost(RestRequest req) { RequestFormData fd = req.getFormData(); int p1 = fd.get("p1", 0, int.class); String p2 = fd.get("p2", String.class); UUID p3 = fd.get("p3", UUID.class); }

The special name "*" (or blank) can be used to represent all values. When used, the data type must be a Map or bean.

Examples:

// Multiple values passed as a map. @RestMethod(name=POST) public void doPost(@FormData("*") Map<String,Object> map) {...}

// Same, but name "*" is inferred. @RestMethod(name=POST) public void doPost(@FormData Map<String,Object> map) {...}

// Multiple values passed as a bean. @RestMethod(name=POST) public void doPost(@FormData MyBean bean) {...}

The registered {@link oajr.RestContext#REST_partParser REST_partParser} is used to convert strings to POJOs and controls what POJO types are supported. By default, this is the {@link oaj.oapi.OpenApiParser} which supports the standard Swagger-based rules for parsing.

For example, the following shows how a pipe-delimited list of comma-delimited numbers (e.g. "1,2,3|4,5,6|7,8,9") can be converted to a 2-dimensional array of Longs:

@RestMethod(method="POST", path="/testFormData") public void testFormData( @FormData( name="formDataParamName", collectionFormat="pipes", items=@SubItems( collectionFormat="csv", type="integer", format="int64", minimum="0", maximum="100" minLength=1, maxLength=10 ), minLength=1, maxLength=10 ) Long[][] formDataParameter ) {...}

Input will be converted based on the types and formats defined in the schema definition. Input validations such as minLength/maxLength that don't match the input will result in automatic 400 Bad Request responses.

For more information about valid parameter types, see {@doc OpenApiParsers OpenAPI Parsers}

The @FormData annotation is also used for supplying swagger information about the HTTP part. This information is used to populate the auto-generated Swagger documentation and UI.

Examples:

// Normal @FormData( name="name", description="Pet name", required=true, example="Doggie" )

// Free-form // Note the extra field @FormData( name="name", api={ "description: 'Pet name',", "required: true,", "example: 'Doggie'," "x-extra: 'extra field'" } )

{@doc RestSvlVariables} (e.g. "$L{my.localized.variable}") are supported on annotation fields.

Example:

@FormData( description="$L{PetNameDescription}" )

This annotation should not be combined with the {@link oaj.http.annotation.Body @Body} annotation or {@link oajr.RestRequest#getBody()} method for application/x-www-form-urlencoded POST posts, since it will trigger the underlying servlet API to parse the body content as key-value pairs resulting in empty content.
The {@link oaj.http.annotation.Query @Query} annotation can be used to retrieve a URL parameter in the URL string without triggering the servlet to drain the body content.
If using this annotation on a Spring bean, note that you are likely to encounter issues when using on parameterized types such as List<MyBean>. This is due to the fact that Spring uses CGLIB to recompile classes at runtime, and CGLIB was written before generics were introduced into Java and is a virtually-unsupported library. Therefore, parameterized types will often be stripped from class definitions and replaced with unparameterized types (e.g. List). Under these circumstances, you are likely to get ClassCastExceptions when trying to access generalized OMaps as beans. The best solution to this issue is to either specify the parameter as a bean array (e.g. MyBean[]) or declare the method as final so that CGLIB will not try to recompile it.