Introduced ResponseEntity, for access to the response status code

This commit is contained in:
Arjen Poutsma
2010-04-01 10:08:51 +00:00
parent 636e2f0f4c
commit 689e7b7af2
13 changed files with 438 additions and 360 deletions

View File

@@ -16,9 +16,6 @@
package org.springframework.http;
import java.util.Map;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
/**
@@ -35,6 +32,15 @@ import org.springframework.util.MultiValueMap;
* String body = entity.getBody();
* MediaType contentType = entity.getHeaders().getContentType();
* </pre>
* Can also be used in Spring MVC, as a return value from a @Controller method:
* <pre>
* &#64;RequestMapping("/handle")
* public HttpEntity&ltString&gt handle() {
* HttpHeaders responseHeaders = new HttpHeaders();
* responseHeaders.set("MyResponseHeader", "MyValue");
* return new HttpEntity<String>("Hello World", responseHeaders);
* }
* </pre>
*
* @author Arjen Poutsma
* @since 3.0.2
@@ -59,7 +65,7 @@ public class HttpEntity<T> {
* Create a new, empty {@code HttpEntity}.
*/
private HttpEntity() {
this(null, (MultiValueMap<String, String>) null);
this(null, null);
}
/**
@@ -67,15 +73,7 @@ public class HttpEntity<T> {
* @param body the entity body
*/
public HttpEntity(T body) {
this(body, (MultiValueMap<String, String>) null);
}
/**
* Create a new {@code HttpEntity} with the given headers and no body.
* @param headers the entity headers
*/
public HttpEntity(Map<String, String> headers) {
this(null, toMultiValueMap(headers));
this(body, null);
}
/**
@@ -86,24 +84,6 @@ public class HttpEntity<T> {
this(null, headers);
}
/**
* Create a new {@code HttpEntity} with the given body and {@code Content-Type} header value.
* @param body the entity body
* @param contentType the value of the {@code Content-Type header}
*/
public HttpEntity(T body, MediaType contentType) {
this(body, toMultiValueMap(contentType));
}
/**
* Create a new {@code HttpEntity} with the given body and headers.
* @param body the entity body
* @param headers the entity headers
*/
public HttpEntity(T body, Map<String, String> headers) {
this(body, toMultiValueMap(headers));
}
/**
* Create a new {@code HttpEntity} with the given body and headers.
* @param body the entity body
@@ -140,27 +120,4 @@ public class HttpEntity<T> {
return (this.body != null);
}
private static MultiValueMap<String, String> toMultiValueMap(Map<String, String> map) {
if (map == null) {
return null;
}
else {
MultiValueMap<String, String> result = new LinkedMultiValueMap<String, String>(map.size());
result.setAll(map);
return result;
}
}
private static MultiValueMap<String, String> toMultiValueMap(MediaType contentType) {
if (contentType == null) {
return null;
}
else {
HttpHeaders result = new HttpHeaders();
result.setContentType(contentType);
return result;
}
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http;
import org.springframework.util.MultiValueMap;
/**
* Extension of {@link HttpEntity} that adds a {@link HttpStatus} status code.
*
* @author Arjen Poutsma
* @since 3.0.2
* @see #getStatusCode()
*/
public class ResponseEntity<T> extends HttpEntity<T> {
private final HttpStatus statusCode;
/**
* Create a new {@code ResponseEntity} with the given body and status code, and no headers.
* @param body the entity body
* @param statusCode the status code
*/
public ResponseEntity(T body, HttpStatus statusCode) {
super(body);
this.statusCode = statusCode;
}
/**
* Create a new {@code HttpEntity} with the given headers and status code, and no body.
* @param headers the entity headers
* @param statusCode the status code
*/
public ResponseEntity(MultiValueMap<String, String> headers, HttpStatus statusCode) {
super(headers);
this.statusCode = statusCode;
}
/**
* Create a new {@code HttpEntity} with the given body, headers, and status code.
* @param body the entity body
* @param headers the entity headers
* @param statusCode the status code
*/
public ResponseEntity(T body, MultiValueMap<String, String> headers, HttpStatus statusCode) {
super(body, headers);
this.statusCode = statusCode;
}
/**
* Return the HTTP status code of the response.
* @return the HTTP status as an HttpStatus enum value
*/
public HttpStatus getStatusCode() {
return statusCode;
}
}

