26
26
import java .util .Optional ;
27
27
import java .util .concurrent .atomic .AtomicBoolean ;
28
28
import java .util .function .Supplier ;
29
-
29
+ import java . util . stream . Collectors ;
30
30
import javax .mail .internet .MimeUtility ;
31
31
32
32
import org .reactivestreams .Publisher ;
@@ -71,28 +71,18 @@ public class MultipartHttpMessageWriter implements HttpMessageWriter<MultiValueM
71
71
72
72
private Charset filenameCharset = DEFAULT_CHARSET ;
73
73
74
- private final DataBufferFactory bufferFactory ;
74
+ private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory () ;
75
75
76
76
77
77
public MultipartHttpMessageWriter () {
78
- this (new DefaultDataBufferFactory ());
79
- }
80
-
81
- public MultipartHttpMessageWriter (DataBufferFactory bufferFactory ) {
82
78
this .partWriters = Arrays .asList (
83
79
new EncoderHttpMessageWriter <>(CharSequenceEncoder .textPlainOnly ()),
84
80
new ResourceHttpMessageWriter ()
85
81
);
86
- this .bufferFactory = bufferFactory ;
87
82
}
88
83
89
84
public MultipartHttpMessageWriter (List <HttpMessageWriter <?>> partWriters ) {
90
- this (partWriters , new DefaultDataBufferFactory ());
91
- }
92
-
93
- public MultipartHttpMessageWriter (List <HttpMessageWriter <?>> partWriters , DataBufferFactory factory ) {
94
85
this .partWriters = partWriters ;
95
- this .bufferFactory = factory ;
96
86
}
97
87
98
88
/**
@@ -130,12 +120,17 @@ public Mono<Void> write(Publisher<? extends MultiValueMap<String, ?>> inputStrea
130
120
131
121
byte [] boundary = generateMultipartBoundary ();
132
122
133
- HttpHeaders headers = outputMessage .getHeaders ();
134
- headers .setContentType (new MediaType (MediaType .MULTIPART_FORM_DATA ,
123
+ outputMessage .getHeaders ().setContentType (new MediaType ("multipart" , "form-data" ,
135
124
Collections .singletonMap ("boundary" , new String (boundary , StandardCharsets .US_ASCII ))));
136
125
137
- return Mono .from (inputStream ).flatMap (multiValueMap ->
138
- outputMessage .writeWith (generateParts (multiValueMap , boundary )));
126
+ return Mono .from (inputStream ).flatMap (map -> {
127
+
128
+ Flux <DataBuffer > body = Flux .fromIterable (map .entrySet ())
129
+ .concatMap (entry -> encodePartValues (boundary , entry .getKey (), entry .getValue ()))
130
+ .concatWith (Mono .just (generateLastLine (boundary )));
131
+
132
+ return outputMessage .writeWith (body );
133
+ });
139
134
}
140
135
141
136
/**
@@ -146,16 +141,13 @@ protected byte[] generateMultipartBoundary() {
146
141
return MimeTypeUtils .generateMultipartBoundary ();
147
142
}
148
143
149
- private Flux <DataBuffer > generateParts (MultiValueMap <String , ?> map , byte [] boundary ) {
150
- return Flux .fromIterable (map .entrySet ())
151
- .concatMap (entry -> Flux
152
- .fromIterable (entry .getValue ())
153
- .concatMap (value -> generatePart (entry .getKey (), value , boundary )))
154
- .concatWith (Mono .just (generateLastLine (boundary )));
144
+ private Flux <DataBuffer > encodePartValues (byte [] boundary , String name , List <?> values ) {
145
+ return Flux .concat (values .stream ().map (v ->
146
+ encodePart (boundary , name , v )).collect (Collectors .toList ()));
155
147
}
156
148
157
149
@ SuppressWarnings ("unchecked" )
158
- private <T > Flux <DataBuffer > generatePart ( String name , T value , byte [] boundary ) {
150
+ private <T > Flux <DataBuffer > encodePart ( byte [] boundary , String name , T value ) {
159
151
160
152
MultipartHttpOutputMessage outputMessage = new MultipartHttpOutputMessage (this .bufferFactory );
161
153
0 commit comments