Polish form writer and converter

This commit is contained in:
Rossen Stoyanchev 2018-06-13 16:00:09 -04:00
parent 0058a1f52d
commit 278881b8df
2 changed files with 58 additions and 61 deletions

View File

@ -120,17 +120,12 @@ public class FormHttpMessageWriter implements HttpMessageWriter<MultiValueMap<St
ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message, ResolvableType elementType, @Nullable MediaType mediaType, ReactiveHttpOutputMessage message,
Map<String, Object> hints) { Map<String, Object> hints) {
mediaType = (mediaType != null ? mediaType : DEFAULT_FORM_DATA_MEDIA_TYPE); mediaType = getMediaType(mediaType);
Charset charset;
if (mediaType.getCharset() == null) {
charset = getDefaultCharset();
mediaType = new MediaType(mediaType, charset);
}
else {
charset = mediaType.getCharset();
}
message.getHeaders().setContentType(mediaType); message.getHeaders().setContentType(mediaType);
Charset charset = mediaType.getCharset();
Assert.notNull(charset, "No charset"); // should never occur
return Mono.from(inputStream).flatMap(form -> { return Mono.from(inputStream).flatMap(form -> {
String value = serializeForm(form, charset); String value = serializeForm(form, charset);
ByteBuffer byteBuffer = charset.encode(value); ByteBuffer byteBuffer = charset.encode(value);
@ -138,45 +133,38 @@ public class FormHttpMessageWriter implements HttpMessageWriter<MultiValueMap<St
message.getHeaders().setContentLength(byteBuffer.remaining()); message.getHeaders().setContentLength(byteBuffer.remaining());
return message.writeWith(Mono.just(buffer)); return message.writeWith(Mono.just(buffer));
}); });
} }
private Charset getMediaTypeCharset(@Nullable MediaType mediaType) { private MediaType getMediaType(@Nullable MediaType mediaType) {
if (mediaType != null && mediaType.getCharset() != null) { if (mediaType == null) {
return mediaType.getCharset(); return DEFAULT_FORM_DATA_MEDIA_TYPE;
}
else if (mediaType.getCharset() == null) {
return new MediaType(mediaType, getDefaultCharset());
} }
else { else {
return getDefaultCharset(); return mediaType;
} }
} }
private String serializeForm(MultiValueMap<String, String> form, Charset charset) { private String serializeForm(MultiValueMap<String, String> formData, Charset charset) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
try { formData.forEach((name, values) ->
for (Iterator<String> names = form.keySet().iterator(); names.hasNext();) { values.forEach(value -> {
String name = names.next(); try {
for (Iterator<?> values = form.get(name).iterator(); values.hasNext();) { if (builder.length() != 0) {
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()) {
builder.append('&'); builder.append('&');
} }
builder.append(URLEncoder.encode(name, charset.name()));
if (value != null) {
builder.append('=');
builder.append(URLEncoder.encode(value, charset.name()));
}
} }
} catch (UnsupportedEncodingException ex) {
if (names.hasNext()) { throw new IllegalStateException(ex);
builder.append('&'); }
} }));
}
}
catch (UnsupportedEncodingException ex) {
throw new IllegalStateException(ex);
}
return builder.toString(); return builder.toString();
} }

View File

@ -26,7 +26,6 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.mail.internet.MimeUtility; import javax.mail.internet.MimeUtility;
@ -290,35 +289,33 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
return false; return false;
} }
private void writeForm(MultiValueMap<String, String> form, @Nullable MediaType contentType, private void writeForm(MultiValueMap<String, String> formData, @Nullable MediaType contentType,
HttpOutputMessage outputMessage) throws IOException { HttpOutputMessage outputMessage) throws IOException {
contentType = (contentType != null ? contentType : DEFAULT_FORM_DATA_MEDIA_TYPE); contentType = getMediaType(contentType);
Charset charset = contentType.getCharset();
if (charset == null) {
charset = this.charset;
contentType = new MediaType(contentType, charset);
}
outputMessage.getHeaders().setContentType(contentType); outputMessage.getHeaders().setContentType(contentType);
Charset charset = contentType.getCharset();
Assert.notNull(charset, "No charset"); // should never occur
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (Iterator<String> nameIterator = form.keySet().iterator(); nameIterator.hasNext();) { formData.forEach((name, values) ->
String name = nameIterator.next(); values.forEach(value -> {
for (Iterator<String> valueIterator = form.get(name).iterator(); valueIterator.hasNext();) { try {
String value = valueIterator.next(); if (builder.length() != 0) {
builder.append(URLEncoder.encode(name, charset.name())); builder.append('&');
if (value != null) { }
builder.append('='); builder.append(URLEncoder.encode(name, charset.name()));
builder.append(URLEncoder.encode(value, charset.name())); if (value != null) {
if (valueIterator.hasNext()) { builder.append('=');
builder.append('&'); builder.append(URLEncoder.encode(value, charset.name()));
}
} }
} catch (UnsupportedEncodingException ex) {
} throw new IllegalStateException(ex);
if (nameIterator.hasNext()) { }
builder.append('&'); }));
}
}
final byte[] bytes = builder.toString().getBytes(charset); final byte[] bytes = builder.toString().getBytes(charset);
outputMessage.getHeaders().setContentLength(bytes.length); outputMessage.getHeaders().setContentLength(bytes.length);
@ -331,6 +328,18 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
} }
} }
private MediaType getMediaType(@Nullable MediaType mediaType) {
if (mediaType == null) {
return DEFAULT_FORM_DATA_MEDIA_TYPE;
}
else if (mediaType.getCharset() == null) {
return new MediaType(mediaType, this.charset);
}
else {
return mediaType;
}
}
private void writeMultipart(final MultiValueMap<String, Object> parts, private void writeMultipart(final MultiValueMap<String, Object> parts,
HttpOutputMessage outputMessage) throws IOException { HttpOutputMessage outputMessage) throws IOException {