Sometimes, our REST endpoint needs to consume data in the form of application/x-www-form-urlencoded or using multipart/form-data. The source of this data can probably be an HTML form. Now, the first question which should come to our mind is, what is exactly this application/x-www-form-urlencoded or using multipart/form-data and how can we let our spring application consume this. This blog will help you to find answers to these questions.
Let’s start with what is application/x-www-form-urlencoded data and multipart/form-data?
Application/x-www-form-urlencoded data: Represents an URL encoded form. This is the default value if enctype attribute is not set to anything. In the case of x-www-form-urlencoded, the whole form of data is sent as a long query string. The query string contains name-value pairs separated by & character e.g. field1=value1&field2=value2 etc.
It is similar to URL encoding and normal GET request where data is sent on URL, but form data goes inside POST request body and they are encoded like that.
Also, both reserved and non-alphanumeric characters are replaced by ‘%HH’, a percent sign and two hexadecimal digits representing the ASCII code of the character e.g. space is replaced by %20 character in URL.
Multipart/form-data: When you choose HTTP header ContentType=multipart/form-data then data is sent in chunks to a server where the boundary is made by a character which should not appear in the content. This is achieved by using a suitable encoding e.g. choosing a base64 encoding and then making a character outside of the base64 encoding scheme as the boundary. The multipart/form-data is often used while uploading files to the server.
How to handle application/x-www-form-urlencoded or using multipart/form-data in Spring?
The most commonly used HTTP method for form submissions is POST. However, for idempotent form submissions, we can also use the HTTP GET method.
For forms that use the GET method, the entire form data is sent as part of the query string. But, if we’re using the POST method, then its data is sent as part of the body of the HTTP request.
Moreover, in the latter case, we can also specify the encoding of data with the form’s enctype attribute, which can take two values, namely application/x-www-form-urlencoded and multipart/form-data.
Let’s start with defining what type of data our POST endpoint is able to consume application/x-www-form-urlencoded and multipart/form-data in our controller
@PostMapping(path = "/test", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE}, produces = MediaType.APPLICATION_JSON_VALUE)
Adding only the data type of the consumed data won’t help. This would give you status 415 Unsupported Media Type message displaying on your screen if we do not map the incoming data to a proper Object. This can be MultiValueMap or a custom model class that you have made.
Let’s learn how can we map the incoming encoded data to a model class directly which also consists of validations. Assume, we have a Student class.
public class Student { @NotBlank(message = "student name should not be blank") @Size(min = 3, message = "student name length should be greater than 2") private String name; @NotBlank(message = "student city should not be blank") private String city; }
For the above class, we have a POST endpoint defines as follows
@PostMapping(path = "/student", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE}, produces = MediaType.APPLICATION_JSON_VALUE) public Mono<ResponseEntity<Student>> createStudent( @Valid @ModelAttribute Student student)
Now notice, we have used @ModelAttribute above to map the incoming application/x-www-form-urlencoded or multipart/form-data directly to the Student model class. The @ModelAttribute is an annotation that binds a method parameter or method return value to a named model attribute and then exposes it to a web view.
The incoming data in your POST request can now directly be accessed using this student object in your code
Conclusion:
In this blog, we have learned about the encoding of data with the form’s enctype attributes namely application/x-www-form-urlencoded and multipart/form-data and how we can consume and use the same in our spring REST application.
References:
spring-url-encoded-form-data blog