diff --git a/spring-web/src/main/java/org/springframework/web/client/RestOperations.java b/spring-web/src/main/java/org/springframework/web/client/RestOperations.java index 33b1d01e1f..03d3cfa350 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestOperations.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -153,8 +153,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @param uriVariables the variables to expand the template @@ -174,8 +173,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @param uriVariables the variables to expand the template @@ -195,8 +193,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @return the value for the {@code Location} header @@ -215,8 +212,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @param responseType the type of the return value @@ -238,8 +234,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @param responseType the type of the return value @@ -260,8 +255,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @param responseType the type of the return value @@ -281,8 +275,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @param uriVariables the variables to expand the template @@ -303,8 +296,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @param uriVariables the variables to expand the template @@ -324,8 +316,7 @@ public interface RestOperations { * {@link org.springframework.util.MultiValueMap MultiValueMap} to create a multipart request. * The values in the {@code MultiValueMap} can be any Object representing the body of the part, * or an {@link org.springframework.http.HttpEntity HttpEntity} representing a part with body - * and headers. The {@code MultiValueMap} can be built conveniently using - * {@link org.springframework.http.client.MultipartBodyBuilder MultipartBodyBuilder}. + * and headers. * @param url the URL * @param request the Object to be POSTed (may be {@code null}) * @return the converted object diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 3e57e04f06..66700f5485 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -1277,45 +1277,46 @@ to serialize only a subset of the object properties, as the following example sh [[rest-template-multipart]] ===== Multipart -To send multipart data, you need to provide a `MultiValueMap` whose values are -either `Object` instances that represent part content or `HttpEntity` instances that represent the content and -headers for a part. `MultipartBodyBuilder` provides a convenient API to prepare a -multipart request, as the following example shows: +To send multipart data, you need to provide a `MultiValueMap` whose values +may be an `Object` for part content, a `Resource` for a file part, or an `HttpEntity` for +part content with headers. For example: ==== [source,java,intent=0] [subs="verbatim,quotes"] ---- - MultipartBodyBuilder builder = new MultipartBodyBuilder(); - builder.part("fieldPart", "fieldValue"); - builder.part("filePart", new FileSystemResource("...logo.png")); - builder.part("jsonPart", new Person("Jason")); + MultiValueMap parts = new LinkedMultiValueMap<>(); - MultiValueMap> parts = builder.build(); + parts.add("fieldPart", "fieldValue"); + parts.add("filePart", new FileSystemResource("...logo.png")); + parts.add("jsonPart", new Person("Jason")); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + parts.add("xmlPart", new HttpEntity<>(myBean, headers)); ---- ==== In most cases, you do not have to specify the `Content-Type` for each part. The content -type is determined automatically based on the `HttpMessageConverter` chosen to serialize it -or, in the case of a `Resource`, based on the file extension. If necessary, you can -explicitly provide the `MediaType` to use for each part through one of the overloaded -builder `part` methods. +type is determined automatically based on the `HttpMessageConverter` chosen to serialize +it or, in the case of a `Resource` based on the file extension. If necessary, you can +explicitly provide the `MediaType` with an `HttpEntity` wrapper. -Once the `MultiValueMap` is ready, you can pass it to the `RestTemplate`, as the following example shows: +Once the `MultiValueMap` is ready, you can pass it to the `RestTemplate`, as show below: ==== [source,java,intent=0] [subs="verbatim,quotes"] ---- - MultipartBodyBuilder builder = ...; - template.postForObject("https://example.com/upload", builder.build(), Void.class); + MultiValueMap parts = ...; + template.postForObject("https://example.com/upload", parts, Void.class); ---- ==== -If the `MultiValueMap` contains at least one non-`String` value, which could also be -represent regular form data (that is, `application/x-www-form-urlencoded`), you need not -set the `Content-Type` to `multipart/form-data`. This is always the case when you use -`MultipartBodyBuilder` which ensures an `HttpEntity` wrapper. +If the `MultiValueMap` contains at least one non-`String` value, the `Content-Type` is set +to `multipart/form-data` by the `FormHttpMessageConverter`. If the `MultiValueMap` has +`String` values the `Content-Type` is defaulted to `application/x-www-form-urlencoded`. +If necessary the `Content-Type` may also be set explicitly. [[rest-async-resttemplate]]