View File

@@ -151,7 +151,8 @@ import java.lang.annotation.Target;
* to the response stream using
* {@linkplain org.springframework.http.converter.HttpMessageConverter message
* converters}.
* <li>A {@link org.springframework.http.HttpEntity HttpEntity&lt;?&gt;} object
* <li>A {@link org.springframework.http.HttpEntity HttpEntity&lt;?&gt;} or
* {@link org.springframework.http.ResponseEntity ResponseEntity&lt;?&gt;} object
* to access to the Servlet reponse HTTP headers and contents. The entity body will
* be converted to the response stream using
* {@linkplain org.springframework.http.converter.HttpMessageConverter message

View File

@@ -23,6 +23,7 @@ import java.util.Set;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
/**
* Interface specifying a basic set of RESTful operations. Implemented by {@link RestTemplate}.
@@ -71,7 +72,7 @@ public interface RestOperations {
/**
* Retrieve an entity by doing a GET on the specified URL.
* The response is converted and stored in an {@link HttpEntity}.
* The response is converted and stored in an {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given URI variables, if any.
* @param url the URL
* @param responseType the type of the return value
@@ -79,11 +80,11 @@ public interface RestOperations {
* @return the entity
* @since 3.0.2
*/
<T> HttpEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
/**
* Retrieve a representation by doing a GET on the URI template.
* The response is converted and stored in an {@link HttpEntity}.
* The response is converted and stored in an {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given map.
* @param url the URL
* @param responseType the type of the return value
@@ -91,17 +92,17 @@ public interface RestOperations {
* @return the converted object
* @since 3.0.2
*/
<T> HttpEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
/**
* Retrieve a representation by doing a GET on the URL .
* The response is converted and stored in an {@link HttpEntity}.
* The response is converted and stored in an {@link ResponseEntity}.
* @param url the URL
* @param responseType the type of the return value
* @return the converted object
* @since 3.0.2
*/
<T> HttpEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;
// HEAD
@@ -219,7 +220,7 @@ public interface RestOperations {
/**
* Create a new resource by POSTing the given object to the URI template,
* and returns the response as {@link HttpEntity}.
* and returns the response as {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given URI variables, if any.
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
* add additional HTTP headers to the request.
@@ -230,7 +231,7 @@ public interface RestOperations {
* @see HttpEntity
* @since 3.0.2
*/
<T> HttpEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
throws RestClientException;
/**
@@ -251,7 +252,7 @@ public interface RestOperations {
/**
* Create a new resource by POSTing the given object to the URL,
* and returns the response as {@link HttpEntity}.
* and returns the response as {@link ResponseEntity}.
* <p>The {@code request} parameter can be a {@link HttpEntity} in order to
* add additional HTTP headers to the request.
* @param url the URL
@@ -260,7 +261,7 @@ public interface RestOperations {
* @see HttpEntity
* @since 3.0.2
*/
<T> HttpEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;
// PUT
@@ -354,7 +355,7 @@ public interface RestOperations {
/**
* Execute the HTTP method to the given URI template, writing the given request entity to the request, and
* returns the response as {@link HttpEntity}.
* returns the response as {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given URI variables, if any.
* @param url the URL
* @param method the HTTP method (GET, POST, etc)
@@ -364,12 +365,12 @@ public interface RestOperations {
* @return the response as entity
* @since 3.0.2
*/
<T> HttpEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
<T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType, Object... uriVariables) throws RestClientException;
/**
* Execute the HTTP method to the given URI template, writing the given request entity to the request, and
* returns the response as {@link HttpEntity}.
* returns the response as {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given URI variables, if any.
* @param url the URL
* @param method the HTTP method (GET, POST, etc)
@@ -379,12 +380,12 @@ public interface RestOperations {
* @return the response as entity
* @since 3.0.2
*/
<T> HttpEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
<T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
/**
* Execute the HTTP method to the given URI template, writing the given request entity to the request, and
* returns the response as {@link HttpEntity}.
* returns the response as {@link ResponseEntity}.
* @param url the URL
* @param method the HTTP method (GET, POST, etc)
* @param requestEntity the entity (headers and/or body) to write to the request, may be {@code null}
@@ -392,7 +393,7 @@ public interface RestOperations {
* @return the response as entity
* @since 3.0.2
*/
<T> HttpEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
<T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType) throws RestClientException;
// general execution

View File

@@ -29,6 +29,7 @@ import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
@@ -212,26 +213,26 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
return execute(url, HttpMethod.GET, requestCallback, responseExtractor);
}
public <T> HttpEntity<T> getForEntity(String url, Class<T> responseType, Object... urlVariables)
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... urlVariables)
throws RestClientException {
AcceptHeaderRequestCallback requestCallback = new AcceptHeaderRequestCallback(responseType);
HttpEntityResponseExtractor<T> responseExtractor =
new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor =
new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables);
}
public <T> HttpEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> urlVariables)
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> urlVariables)
throws RestClientException {
AcceptHeaderRequestCallback requestCallback = new AcceptHeaderRequestCallback(responseType);
HttpEntityResponseExtractor<T> responseExtractor =
new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor =
new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables);
}
public <T> HttpEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException {
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException {
AcceptHeaderRequestCallback requestCallback = new AcceptHeaderRequestCallback(responseType);
HttpEntityResponseExtractor<T> responseExtractor =
new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor =
new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor);
}
@@ -293,11 +294,11 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
return execute(url, HttpMethod.POST, requestCallback, responseExtractor);
}
public <T> HttpEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
throws RestClientException {
HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(request, responseType);
HttpEntityResponseExtractor<T> responseExtractor =
new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor =
new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
}
@@ -307,15 +308,15 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
Map<String, ?> uriVariables)
throws RestClientException {
HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(request, responseType);
HttpEntityResponseExtractor<T> responseExtractor =
new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor =
new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
}
public <T> HttpEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException {
public <T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException {
HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(request, responseType);
HttpEntityResponseExtractor<T> responseExtractor =
new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor =
new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor);
}
@@ -369,24 +370,24 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
// exchange
public <T> HttpEntity<T> exchange(String url, HttpMethod method,
public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException {
HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(requestEntity, responseType);
HttpEntityResponseExtractor<T> responseExtractor = new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor = new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, method, requestCallback, responseExtractor, uriVariables);
}
public <T> HttpEntity<T> exchange(String url, HttpMethod method,
public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(requestEntity, responseType);
HttpEntityResponseExtractor<T> responseExtractor = new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor = new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, method, requestCallback, responseExtractor, uriVariables);
}
public <T> HttpEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType) throws RestClientException {
HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(requestEntity, responseType);
HttpEntityResponseExtractor<T> responseExtractor = new HttpEntityResponseExtractor<T>(responseType);
ResponseEntityResponseExtractor<T> responseExtractor = new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, method, requestCallback, responseExtractor);
}
@@ -601,11 +602,11 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
/**
* Response extractor for {@link HttpEntity}.
*/
private class HttpEntityResponseExtractor<T> implements ResponseExtractor<HttpEntity<T>> {
private class ResponseEntityResponseExtractor<T> implements ResponseExtractor<ResponseEntity<T>> {
private final HttpMessageConverterExtractor<T> delegate;
public HttpEntityResponseExtractor(Class<T> responseType) {
public ResponseEntityResponseExtractor(Class<T> responseType) {
if (responseType != null) {
this.delegate = new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
} else {
@@ -613,13 +614,13 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
}
}
public HttpEntity<T> extractData(ClientHttpResponse response) throws IOException {
public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
if (delegate != null) {
T body = delegate.extractData(response);
return new HttpEntity<T>(body, response.getHeaders());
return new ResponseEntity<T>(body, response.getHeaders(), response.getStatusCode());
}
else {
return new HttpEntity<T>(response.getHeaders());
return new ResponseEntity<T>(response.getHeaders(), response.getStatusCode());
}
}
}