Package org.springframework.http.converter

# Class FormHttpMessageConverter

java.lang.Object
org.springframework.http.converter.FormHttpMessageConverter

All Implemented Interfaces:
  `HttpMessageConverter<org.springframework.util.MultiValueMap<String,?>>`

Direct Known Subclasses:
  `AllEncompassingFormHttpMessageConverter`

public class FormHttpMessageConverter extends Object implements HttpMessageConverter<org.springframework.util.MultiValueMap<String,?>>
Implementation of `HttpMessageConverter` to read and write 'normal' HTML forms and also to write (but not read) multipart data (for example, file uploads).

In other words, this converter can read and write the `"application/x-www-form-urlencoded"` media type as `MultiValueMap<String, String>`, and it can also write (but not read) the `"multipart/form-data"` and `"multipart/mixed"` media types as `MultiValueMap<String, Object>`.

### Multipart Data

By default, `"multipart/form-data"` is used as the content type when writing multipart data. It is also possible to write multipart data using other multipart subtypes such as `"multipart/mixed"` and `"multipart/related"`, as long as the multipart subtype is registered as a supported media type and the desired multipart subtype is specified as the content type when writing the multipart data. Note that `"multipart/mixed"` is registered as a supported media type by default.

When writing multipart data, this converter uses other `HttpMessageConverters` to write the respective MIME parts. By default, basic converters are registered for byte array, `String`, and `Resource`. These can be overridden via `setPartConverters(java.util.List<org.springframework.http.converter.HttpMessageConverter<?>>)` or augmented via `addPartConverter(org.springframework.http.converter.HttpMessageConverter<?>)`.

### Examples

The following snippet shows how to submit an HTML form using the `"multipart/form-data"` content type.

     RestClient restClient = RestClient.create();
     // AllEncompassingFormHttpMessageConverter is configured by default

     MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
     form.add("field 1", "value 1");
     form.add("field 2", "value 2");
     form.add("field 2", "value 3");
     form.add("field 3", 4);  // non-String form values supported as of 5.1.4

     ResponseEntity<Void> response = restClient.post()
       .uri("https://example.com/myForm")
       .contentType(MULTIPART_FORM_DATA)
       .body(form)
       .retrieve()
       .toBodilessEntity();

The following snippet shows how to do a file upload using the `"multipart/form-data"` content type.

     MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
     parts.add("field 1", "value 1");
     parts.add("file", new ClassPathResource("myFile.jpg"));

     ResponseEntity<Void> response = restClient.post()
       .uri("https://example.com/myForm")
       .contentType(MULTIPART_FORM_DATA)
       .body(parts)
       .retrieve()
       .toBodilessEntity();

The following snippet shows how to do a file upload using the `"multipart/mixed"` content type.

     MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
     parts.add("field 1", "value 1");
     parts.add("file", new ClassPathResource("myFile.jpg"));

     ResponseEntity<Void> response = restClient.post()
       .uri("https://example.com/myForm")
       .contentType(MULTIPART_MIXED)
       .body(form)
       .retrieve()
       .toBodilessEntity();

