diff --git a/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java index 98d74f6ba16292852b1a126e2d7ab4c9fa94645a..c2463d5a7cafb8ff43e2f2164a75cffc8a9dda1e 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java @@ -25,6 +25,7 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -148,10 +149,17 @@ public class FormHttpMessageConverter implements HttpMessageConverterBy default this is set to "UTF-8". As of 4.3, it will also be used as - * the default charset for the conversion of text bodies in a multipart request. - * In contrast to this, {@link #setMultipartCharset} only affects the encoding of - * file names in a multipart request according to the encoded-word syntax. + * + *

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) {@link #setMultipartCharset} 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". */ public void setCharset(Charset charset) { if (charset != this.charset) { @@ -177,9 +185,13 @@ public class FormHttpMessageConverter implements HttpMessageConverterIf not set file names will be encoded as US-ASCII. + * + *

As of 5.0 by default part headers, including Content-Disposition (and + * its filename parameter) will be encoded based on the setting of + * {@link #setCharset(Charset)} or {@code UTF-8} by default. + * * @since 4.1.1 * @see Encoded-Word */ @@ -322,7 +334,11 @@ public class FormHttpMessageConverter implements HttpMessageConverter parts, HttpOutputMessage outputMessage) throws IOException { final byte[] boundary = generateMultipartBoundary(); - Map parameters = Collections.singletonMap("boundary", new String(boundary, "US-ASCII")); + Map parameters = new HashMap<>(2); + parameters.put("boundary", new String(boundary, "US-ASCII")); + if (!isFilenameCharsetSet()) { + parameters.put("charset", this.charset.name()); + } MediaType contentType = new MediaType(MediaType.MULTIPART_FORM_DATA, parameters); HttpHeaders headers = outputMessage.getHeaders(); @@ -344,6 +360,15 @@ public class FormHttpMessageConverter implements HttpMessageConverter parts, byte[] boundary) throws IOException { for (Map.Entry> entry : parts.entrySet()) { String name = entry.getKey(); @@ -365,7 +390,8 @@ public class FormHttpMessageConverter implements HttpMessageConverter messageConverter : this.partConverters) { if (messageConverter.canWrite(partType, partContentType)) { - HttpOutputMessage multipartMessage = new MultipartHttpOutputMessage(os); + Charset charset = isFilenameCharsetSet() ? StandardCharsets.US_ASCII : this.charset; + HttpOutputMessage multipartMessage = new MultipartHttpOutputMessage(os, charset); multipartMessage.getHeaders().setContentDispositionFormData(name, getFilename(partBody)); if (!partHeaders.isEmpty()) { multipartMessage.getHeaders().putAll(partHeaders); @@ -378,7 +404,6 @@ public class FormHttpMessageConverter implements HttpMessageConverterThis implementation delegates to @@ -451,12 +476,15 @@ public class FormHttpMessageConverter implements HttpMessageConverter> entry : this.headers.entrySet()) { - byte[] headerName = getAsciiBytes(entry.getKey()); + byte[] headerName = getBytes(entry.getKey()); for (String headerValueString : entry.getValue()) { - byte[] headerValue = getAsciiBytes(headerValueString); + byte[] headerValue = getBytes(headerValueString); this.outputStream.write(headerName); this.outputStream.write(':'); this.outputStream.write(' '); @@ -488,8 +516,8 @@ public class FormHttpMessageConverter implements HttpMessageConverter