类 FormHttpMessageConverter

java.lang.Object
cn.taketoday.http.converter.FormHttpMessageConverter
所有已实现的接口:
HttpMessageConverter<cn.taketoday.util.MultiValueMap<String,?>>
直接已知子类:
AllEncompassingFormHttpMessageConverter

public class FormHttpMessageConverter extends Object implements HttpMessageConverter<cn.taketoday.util.MultiValueMap<String,?>>
Implementation of 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. 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<cn.taketoday.http.converter.HttpMessageConverter<?>>) or augmented via addPartConverter(cn.taketoday.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 DefaultMultiValueMap<>();
 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

 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 DefaultMultiValueMap<>();
 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 DefaultMultiValueMap<>();
 parts.add("field 1", "value 1");
 parts.add("file", new ClassPathResource("myFile.jpg"));

 HttpHeaders requestHeaders = HttpHeaders.create();
 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 DefaultMultiValueMap<>();
 parts.add("field 1", "value 1");
 parts.add("file", new ClassPathResource("myFile.jpg"));

 HttpHeaders requestHeaders = HttpHeaders.create();
 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.

从以下版本开始:
4.0
作者:
Arjen Poutsma, Rossen Stoyanchev, Juergen Hoeller, Sam Brannen
另请参阅:
  • 字段详细资料

    • DEFAULT_CHARSET

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

      private static final MediaType DEFAULT_FORM_DATA_MEDIA_TYPE
    • supportedMediaTypes

      private List<MediaType> supportedMediaTypes
    • partConverters

      private List<HttpMessageConverter<?>> partConverters
    • charset

      private Charset charset
    • multipartCharset

      @Nullable private Charset multipartCharset
  • 构造器详细资料

    • FormHttpMessageConverter

      public FormHttpMessageConverter()
  • 方法详细资料

    • setSupportedMediaTypes

      public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes)
      Set the list of MediaType objects supported by this converter.
      另请参阅:
    • 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.

      参数:
      supportedMediaTypes - a var-args list of MediaType objects to add
      另请参阅:
    • 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.
      指定者:
      getSupportedMediaTypes 在接口中 HttpMessageConverter<cn.taketoday.util.MultiValueMap<String,?>>
      返回:
      the list of supported media types
      另请参阅:
    • 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.
    • 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.

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

      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".

    • applyDefaultCharset

      private void applyDefaultCharset()
      Apply the configured charset as a default to registered part converters.
    • 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 javax.mail.

      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.

      另请参阅:
    • canRead

      public boolean canRead(Class<?> clazz, @Nullable MediaType mediaType)
      从接口复制的说明: HttpMessageConverter
      Indicates whether the given class can be read by this converter.
      指定者:
      canRead 在接口中 HttpMessageConverter<cn.taketoday.util.MultiValueMap<String,?>>
      参数:
      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.
      返回:
      true if readable; false otherwise
    • canWrite

      public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType)
      从接口复制的说明: HttpMessageConverter
      Indicates whether the given class can be written by this converter.
      指定者:
      canWrite 在接口中 HttpMessageConverter<cn.taketoday.util.MultiValueMap<String,?>>
      参数:
      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.
      返回:
      true if writable; false otherwise
    • read

      public cn.taketoday.util.MultiValueMap<String,String> read(@Nullable Class<? extends cn.taketoday.util.MultiValueMap<String,?>> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException
      从接口复制的说明: HttpMessageConverter
      Read an object of the given type from the given input message, and returns it.
      指定者:
      read 在接口中 HttpMessageConverter<cn.taketoday.util.MultiValueMap<String,?>>
      参数:
      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
      返回:
      the converted object
      抛出:
      IOException - in case of I/O errors
      HttpMessageNotReadableException - in case of conversion errors
    • write

      public void write(cn.taketoday.util.MultiValueMap<String,?> map, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException
      从接口复制的说明: HttpMessageConverter
      Write an given object to the given output message.
      指定者:
      write 在接口中 HttpMessageConverter<cn.taketoday.util.MultiValueMap<String,?>>
      参数:
      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
      抛出:
      IOException - in case of I/O errors
      HttpMessageNotWritableException - in case of conversion errors
    • isMultipart

      private boolean isMultipart(cn.taketoday.util.MultiValueMap<String,?> map, @Nullable MediaType contentType)
    • writeForm

      private void writeForm(cn.taketoday.util.MultiValueMap<String,Object> formData, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException
      抛出:
      IOException
    • getFormContentType

      protected MediaType getFormContentType(@Nullable MediaType contentType)
      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. If contentType is null, application/x-www-form-urlencoded; charset=UTF-8 is returned.

      Subclasses can override this method to change this behavior.

      参数:
      contentType - the preferred content type (can be null)
      返回:
      the content type to be used
    • serializeForm

      protected String serializeForm(cn.taketoday.util.MultiValueMap<String,Object> formData, Charset charset)
    • writeMultipart

      private void writeMultipart(cn.taketoday.util.MultiValueMap<String,Object> parts, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException
      抛出:
      IOException
    • isFilenameCharsetSet

      private boolean isFilenameCharsetSet()
      When setMultipartCharset(Charset) is configured (i.e. RFC 2047, encoded-word syntax) we need to use ASCII for part headers, or otherwise we encode directly using the configured setCharset(Charset).
    • writeParts

      private void writeParts(OutputStream os, cn.taketoday.util.MultiValueMap<String,Object> parts, byte[] boundary) throws IOException
      抛出:
      IOException
    • writePart

      private void writePart(String name, HttpEntity<?> partEntity, OutputStream os) throws IOException
      抛出:
      IOException
    • 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.
      参数:
      part - the part to return an HttpEntity for
      返回:
      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.getName() if the part is a Resource, and null in other cases. Can be overridden in subclasses.

      参数:
      part - the part to determine the file name for
      返回:
      the filename, or null if not known
    • writeBoundary

      private void writeBoundary(OutputStream os, byte[] boundary) throws IOException
      抛出:
      IOException
    • writeEnd

      private static void writeEnd(OutputStream os, byte[] boundary) throws IOException
      抛出:
      IOException
    • writeNewLine

      private static void writeNewLine(OutputStream os) throws IOException
      抛出:
      IOException