Affects: 6.0.11
With the WebClient upload snippet below, trying to upload file with some parameters. The body sent have unnecessary headers submitted. When I tested with just html form upload, upload process was successful, however with webclient, error was occured. As I do not have access to the endpoint nor have no idea how they process at the endpoint, the only differences I saw was they payload sent.
MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("data_file", new FileSystemResource(uFile));
builder.part("user_id", "test_user");
builder.part("password", "testPwd");
builder.part("up_type", "2");
builder.part("kind", "35");
builder.part("kind_name", "SAMPLE UPLOAD TEST");
builder.part("file_name", "XXXXX.csv");
WebClient client = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(
HttpClient.create().option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 180000).compress(true).followRedirect(true)))
.filter(new LoggingExchangeFilterFunction(true)).build();
String httpStatusMono = client.post().uri(uploadUrl).contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(builder.build()))
.retrieve().bodyToMono(String.class).block();
System.out.println("Http Status : " + httpStatusMono);
Payload Sent through browser (Expected Value)
------WebKitFormBoundaryZrXyDAsX9SPUu09A
Content-Disposition: form-data; name="data_file"; filename="XXXXX.csv"
Content-Type: text/csv
Content-Length: 135
S,1,test_user,20230825,40
D,9999,0012102,5,20230904,,01,R000000,,20230908,,,,
D,9999,0037669,6,20230905,,01,R000000,,20230909,,,,
E,4
------WebKitFormBoundaryZrXyDAsX9SPUu09A
Content-Disposition: form-data; name="user_id"
test_user
------WebKitFormBoundaryZrXyDAsX9SPUu09A
Content-Disposition: form-data; name="password"
testPwd
------WebKitFormBoundaryZrXyDAsX9SPUu09A
Content-Disposition: form-data; name="up_type"
2
------WebKitFormBoundaryZrXyDAsX9SPUu09A
Content-Disposition: form-data; name="kind"
35
------WebKitFormBoundaryZrXyDAsX9SPUu09A
Content-Disposition: form-data; name="kind_name"
SAMPLE UPLOAD TEST
------WebKitFormBoundaryZrXyDAsX9SPUu09A
Content-Disposition: form-data; name="file_name"
XXXXX.csv
------WebKitFormBoundaryZrXyDAsX9SPUu09A--
Payload sent through WebClient (Error occured)
--KNeG0Ctz9Py2S3-WVI-GQBu27kptq1DOrxSoDb
Content-Disposition: form-data; name="data_file"; filename="XXXXX.csv"
Content-Type: text/csv
Content-Length: 135
S,1,test_user,20230825,40
D,9999,0012102,5,20230904,,01,R000000,,20230908,,,,
D,9999,0037669,6,20230905,,01,R000000,,20230909,,,,
E,4
--KNeG0Ctz9Py2S3-WVI-GQBu27kptq1DOrxSoDb
Content-Disposition: form-data; name="user_id"
Content-Type: text/plain;charset=UTF-8
Content-Length: 8
test_user
--KNeG0Ctz9Py2S3-WVI-GQBu27kptq1DOrxSoDb
Content-Disposition: form-data; name="password"
Content-Type: text/plain;charset=UTF-8
Content-Length: 8
testPwd
--KNeG0Ctz9Py2S3-WVI-GQBu27kptq1DOrxSoDb
Content-Disposition: form-data; name="up_type"
Content-Type: text/plain;charset=UTF-8
Content-Length: 1
2
--KNeG0Ctz9Py2S3-WVI-GQBu27kptq1DOrxSoDb
Content-Disposition: form-data; name="kind"
Content-Type: text/plain;charset=UTF-8
Content-Length: 2
35
--KNeG0Ctz9Py2S3-WVI-GQBu27kptq1DOrxSoDb
Content-Disposition: form-data; name="kind_name"
Content-Type: text/plain;charset=UTF-8
Content-Length: 52
SAMPLE UPLOAD TEST
--KNeG0Ctz9Py2S3-WVI-GQBu27kptq1DOrxSoDb
Content-Disposition: form-data; name="file_name"
Content-Type: text/plain;charset=UTF-8
Content-Length: 24
XXXXX.csv
--KNeG0Ctz9Py2S3-WVI-GQBu27kptq1DOrxSoDb--
As you can see, the only difference is the "Content-Type" and "Content-Length" added in the headers of each parameter. I tried several approaches in setting of the body but no avail. I noticed that in MultipartHttpMessageWriter.java, content-type is always included in sending the payload so there is no way to exclude it. Is there's a way to override MultipartHttpMessageWriter with custom Writer class?
Comment From: rstoyanchev
MultipartHttpMessageWriter
encodes individual parts through a list of HttpMessageWriter
's that support specific Java types and media formats. You can customize this list:
WebClient webClient = WebClient.builder()
.baseUrl("...")
.codecs(config -> config.defaultCodecs().multipartCodecs().encoder(..).writer(...))
.build();
For files, you can use ResourceEncoder
. For text, CharSequenceEncoder
is wrapped with EncoderHttpMessageWriter
and that's what adds content-length and content-type. You could instead wrap CharSequenceEncoder
with a simpler HttpMessageWriter
that delegates CharSequenceEncoder
doesn't set any headers.