Class FormHttpMessageConverter
- All Implemented Interfaces:
HttpMessageConverter<MultiValueMap<String,
?>>
- Direct Known Subclasses:
AllEncompassingFormHttpMessageConverter
HttpMessageConverter
to read and write 'normal' HTML
forms and also to write (but not read) multipart data (e.g. 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. As of Spring Framework 5.2 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.
RestTemplate restTemplate = new RestTemplate(); // 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 restTemplate.postForLocation("https://example.com/myForm", form);
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")); restTemplate.postForLocation("https://example.com/myFileUpload", parts);
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")); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(MediaType.MULTIPART_MIXED); restTemplate.postForLocation("https://example.com/myFileUpload", new HttpEntity<>(parts, requestHeaders));
The following snippet shows how to do a file upload using the
"multipart/related"
content type.
MediaType multipartRelated = new MediaType("multipart", "related"); restTemplate.getMessageConverters().stream() .filter(FormHttpMessageConverter.class::isInstance) .map(FormHttpMessageConverter.class::cast) .findFirst() .orElseThrow(() -> new IllegalStateException("Failed to find FormHttpMessageConverter")) .addSupportedMediaTypes(multipartRelated); MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>(); parts.add("field 1", "value 1"); parts.add("file", new ClassPathResource("myFile.jpg")); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(multipartRelated); restTemplate.postForLocation("https://example.com/myFileUpload", new HttpEntity<>(parts, requestHeaders));
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:
-
Field Summary
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
addPartConverter
(HttpMessageConverter<?> partConverter) Add a message body converter.void
addSupportedMediaTypes
(MediaType... supportedMediaTypes) AddMediaType
objects to be supported by this converter.boolean
Indicates whether the given class can be read by this converter.boolean
Indicates whether the given class can be written by this converter.protected byte[]
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, given the preferred content type.protected HttpEntity<?>
getHttpEntity
(Object part) Return anHttpEntity
for the given part Object.Return the configured converters for MIME parts.Return the list of media types supported by this converter.read
(Class<? extends MultiValueMap<String, ?>> clazz, HttpInputMessage inputMessage) Read an object of the given type from the given input message, and returns it.protected String
serializeForm
(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 responseContent-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 ofMediaType
objects supported by this converter.void
write
(MultiValueMap<String, ?> map, MediaType contentType, HttpOutputMessage outputMessage) Write an 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
The default charset used by the converter.
-
-
Constructor Details
-
FormHttpMessageConverter
public FormHttpMessageConverter()
-
-
Method Details
-
setSupportedMediaTypes
Set the list ofMediaType
objects supported by this converter. -
addSupportedMediaTypes
AddMediaType
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 ofMediaType
objects to add- Since:
- 5.2
- See Also:
-
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 viacanWrite(clazz, null
. The list may also exclude MIME types supported only for a specific class. Alternatively, useHttpMessageConverter.getSupportedMediaTypes(Class)
for a more precise list.- Specified by:
getSupportedMediaTypes
in interfaceHttpMessageConverter<MultiValueMap<String,
?>> - Returns:
- the list of supported media types
- See Also:
-
setPartConverters
Set the message body converters to use. These converters are used to convert objects to MIME parts. -
getPartConverters
Return the configured converters for MIME parts.- Since:
- 5.3
-
addPartConverter
Add a message body converter. Such a converter is used to convert objects to MIME parts. -
setCharset
Set the default character set to use for reading and writing form data when the request or responseContent-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 theencoded-word
syntax from RFC 2047.By default this is set to "UTF-8".
-
setMultipartCharset
Set the character set to use when writing multipart data to encode file names. Encoding is based on theencoded-word
syntax defined in RFC 2047 and relies onMimeUtility
fromjakarta.mail
.As of 5.0 by default part headers, including
Content-Disposition
(and its filename parameter) will be encoded based on the setting ofsetCharset(Charset)
orUTF-8
by default.- Since:
- 4.1.1
- See Also:
-
canRead
Description copied from interface:HttpMessageConverter
Indicates whether the given class can be read by this converter.- Specified by:
canRead
in interfaceHttpMessageConverter<MultiValueMap<String,
?>> - Parameters:
clazz
- the class to test for readabilitymediaType
- the media type to read (can benull
if not specified); typically the value of aContent-Type
header.- Returns:
true
if readable;false
otherwise
-
canWrite
Description copied from interface:HttpMessageConverter
Indicates whether the given class can be written by this converter.- Specified by:
canWrite
in interfaceHttpMessageConverter<MultiValueMap<String,
?>> - Parameters:
clazz
- the class to test for writabilitymediaType
- the media type to write (can benull
if not specified); typically the value of anAccept
header.- Returns:
true
if writable;false
otherwise
-
read
public MultiValueMap<String,String> read(@Nullable Class<? extends MultiValueMap<String, ?>> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableExceptionDescription copied from interface:HttpMessageConverter
Read an object of the given type from the given input message, and returns it.- Specified by:
read
in interfaceHttpMessageConverter<MultiValueMap<String,
?>> - Parameters:
clazz
- the type of object to return. This type must have previously been passed to thecanRead
method of this interface, which must have returnedtrue
.inputMessage
- the HTTP input message to read from- Returns:
- the converted object
- Throws:
IOException
- in case of I/O errorsHttpMessageNotReadableException
- in case of conversion errors
-
write
public void write(MultiValueMap<String, ?> map, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableExceptionDescription copied from interface:HttpMessageConverter
Write an given object to the given output message.- Specified by:
write
in interfaceHttpMessageConverter<MultiValueMap<String,
?>> - Parameters:
map
- the object to write to the output message. The type of this object must have previously been passed to thecanWrite
method of this interface, which must have returnedtrue
.contentType
- the content type to use when writing. May benull
to indicate that the default content type of the converter must be used. If notnull
, this media type must have previously been passed to thecanWrite
method of this interface, which must have returnedtrue
.outputMessage
- the message to write to- Throws:
IOException
- in case of I/O errorsHttpMessageNotWritableException
- in case of conversion errors
-
getFormContentType
Return the content type used to write forms, given the preferred content type. By default, this method returns the given content type, but adds the charset if it does not have one. IfcontentType
isnull
,application/x-www-form-urlencoded; charset=UTF-8
is returned.Subclasses can override this method to change this behavior.
- Parameters:
contentType
- the preferred content type (can benull
)- Returns:
- the content type to be used
- Since:
- 5.2.2
-
serializeForm
-
generateMultipartBoundary
protected byte[] generateMultipartBoundary()Generate a multipart boundary.This implementation delegates to
MimeTypeUtils.generateMultipartBoundary()
. -
getHttpEntity
Return anHttpEntity
for the given part Object.- Parameters:
part
- the part to return anHttpEntity
for- Returns:
- the part Object itself it is an
HttpEntity
, or a newly builtHttpEntity
wrapper for that part
-
getFilename
Return the filename of the given multipart part. This value will be used for theContent-Disposition
header.The default implementation returns
Resource.getFilename()
if the part is aResource
, andnull
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
-