@ -30,36 +30,36 @@ Java::
+
+
[source,java,indent=0,subs="verbatim"]
[source,java,indent=0,subs="verbatim"]
----
----
RestClient defaultClient = RestClient.create();
RestClient defaultClient = RestClient.create();
RestClient customClient = RestClient.builder()
RestClient customClient = RestClient.builder()
.requestFactory(new HttpComponentsClientHttpRequestFactory())
.requestFactory(new HttpComponentsClientHttpRequestFactory())
.messageConverters(converters -> converters.add(new MyCustomMessageConverter()))
.messageConverters(converters -> converters.add(new MyCustomMessageConverter()))
.baseUrl("https://example.com")
.baseUrl("https://example.com")
.defaultUriVariables(Map.of("variable", "foo"))
.defaultUriVariables(Map.of("variable", "foo"))
.defaultHeader("My-Header", "Foo")
.defaultHeader("My-Header", "Foo")
.defaultCookie("My-Cookie", "Bar")
.defaultCookie("My-Cookie", "Bar")
.requestInterceptor(myCustomInterceptor)
.requestInterceptor(myCustomInterceptor)
.requestInitializer(myCustomInitializer)
.requestInitializer(myCustomInitializer)
.build();
.build();
----
----
Kotlin::
Kotlin::
+
+
[source,kotlin,indent=0,subs="verbatim"]
[source,kotlin,indent=0,subs="verbatim"]
----
----
val defaultClient = RestClient.create()
val defaultClient = RestClient.create()
val customClient = RestClient.builder()
val customClient = RestClient.builder()
.requestFactory(HttpComponentsClientHttpRequestFactory())
.requestFactory(HttpComponentsClientHttpRequestFactory())
.messageConverters { converters -> converters.add(MyCustomMessageConverter()) }
.messageConverters { converters -> converters.add(MyCustomMessageConverter()) }
.baseUrl("https://example.com")
.baseUrl("https://example.com")
.defaultUriVariables(mapOf("variable" to "foo"))
.defaultUriVariables(mapOf("variable" to "foo"))
.defaultHeader("My-Header", "Foo")
.defaultHeader("My-Header", "Foo")
.defaultCookie("My-Cookie", "Bar")
.defaultCookie("My-Cookie", "Bar")
.requestInterceptor(myCustomInterceptor)
.requestInterceptor(myCustomInterceptor)
.requestInitializer(myCustomInitializer)
.requestInitializer(myCustomInitializer)
.build()
.build()
----
----
======
======
@ -81,20 +81,20 @@ Java::
+
+
[source,java,indent=0,subs="verbatim,quotes"]
[source,java,indent=0,subs="verbatim,quotes"]
----
----
int id = 42;
int id = 42;
restClient.get()
restClient.get()
.uri("https://example.com/orders/{id}", id)
.uri("https://example.com/orders/{id}", id)
. ...
// ...
----
----
Kotlin::
Kotlin::
+
+
[source,kotlin,indent=0,subs="verbatim,quotes"]
[source,kotlin,indent=0,subs="verbatim,quotes"]
----
----
val id = 42
val id = 42
restClient.get()
restClient.get()
.uri("https://example.com/orders/{id}", id)
.uri("https://example.com/orders/{id}", id)
...
// ...
----
----
======
======
@ -133,12 +133,12 @@ Java::
+
+
[source,java,indent=0,subs="verbatim,quotes"]
[source,java,indent=0,subs="verbatim,quotes"]
----
----
String result = restClient.get() <1>
String result = restClient.get() <1>
.uri("https://example.com") <2>
.uri("https://example.com") <2>
.retrieve() <3>
.retrieve() <3>
.body(String.class); <4>
.body(String.class); <4>
System.out.println(result); <5>
System.out.println(result); <5>
----
----
<1> Set up a GET request
<1> Set up a GET request
<2> Specify the URL to connect to
<2> Specify the URL to connect to
@ -150,12 +150,12 @@ Kotlin::
+
+
[source,kotlin,indent=0,subs="verbatim,quotes"]
[source,kotlin,indent=0,subs="verbatim,quotes"]
----
----
val result= restClient.get() <1>
val result= restClient.get() <1>
.uri("https://example.com") <2>
.uri("https://example.com") <2>
.retrieve() <3>
.retrieve() <3>
.body<String>() <4>
.body<String>() <4>
println(result) <5>
println(result) <5>
----
----
<1> Set up a GET request
<1> Set up a GET request
<2> Specify the URL to connect to
<2> Specify the URL to connect to
@ -172,14 +172,14 @@ Java::
+
+
[source,java,indent=0,subs="verbatim,quotes"]
[source,java,indent=0,subs="verbatim,quotes"]
----
----
ResponseEntity<String> result = restClient.get() <1>
ResponseEntity<String> result = restClient.get() <1>
.uri("https://example.com") <1>
.uri("https://example.com") <1>
.retrieve()
.retrieve()
.toEntity(String.class); <2>
.toEntity(String.class); <2>
System.out.println("Response status: " + result.getStatusCode()); <3>
System.out.println("Response status: " + result.getStatusCode()); <3>
System.out.println("Response headers: " + result.getHeaders()); <3>
System.out.println("Response headers: " + result.getHeaders()); <3>
System.out.println("Contents: " + result.getBody()); <3>
System.out.println("Contents: " + result.getBody()); <3>
----
----
<1> Set up a GET request for the specified URL
<1> Set up a GET request for the specified URL
<2> Convert the response into a `ResponseEntity`
<2> Convert the response into a `ResponseEntity`
@ -189,14 +189,14 @@ Kotlin::
+
+
[source,kotlin,indent=0,subs="verbatim,quotes"]
[source,kotlin,indent=0,subs="verbatim,quotes"]
----
----
val result = restClient.get() <1>
val result = restClient.get() <1>
.uri("https://example.com") <1>
.uri("https://example.com") <1>
.retrieve()
.retrieve()
.toEntity<String>() <2>
.toEntity<String>() <2>
println("Response status: " + result.statusCode) <3>
println("Response status: " + result.statusCode) <3>
println("Response headers: " + result.headers) <3>
println("Response headers: " + result.headers) <3>
println("Contents: " + result.body) <3>
println("Contents: " + result.body) <3>
----
----
<1> Set up a GET request for the specified URL
<1> Set up a GET request for the specified URL
<2> Convert the response into a `ResponseEntity`
<2> Convert the response into a `ResponseEntity`
@ -212,12 +212,12 @@ Java::
+
+
[source,java,indent=0,subs="verbatim,quotes"]
[source,java,indent=0,subs="verbatim,quotes"]
----
----
int id = ...;
int id = ...;
Pet pet = restClient.get()
Pet pet = restClient.get()
.uri("https://petclinic.example.com/pets/{id}", id) <1>
.uri("https://petclinic.example.com/pets/{id}", id) <1>
.accept(APPLICATION_JSON) <2>
.accept(APPLICATION_JSON) <2>
.retrieve()
.retrieve()
.body(Pet.class); <3>
.body(Pet.class); <3>
----
----
<1> Using URI variables
<1> Using URI variables
<2> Set the `Accept` header to `application/json`
<2> Set the `Accept` header to `application/json`
@ -227,12 +227,12 @@ Kotlin::
+
+
[source,kotlin,indent=0,subs="verbatim,quotes"]
[source,kotlin,indent=0,subs="verbatim,quotes"]
----
----
val id = ...
val id = ...
val pet = restClient.get()
val pet = restClient.get()
.uri("https://petclinic.example.com/pets/{id}", id) <1>
.uri("https://petclinic.example.com/pets/{id}", id) <1>
.accept(APPLICATION_JSON) <2>
.accept(APPLICATION_JSON) <2>
.retrieve()
.retrieve()
.body<Pet>() <3>
.body<Pet>() <3>
----
----
<1> Using URI variables
<1> Using URI variables
<2> Set the `Accept` header to `application/json`
<2> Set the `Accept` header to `application/json`
@ -247,13 +247,13 @@ Java::
+
+
[source,java,indent=0,subs="verbatim,quotes"]
[source,java,indent=0,subs="verbatim,quotes"]
----
----
Pet pet = ... <1>
Pet pet = ... <1>
ResponseEntity<Void> response = restClient.post() <2>
ResponseEntity<Void> response = restClient.post() <2>
.uri("https://petclinic.example.com/pets/new") <2>
.uri("https://petclinic.example.com/pets/new") <2>
.contentType(APPLICATION_JSON) <3>
.contentType(APPLICATION_JSON) <3>
.body(pet) <4>
.body(pet) <4>
.retrieve()
.retrieve()
.toBodilessEntity(); <5>
.toBodilessEntity(); <5>
----
----
<1> Create a `Pet` domain object
<1> Create a `Pet` domain object
<2> Set up a POST request, and the URL to connect to
<2> Set up a POST request, and the URL to connect to
@ -265,13 +265,13 @@ Kotlin::
+
+
[source,kotlin,indent=0,subs="verbatim,quotes"]
[source,kotlin,indent=0,subs="verbatim,quotes"]
----
----
val pet: Pet = ... <1>
val pet: Pet = ... <1>
val response = restClient.post() <2>
val response = restClient.post() <2>
.uri("https://petclinic.example.com/pets/new") <2>
.uri("https://petclinic.example.com/pets/new") <2>
.contentType(APPLICATION_JSON) <3>
.contentType(APPLICATION_JSON) <3>
.body(pet) <4>
.body(pet) <4>
.retrieve()
.retrieve()
.toBodilessEntity() <5>
.toBodilessEntity() <5>
----
----
<1> Create a `Pet` domain object
<1> Create a `Pet` domain object
<2> Set up a POST request, and the URL to connect to
<2> Set up a POST request, and the URL to connect to
@ -291,13 +291,13 @@ Java::
+
+
[source,java,indent=0,subs="verbatim,quotes"]
[source,java,indent=0,subs="verbatim,quotes"]
----
----
String result = restClient.get() <1>
String result = restClient.get() <1>
.uri("https://example.com/this-url-does-not-exist") <1>
.uri("https://example.com/this-url-does-not-exist") <1>
.retrieve()
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { <2>
.onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { <2>
throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); <3>
throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); <3>
})
})
.body(String.class);
.body(String.class);
----
----
<1> Create a GET request for a URL that returns a 404 status code
<1> Create a GET request for a URL that returns a 404 status code
<2> Set up a status handler for all 4xx status codes
<2> Set up a status handler for all 4xx status codes
@ -307,12 +307,12 @@ Kotlin::
+
+
[source,kotlin,indent=0,subs="verbatim,quotes"]
[source,kotlin,indent=0,subs="verbatim,quotes"]
----
----
val result = restClient.get() <1>
val result = restClient.get() <1>
.uri("https://example.com/this-url-does-not-exist") <1>
.uri("https://example.com/this-url-does-not-exist") <1>
.retrieve()
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError) { _, response -> <2>
.onStatus(HttpStatusCode::is4xxClientError) { _, response -> <2>
throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) } <3>
throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) } <3>
.body<String>()
.body<String>()
----
----
<1> Create a GET request for a URL that returns a 404 status code
<1> Create a GET request for a URL that returns a 404 status code
<2> Set up a status handler for all 4xx status codes
<2> Set up a status handler for all 4xx status codes
@ -330,18 +330,18 @@ Java::
+
+
[source,java,indent=0,subs="verbatim,quotes"]
[source,java,indent=0,subs="verbatim,quotes"]
----
----
Pet result = restClient.get()
Pet result = restClient.get()
.uri("https://petclinic.example.com/pets/{id}", id)
.uri("https://petclinic.example.com/pets/{id}", id)
.accept(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.exchange((request, response) -> { <1>
.exchange((request, response) -> { <1>
if (response.getStatusCode().is4xxClientError()) { <2>
if (response.getStatusCode().is4xxClientError()) { <2>
throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); <2>
throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); <2>
}
}
else {
else {
Pet pet = convertResponse(response); <3>
Pet pet = convertResponse(response); <3>
return pet;
return pet;
}
}
});
});
----
----
<1> `exchange` provides the request and response
<1> `exchange` provides the request and response
<2> Throw an exception when the response has a 4xx status code
<2> Throw an exception when the response has a 4xx status code
@ -351,17 +351,17 @@ Kotlin::
+
+
[source,kotlin,indent=0,subs="verbatim,quotes"]
[source,kotlin,indent=0,subs="verbatim,quotes"]
----
----
val result = restClient.get()
val result = restClient.get()
.uri("https://petclinic.example.com/pets/{id}", id)
.uri("https://petclinic.example.com/pets/{id}", id)
.accept(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.exchange { request, response -> <1>
.exchange { request, response -> <1>
if (response.getStatusCode().is4xxClientError()) { <2>
if (response.getStatusCode().is4xxClientError()) { <2>
throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) <2>
throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) <2>
} else {
} else {
val pet: Pet = convertResponse(response) <3>
val pet: Pet = convertResponse(response) <3>
pet
pet
}
}
}
}
----
----
<1> `exchange` provides the request and response
<1> `exchange` provides the request and response
<2> Throw an exception when the response has a 4xx status code
<2> Throw an exception when the response has a 4xx status code
@ -380,15 +380,14 @@ To serialize only a subset of the object properties, you can specify a {baeldung
[source,java,indent=0,subs="verbatim"]
[source,java,indent=0,subs="verbatim"]
----
----
MappingJacksonValue value = new MappingJacksonValue(new User("eric", "7!jd#h23"));
MappingJacksonValue value = new MappingJacksonValue(new User("eric", "7!jd#h23"));
value.setSerializationView(User.WithoutPasswordView.class);
value.setSerializationView(User.WithoutPasswordView.class);
ResponseEntity<Void> response = restClient.post() // or RestTemplate.postForEntity
ResponseEntity<Void> response = restClient.post() // or RestTemplate.postForEntity
.contentType(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.body(value)
.body(value)
.retrieve()
.retrieve()
.toBodilessEntity();
.toBodilessEntity();
----
----
==== Multipart
==== Multipart
@ -398,24 +397,24 @@ For example:
[source,java,indent=0,subs="verbatim"]
[source,java,indent=0,subs="verbatim"]
----
----
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("fieldPart", "fieldValue");
parts.add("fieldPart", "fieldValue");
parts.add("filePart", new FileSystemResource("...logo.png"));
parts.add("filePart", new FileSystemResource("...logo.png"));
parts.add("jsonPart", new Person("Jason"));
parts.add("jsonPart", new Person("Jason"));
HttpHeaders headers = new HttpHeaders();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
headers.setContentType(MediaType.APPLICATION_XML);
parts.add("xmlPart", new HttpEntity<>(myBean, headers));
parts.add("xmlPart", new HttpEntity<>(myBean, headers));
// send using RestClient.post or RestTemplate.postForEntity
// send using RestClient.post or RestTemplate.postForEntity
----
----
In most cases, you do not have to specify the `Content-Type` for each part.
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.
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` with an `HttpEntity` wrapper.
If necessary, you can explicitly provide the `MediaType` with an `HttpEntity` wrapper.
Once the `MultiValueMap` is ready, you can use it as the body of a `POST` request, using `RestClient.post().body(parts)` (or `RestTemplate.postForObject`).
Once the `MultiValueMap` is ready, you can use it as the body of a `POST` request, using `RestClient.post().body(parts)` (or `RestTemplate.postForObject`).
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` 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` defaults to `application/x-www-form-urlencoded`.
If the `MultiValueMap` has `String` values, the `Content-Type` defaults to `application/x-www-form-urlencoded`.
@ -1137,11 +1136,11 @@ performed through the client:
[source,java,indent=0,subs="verbatim,quotes"]
[source,java,indent=0,subs="verbatim,quotes"]
----
----
RestTemplate restTemplate = new RestTemplate();
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(myErrorHandler);
restTemplate.setErrorHandler(myErrorHandler);
RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
----
----
For more details and options, see the Javadoc of `setErrorHandler` in `RestTemplate` and
For more details and options, see the Javadoc of `setErrorHandler` in `RestTemplate` and