Skip to content

Commit 594f4d5

Browse files
committed
RestTemplate provides patchForObject operations
Issue: SPR-14857
1 parent 2d83ca6 commit 594f4d5

File tree

4 files changed

+196
-31
lines changed

4 files changed

+196
-31
lines changed

spring-web/src/main/java/org/springframework/web/client/RestOperations.java

Lines changed: 87 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -28,9 +28,9 @@
2828
import org.springframework.http.ResponseEntity;
2929

3030
/**
31-
* Interface specifying a basic set of RESTful operations. Implemented by {@link RestTemplate}.
32-
* Not often used directly, but a useful option to enhance testability, as it can easily
33-
* be mocked or stubbed.
31+
* Interface specifying a basic set of RESTful operations.
32+
* Implemented by {@link RestTemplate}. Not often used directly, but a useful
33+
* option to enhance testability, as it can easily be mocked or stubbed.
3434
*
3535
* @author Arjen Poutsma
3636
* @author Juergen Hoeller
@@ -139,27 +139,27 @@ public interface RestOperations {
139139
// POST
140140

141141
/**
142-
* Create a new resource by POSTing the given object to the URI template, and returns the value of the
143-
* {@code Location} header. This header typically indicates where the new resource is stored.
142+
* Create a new resource by POSTing the given object to the URI template, and returns the value of
143+
* the {@code Location} header. This header typically indicates where the new resource is stored.
144144
* <p>URI Template variables are expanded using the given URI variables, if any.
145145
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
146146
* add additional HTTP headers to the request.
147147
* @param url the URL
148-
* @param request the Object to be POSTed, may be {@code null}
148+
* @param request the Object to be POSTed (may be {@code null})
149149
* @param uriVariables the variables to expand the template
150150
* @return the value for the {@code Location} header
151151
* @see HttpEntity
152152
*/
153153
URI postForLocation(String url, Object request, Object... uriVariables) throws RestClientException;
154154

