diff --git a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java index 2e8a676593c..a34a0398944 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageWriter.java @@ -120,17 +120,12 @@ public class FormHttpMessageWriter implements HttpMessageWriter hints) { - mediaType = (mediaType != null ? mediaType : DEFAULT_FORM_DATA_MEDIA_TYPE); - Charset charset; - if (mediaType.getCharset() == null) { - charset = getDefaultCharset(); - mediaType = new MediaType(mediaType, charset); - } - else { - charset = mediaType.getCharset(); - } + mediaType = getMediaType(mediaType); message.getHeaders().setContentType(mediaType); + Charset charset = mediaType.getCharset(); + Assert.notNull(charset, "No charset"); // should never occur + return Mono.from(inputStream).flatMap(form -> { String value = serializeForm(form, charset); ByteBuffer byteBuffer = charset.encode(value); @@ -138,45 +133,38 @@ public class FormHttpMessageWriter implements HttpMessageWriter form, Charset charset) { + private String serializeForm(MultiValueMap formData, Charset charset) { StringBuilder builder = new StringBuilder(); - try { - for (Iterator names = form.keySet().iterator(); names.hasNext();) { - String name = names.next(); - for (Iterator values = form.get(name).iterator(); values.hasNext();) { - Object rawValue = values.next(); - builder.append(URLEncoder.encode(name, charset.name())); - if (rawValue != null) { - builder.append('='); - Assert.isInstanceOf(String.class, rawValue, - "FormHttpMessageWriter supports String values only. " + - "Use MultipartHttpMessageWriter for multipart requests."); - builder.append(URLEncoder.encode((String) rawValue, charset.name())); - if (values.hasNext()) { + formData.forEach((name, values) -> + values.forEach(value -> { + try { + if (builder.length() != 0) { builder.append('&'); } + builder.append(URLEncoder.encode(name, charset.name())); + if (value != null) { + builder.append('='); + builder.append(URLEncoder.encode(value, charset.name())); + } } - } - if (names.hasNext()) { - builder.append('&'); - } - } - } - catch (UnsupportedEncodingException ex) { - throw new IllegalStateException(ex); - } + catch (UnsupportedEncodingException ex) { + throw new IllegalStateException(ex); + } + })); return builder.toString(); } 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 70d5e4c498e..d2b45736e51 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 @@ -26,7 +26,6 @@ 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; import javax.mail.internet.MimeUtility; @@ -290,35 +289,33 @@ public class FormHttpMessageConverter implements HttpMessageConverter form, @Nullable MediaType contentType, + private void writeForm(MultiValueMap formData, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException { - contentType = (contentType != null ? contentType : DEFAULT_FORM_DATA_MEDIA_TYPE); - Charset charset = contentType.getCharset(); - if (charset == null) { - charset = this.charset; - contentType = new MediaType(contentType, charset); - } + contentType = getMediaType(contentType); outputMessage.getHeaders().setContentType(contentType); + Charset charset = contentType.getCharset(); + Assert.notNull(charset, "No charset"); // should never occur + StringBuilder builder = new StringBuilder(); - for (Iterator nameIterator = form.keySet().iterator(); nameIterator.hasNext();) { - String name = nameIterator.next(); - for (Iterator valueIterator = form.get(name).iterator(); valueIterator.hasNext();) { - String value = valueIterator.next(); - builder.append(URLEncoder.encode(name, charset.name())); - if (value != null) { - builder.append('='); - builder.append(URLEncoder.encode(value, charset.name())); - if (valueIterator.hasNext()) { - builder.append('&'); + formData.forEach((name, values) -> + values.forEach(value -> { + try { + if (builder.length() != 0) { + builder.append('&'); + } + builder.append(URLEncoder.encode(name, charset.name())); + if (value != null) { + builder.append('='); + builder.append(URLEncoder.encode(value, charset.name())); + } } - } - } - if (nameIterator.hasNext()) { - builder.append('&'); - } - } + catch (UnsupportedEncodingException ex) { + throw new IllegalStateException(ex); + } + })); + final byte[] bytes = builder.toString().getBytes(charset); outputMessage.getHeaders().setContentLength(bytes.length); @@ -331,6 +328,18 @@ public class FormHttpMessageConverter implements HttpMessageConverter parts, HttpOutputMessage outputMessage) throws IOException {