The following snippet shows how to do a file upload using the `"multipart/related"` content type.

     restClient = restClient.mutate()
       .messageConverters(l -> l.stream()
        .filter(FormHttpMessageConverter.class::isInstance)
         .map(FormHttpMessageConverter.class::cast)
         .findFirst()
         .orElseThrow(() -> new IllegalStateException("Failed to find FormHttpMessageConverter"))
         .addSupportedMediaTypes(MULTIPART_RELATED);

     MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
     parts.add("field 1", "value 1");
     parts.add("file", new ClassPathResource("myFile.jpg"));

     ResponseEntity<Void> response = restClient.post()
       .uri("https://example.com/myForm")
       .contentType(MULTIPART_RELATED)
       .body(form)
       .retrieve()
       .toBodilessEntity();

### Miscellaneous

Some methods in this class were inspired by `org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity`.

Since:
  3.0
Author:
  Arjen Poutsma, Rossen Stoyanchev, Juergen Hoeller, Sam Brannen
See Also:
  - `AllEncompassingFormHttpMessageConverter`
  - `MultiValueMap`

## Field Summary

Fields
Modifier and Type
Field
Description
`static final Charset`
`DEFAULT_CHARSET`
The default charset used by the converter.

## Constructor Summary

Constructors
Constructor
Description
`FormHttpMessageConverter()`

## Method Summary

Modifier and Type
Method
Description
`void`
`addPartConverter(HttpMessageConverter<?> partConverter)`
Add a message body converter.
`void`
`addSupportedMediaTypes(MediaType... supportedMediaTypes)`
Add `MediaType` objects to be supported by this converter.
`boolean`
`canRead(Class<?> clazz, MediaType mediaType)`
Indicates whether the given class can be read by this converter.
`boolean`
`canWrite(Class<?> clazz, MediaType mediaType)`
Indicates whether the given class can be written by this converter.
`protected byte[]`
`generateMultipartBoundary()`
Generate a multipart boundary.
`protected String`
`getFilename(Object part)`
Return the filename of the given multipart part.
`protected MediaType`
`getFormContentType(MediaType contentType)`
Return the content type used to write forms, either the given content type or otherwise `application/x-www-form-urlencoded`.
`protected HttpEntity<?>`
`getHttpEntity(Object part)`
Return an `HttpEntity` for the given part Object.
`List<HttpMessageConverter<?>>`
`getPartConverters()`
Return the configured converters for MIME parts.
`List<MediaType>`
`getSupportedMediaTypes()`
Return the list of media types supported by this converter.
`org.springframework.util.MultiValueMap<String,String>`
`read(Class<? extends org.springframework.util.MultiValueMap<String,?>> clazz, HttpInputMessage inputMessage)`
Read an object of the given type from the given input message, and returns it.
`protected String`
`serializeForm(org.springframework.util.MultiValueMap<String,Object> formData, Charset charset)`
`void`
`setCharset(Charset charset)`
Set the default character set to use for reading and writing form data when the request or response `Content-Type` header does not explicitly specify it.
`void`
`setMultipartCharset(Charset charset)`
Set the character set to use when writing multipart data to encode file names.
`void`
`setPartConverters(List<HttpMessageConverter<?>> partConverters)`
Set the message body converters to use.
`void`
`setSupportedMediaTypes(List<MediaType> supportedMediaTypes)`
Set the list of `MediaType` objects supported by this converter.
`void`
`write(org.springframework.util.MultiValueMap<String,?> map, MediaType contentType, HttpOutputMessage outputMessage)`
Write a given object to the given output message.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface org.springframework.http.converter.HttpMessageConverter

`getSupportedMediaTypes`

## Field Details

### DEFAULT_CHARSET

public static final Charset DEFAULT_CHARSET
The default charset used by the converter.

## Constructor Details

### FormHttpMessageConverter

public FormHttpMessageConverter()

## Method Details

### setSupportedMediaTypes

public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes)
Set the list of `MediaType` objects supported by this converter.

See Also:
  - `addSupportedMediaTypes(MediaType...)`
  - `getSupportedMediaTypes()`

### addSupportedMediaTypes

public void addSupportedMediaTypes(MediaType... supportedMediaTypes)
Add `MediaType` objects to be supported by this converter.

The supplied `MediaType` objects will be appended to the list of supported MediaType objects.

Parameters:
  `supportedMediaTypes` - a var-args list of `MediaType` objects to add
Since:
  5.2
See Also:
  - `setSupportedMediaTypes(List)`

### getSupportedMediaTypes

public List<MediaType> getSupportedMediaTypes()
Return the list of media types supported by this converter. The list may not apply to every possible target element type and calls to this method should typically be guarded via `canWrite(clazz, null`. The list may also exclude MIME types supported only for a specific class. Alternatively, use `HttpMessageConverter.getSupportedMediaTypes(Class)` for a more precise list.

Specified by:
  `getSupportedMediaTypes` in interface `HttpMessageConverter<org.springframework.util.MultiValueMap<String,?>>`
Returns:
  the list of supported media types
See Also:
  - `setSupportedMediaTypes(List)`
  - `addSupportedMediaTypes(MediaType...)`

### setPartConverters

public void setPartConverters(List<HttpMessageConverter<?>> partConverters)
Set the message body converters to use. These converters are used to convert objects to MIME parts.

### getPartConverters

public List<HttpMessageConverter<?>> getPartConverters()
Return the configured converters for MIME parts.

Since:
  5.3

### addPartConverter

public void addPartConverter(HttpMessageConverter<?> partConverter)
Add a message body converter. Such a converter is used to convert objects to MIME parts.

### setCharset

public void setCharset(@Nullable Charset charset)
Set the default character set to use for reading and writing form data when the request or response `Content-Type` header does not explicitly specify it.

As of 4.3, this is also used as the default charset for the conversion of text bodies in a multipart request.