155155
/**
156-
* Create a new resource by POSTing the given object to the URI template, and returns the value of the
157-
* {@code Location} header. This header typically indicates where the new resource is stored.
156+
* Create a new resource by POSTing the given object to the URI template, and returns the value of
157+
* the {@code Location} header. This header typically indicates where the new resource is stored.
158158
* <p>URI Template variables are expanded using the given map.
159159
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
160160
* add additional HTTP headers to the request.
161161
* @param url the URL
162-
* @param request the Object to be POSTed, may be {@code null}
162+
* @param request the Object to be POSTed (may be {@code null})
163163
* @param uriVariables the variables to expand the template
164164
* @return the value for the {@code Location} header
165165
* @see HttpEntity
@@ -172,7 +172,7 @@ public interface RestOperations {
172172
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
173173
* add additional HTTP headers to the request.
174174
* @param url the URL
175-
* @param request the Object to be POSTed, may be {@code null}
175+
* @param request the Object to be POSTed (may be {@code null})
176176
* @return the value for the {@code Location} header
177177
* @see HttpEntity
178178
*/
@@ -185,7 +185,7 @@ public interface RestOperations {
185185
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
186186
* add additional HTTP headers to the request.
187187
* @param url the URL
188-
* @param request the Object to be POSTed, may be {@code null}
188+
* @param request the Object to be POSTed (may be {@code null})
189189
* @param responseType the type of the return value
190190
* @param uriVariables the variables to expand the template
191191
* @return the converted object
@@ -201,7 +201,7 @@ <T> T postForObject(String url, Object request, Class<T> responseType, Object...
201201
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
202202
* add additional HTTP headers to the request.
203203
* @param url the URL
204-
* @param request the Object to be POSTed, may be {@code null}
204+
* @param request the Object to be POSTed (may be {@code null})
205205
* @param responseType the type of the return value
206206
* @param uriVariables the variables to expand the template
207207
* @return the converted object
@@ -216,7 +216,7 @@ <T> T postForObject(String url, Object request, Class<T> responseType, Map<Strin
216216
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
217217
* add additional HTTP headers to the request.
218218
* @param url the URL
219-
* @param request the Object to be POSTed, may be {@code null}
219+
* @param request the Object to be POSTed (may be {@code null})
220220
* @param responseType the type of the return value
221221
* @return the converted object
222222
* @see HttpEntity
@@ -230,11 +230,11 @@ <T> T postForObject(String url, Object request, Class<T> responseType, Map<Strin
230230
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
231231
* add additional HTTP headers to the request.
232232
* @param url the URL
233-
* @param request the Object to be POSTed, may be {@code null}
233+
* @param request the Object to be POSTed (may be {@code null})
234234
* @param uriVariables the variables to expand the template
235235
* @return the converted object
236-
* @see HttpEntity
237236
* @since 3.0.2
237+
* @see HttpEntity
238238
*/
239239
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
240240
throws RestClientException;
@@ -246,11 +246,11 @@ <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> respons
246246
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
247247
* add additional HTTP headers to the request.
248248
* @param url the URL
249-
* @param request the Object to be POSTed, may be {@code null}
249+
* @param request the Object to be POSTed (may be {@code null})
250250
* @param uriVariables the variables to expand the template
251251
* @return the converted object
252-
* @see HttpEntity
253252
* @since 3.0.2
253+
* @see HttpEntity
254254
*/
255255
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
256256
throws RestClientException;
@@ -261,10 +261,10 @@ <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> respons
261261
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
262262
* add additional HTTP headers to the request.
263263
* @param url the URL
264-
* @param request the Object to be POSTed, may be {@code null}
264+
* @param request the Object to be POSTed (may be {@code null})
265265
* @return the converted object
266-
* @see HttpEntity
267266
* @since 3.0.2
267+
* @see HttpEntity
268268
*/
269269
<T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;
270270

@@ -277,7 +277,7 @@ <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> respons
277277
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
278278
* add additional HTTP headers to the request.
279279
* @param url the URL
280-
* @param request the Object to be PUT, may be {@code null}
280+
* @param request the Object to be PUT (may be {@code null})
281281
* @param uriVariables the variables to expand the template
282282
* @see HttpEntity
283283
*/
@@ -289,7 +289,7 @@ <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> respons
289289
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
290290
* add additional HTTP headers to the request.
291291
* @param url the URL
292-
* @param request the Object to be PUT, may be {@code null}
292+
* @param request the Object to be PUT (may be {@code null})
293293
* @param uriVariables the variables to expand the template
294294
* @see HttpEntity
295295
*/
@@ -300,12 +300,64 @@ <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> respons
300300
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
301301
* add additional HTTP headers to the request.
302302
* @param url the URL
303-
* @param request the Object to be PUT, may be {@code null}
303+
* @param request the Object to be PUT (may be {@code null})
304304
* @see HttpEntity
305305
*/
306306
void put(URI url, Object request) throws RestClientException;
307307

308308

309+
// PATCH
310+
311+
/**
312+
* Update a resource by PATCHing the given object to the URI template,
313+
* and returns the representation found in the response.
314+
* <p>URI Template variables are expanded using the given URI variables, if any.
315+
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
316+
* add additional HTTP headers to the request.
317+
* @param url the URL
318+
* @param request the Object to be PATCHed (may be {@code null})
319+
* @param responseType the type of the return value
320+
* @param uriVariables the variables to expand the template
321+
* @return the converted object
322+
* @since 4.3.5
323+
* @see HttpEntity
324+
*/
325+
<T> T patchForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
326+
throws RestClientException;
327+
328+
/**
329+
* Update a resource by PATCHing the given object to the URI template,
330+
* and returns the representation found in the response.
331+
* <p>URI Template variables are expanded using the given map.
332+
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
333+
* add additional HTTP headers to the request.
334+
* @param url the URL
335+
* @param request the Object to be PATCHed (may be {@code null})
336+
* @param responseType the type of the return value
337+
* @param uriVariables the variables to expand the template
338+
* @return the converted object
339+
* @since 4.3.5
340+
* @see HttpEntity
341+
*/
342+
<T> T patchForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
343+
throws RestClientException;
344+
345+
/**
346+
* Update a resource by PATCHing the given object to the URL,
347+
* and returns the representation found in the response.
348+
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
349+
* add additional HTTP headers to the request.
350+
* @param url the URL
351+
* @param request the Object to be PATCHed (may be {@code null})
352+
* @param responseType the type of the return value
353+
* @return the converted object
354+
* @since 4.3.5
355+
* @see HttpEntity
356+
*/
357+
<T> T patchForObject(URI url, Object request, Class<T> responseType) throws RestClientException;
358+
359+
360+
309361
// DELETE
310362

311363
/**
@@ -368,7 +420,8 @@ <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> respons
368420
* <p>URI Template variables are expanded using the given URI variables, if any.
369421
* @param url the URL
370422
* @param method the HTTP method (GET, POST, etc)
371-
* @param requestEntity the entity (headers and/or body) to write to the request, may be {@code null}
423+
* @param requestEntity the entity (headers and/or body) to write to the request
424+
* may be {@code null})
372425
* @param responseType the type of the return value
373426
* @param uriVariables the variables to expand in the template
374427
* @return the response as entity
@@ -383,7 +436,8 @@ <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requ
383436
* <p>URI Template variables are expanded using the given URI variables, if any.
384437
* @param url the URL
385438
* @param method the HTTP method (GET, POST, etc)
386-
* @param requestEntity the entity (headers and/or body) to write to the request, may be {@code null}
439+
* @param requestEntity the entity (headers and/or body) to write to the request
440+
* (may be {@code null})
387441
* @param responseType the type of the return value
388442
* @param uriVariables the variables to expand in the template
389443
* @return the response as entity
@@ -397,7 +451,8 @@ <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requ
397451
* returns the response as {@link ResponseEntity}.
398452
* @param url the URL
399453
* @param method the HTTP method (GET, POST, etc)
400-
* @param requestEntity the entity (headers and/or body) to write to the request, may be {@code null}
454+
* @param requestEntity the entity (headers and/or body) to write to the request
455+
* (may be {@code null})
401456
* @param responseType the type of the return value
402457
* @return the response as entity
403458
* @since 3.0.2
@@ -416,7 +471,7 @@ <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> request
416471
* @param url the URL
417472
* @param method the HTTP method (GET, POST, etc)
418473
* @param requestEntity the entity (headers and/or body) to write to the
419-
* request, may be {@code null}
474+
* request (may be {@code null})
420475
* @param responseType the type of the return value
421476
* @param uriVariables the variables to expand in the template
422477
* @return the response as entity
@@ -435,7 +490,8 @@ <T> ResponseEntity<T> exchange(String url,HttpMethod method, HttpEntity<?> reque
435490
* </pre>
436491
* @param url the URL
437492
* @param method the HTTP method (GET, POST, etc)
438-
* @param requestEntity the entity (headers and/or body) to write to the request, may be {@code null}
493+
* @param requestEntity the entity (headers and/or body) to write to the request
494+
* (may be {@code null})
439495
* @param responseType the type of the return value
440496
* @param uriVariables the variables to expand in the template
441497
* @return the response as entity
@@ -454,7 +510,8 @@ <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requ
454510
* </pre>
455511
* @param url the URL
456512
* @param method the HTTP method (GET, POST, etc)
457-
* @param requestEntity the entity (headers and/or body) to write to the request, may be {@code null}
513+
* @param requestEntity the entity (headers and/or body) to write to the request
514+
* (may be {@code null})
458515
* @param responseType the type of the return value
459516
* @return the response as entity
460517
* @since 3.2

spring-web/src/main/java/org/springframework/web/client/RestTemplate.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,39 @@ public void put(URI url, Object request) throws RestClientException {
445445
}
446446

447447

448+
// PATCH
449+
450+
@Override
451+
public <T> T patchForObject(String url, Object request, Class<T> responseType,
452+
Object... uriVariables) throws RestClientException {
453+
454+
RequestCallback requestCallback = httpEntityCallback(request, responseType);
455+
HttpMessageConverterExtractor<T> responseExtractor =
456+
new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
457+
return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor, uriVariables);
458+
}
459+
460+
@Override
461+
public <T> T patchForObject(String url, Object request, Class<T> responseType,
462+
Map<String, ?> uriVariables) throws RestClientException {
463+
464+
RequestCallback requestCallback = httpEntityCallback(request, responseType);
465+
HttpMessageConverterExtractor<T> responseExtractor =
466+
new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
467+
return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor, uriVariables);
468+
}
469+
470+
@Override
471+
public <T> T patchForObject(URI url, Object request, Class<T> responseType)
472+
throws RestClientException {
473+
474+
RequestCallback requestCallback = httpEntityCallback(request, responseType);
475+
HttpMessageConverterExtractor<T> responseExtractor =
476+
new HttpMessageConverterExtractor<T>(responseType, getMessageConverters());
477+
return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor);
478+
}
479+
480+
448481
// DELETE
449482

450483
@Override
@@ -647,8 +680,8 @@ protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCal
647680
* @param method the HTTP method to execute (GET, POST, etc.)
648681
* @param response the resulting {@link ClientHttpResponse}
649682
* @throws IOException if propagated from {@link ResponseErrorHandler}
650-
* @see #setErrorHandler
651683
* @since 4.1.6
684+
* @see #setErrorHandler
652685
*/
653686
protected void handleResponse(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
654687
ResponseErrorHandler errorHandler = getErrorHandler();

spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,15 @@ public void postForObject() throws URISyntaxException {
154154
assertEquals("Invalid content", helloWorld, s);
155155
}
156156

157+
@Test
158+
public void patchForObject() throws URISyntaxException {
159+
// JDK client does not support the PATCH method
160+
Assume.assumeThat(this.clientHttpRequestFactory,
161+
Matchers.not(Matchers.instanceOf(SimpleClientHttpRequestFactory.class)));
162+
String s = template.patchForObject(baseUrl + "/{method}", helloWorld, String.class, "patch");
163+
assertEquals("Invalid content", helloWorld, s);
164+
}
165+
157166
@Test
158167
public void notFound() {
159168
try {

0 commit comments

Comments
 (0)