As of 5.0, this is also used for part headers including `Content-Disposition` (and its filename parameter) unless (the mutually exclusive) `multipartCharset` is also set, in which case part headers are encoded as ASCII and filename is encoded with the `encoded-word` syntax from RFC 2047.

By default this is set to "UTF-8".

### setMultipartCharset

public void setMultipartCharset(Charset charset)
Set the character set to use when writing multipart data to encode file names. Encoding is based on the `encoded-word` syntax defined in RFC 2047 and relies on `MimeUtility` from `jakarta.mail`.

As of 5.0 by default part headers, including `Content-Disposition` (and its filename parameter) will be encoded based on the setting of `setCharset(Charset)` or `UTF-8` by default.

Since:
  4.1.1
See Also:
  - Encoded-Word

### canRead

public boolean canRead(Class<?> clazz, @Nullable MediaType mediaType)
Description copied from interface: `HttpMessageConverter`
Indicates whether the given class can be read by this converter.

Specified by:
  `canRead` in interface `HttpMessageConverter<org.springframework.util.MultiValueMap<String,?>>`
Parameters:
  `clazz` - the class to test for readability
  `mediaType` - the media type to read (can be `null` if not specified); typically the value of a `Content-Type` header.
Returns:
  `true` if readable; `false` otherwise

### canWrite

public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType)
Description copied from interface: `HttpMessageConverter`
Indicates whether the given class can be written by this converter.

Specified by:
  `canWrite` in interface `HttpMessageConverter<org.springframework.util.MultiValueMap<String,?>>`
Parameters:
  `clazz` - the class to test for writability
  `mediaType` - the media type to write (can be `null` if not specified); typically the value of an `Accept` header.
Returns:
  `true` if writable; `false` otherwise

### read

public org.springframework.util.MultiValueMap<String,String> read(@Nullable Class<? extends org.springframework.util.MultiValueMap<String,?>> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException
Description copied from interface: `HttpMessageConverter`
Read an object of the given type from the given input message, and returns it.

Specified by:
  `read` in interface `HttpMessageConverter<org.springframework.util.MultiValueMap<String,?>>`
Parameters:
  `clazz` - the type of object to return. This type must have previously been passed to the `canRead` method of this interface, which must have returned `true`.
  `inputMessage` - the HTTP input message to read from
Returns:
  the converted object
Throws:
  `IOException` - in case of I/O errors
  `HttpMessageNotReadableException` - in case of conversion errors

### write

public void write(org.springframework.util.MultiValueMap<String,?> map, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException
Description copied from interface: `HttpMessageConverter`
Write a given object to the given output message.

Specified by:
  `write` in interface `HttpMessageConverter<org.springframework.util.MultiValueMap<String,?>>`
Parameters:
  `map` - the object to write to the output message. The type of this object must have previously been passed to the `canWrite` method of this interface, which must have returned `true`.
  `contentType` - the content type to use when writing. May be `null` to indicate that the default content type of the converter must be used. If not `null`, this media type must have previously been passed to the `canWrite` method of this interface, which must have returned `true`.
  `outputMessage` - the message to write to
Throws:
  `IOException` - in case of I/O errors
  `HttpMessageNotWritableException` - in case of conversion errors

### getFormContentType

protected MediaType getFormContentType(@Nullable MediaType contentType)
Return the content type used to write forms, either the given content type or otherwise `application/x-www-form-urlencoded`.

Parameters:
  `contentType` - the content type passed to `write(org.springframework.util.MultiValueMap<java.lang.String, ?>, org.springframework.http.MediaType, org.springframework.http.HttpOutputMessage)`, or `null`
Returns:
  the content type to use
Since:
  5.2.2

### serializeForm

protected String serializeForm(org.springframework.util.MultiValueMap<String,Object> formData, Charset charset)

### generateMultipartBoundary

protected byte[] generateMultipartBoundary()
Generate a multipart boundary.

This implementation delegates to `MimeTypeUtils.generateMultipartBoundary()`.

### getHttpEntity

protected HttpEntity<?> getHttpEntity(Object part)
Return an `HttpEntity` for the given part Object.

Parameters:
  `part` - the part to return an `HttpEntity` for
Returns:
  the part Object itself it is an `HttpEntity`, or a newly built `HttpEntity` wrapper for that part

### getFilename

@Nullable protected String getFilename(Object part)
Return the filename of the given multipart part. This value will be used for the `Content-Disposition` header.

The default implementation returns `Resource.getFilename()` if the part is a `Resource`, and `null` in other cases. Can be overridden in subclasses.

Parameters:
  `part` - the part to determine the file name for
Returns:
  the filename, or `null` if not known