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

@ -61,12 +61,14 @@ import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.ui.ExtendedModelMap;
@ -895,6 +897,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
}
HttpInputMessage inputMessage = createHttpInputMessage(webRequest);
HttpOutputMessage outputMessage = createHttpOutputMessage(webRequest);
if (responseEntity instanceof ResponseEntity && outputMessage instanceof ServerHttpResponse) {
((ServerHttpResponse)outputMessage).setStatusCode(((ResponseEntity) responseEntity).getStatusCode());
}
HttpHeaders entityHeaders = responseEntity.getHeaders();
if (!entityHeaders.isEmpty()) {
outputMessage.getHeaders().putAll(entityHeaders);

View File

@ -75,6 +75,7 @@ import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
@ -1201,7 +1202,7 @@ public class ServletAnnotationControllerTests {
request.addHeader("MyRequestHeader", "MyValue");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals(200, response.getStatus());
assertEquals(201, response.getStatus());
assertEquals(requestBody, response.getContentAsString());
assertEquals("MyValue", response.getHeader("MyResponseHeader"));
}
@ -2598,7 +2599,7 @@ public class ServletAnnotationControllerTests {
public static class HttpEntityController {
@RequestMapping("/handle")
public HttpEntity<String> handle(HttpEntity<byte[]> requestEntity) throws UnsupportedEncodingException {
public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntity) throws UnsupportedEncodingException {
assertNotNull(requestEntity);
assertEquals("MyValue", requestEntity.getHeaders().getFirst("MyRequestHeader"));
String requestBody = new String(requestEntity.getBody(), "UTF-8");
@ -2606,7 +2607,7 @@ public class ServletAnnotationControllerTests {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new HttpEntity<String>(requestBody, responseHeaders);
return new ResponseEntity<String>(requestBody, responseHeaders, HttpStatus.CREATED);
}
}

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());
}
}
}

View File

@ -16,9 +16,6 @@
package org.springframework.http;
import java.util.LinkedHashMap;
import java.util.Map;
import static org.junit.Assert.*;
import org.junit.Test;
@ -39,10 +36,13 @@ public class HttpEntityTests {
}
@Test
public void contentType() {
MediaType contentType = MediaType.TEXT_PLAIN;
HttpEntity<String> entity = new HttpEntity<String>("foo", contentType);
assertEquals(contentType, entity.getHeaders().getContentType());
public void httpHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
String body = "foo";
HttpEntity<String> entity = new HttpEntity<String>(body, headers);
assertEquals(body, entity.getBody());
assertEquals(MediaType.TEXT_PLAIN, entity.getHeaders().getContentType());
assertEquals("text/plain", entity.getHeaders().getFirst("Content-Type"));
}
@ -50,18 +50,24 @@ public class HttpEntityTests {
public void multiValueMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.set("Content-Type", "text/plain");
HttpEntity<String> entity = new HttpEntity<String>("foo", map);
String body = "foo";
HttpEntity<String> entity = new HttpEntity<String>(body, map);
assertEquals(body, entity.getBody());
assertEquals(MediaType.TEXT_PLAIN, entity.getHeaders().getContentType());
assertEquals("text/plain", entity.getHeaders().getFirst("Content-Type"));
}
@Test
public void map() {
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("Content-Type", "text/plain");
HttpEntity<String> entity = new HttpEntity<String>("foo", map);
public void responseEntity() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
String body = "foo";
ResponseEntity<String> entity = new ResponseEntity<String>(body, headers, HttpStatus.OK);
assertEquals(body, entity.getBody());
assertEquals(MediaType.TEXT_PLAIN, entity.getHeaders().getContentType());
assertEquals("text/plain", entity.getHeaders().getFirst("Content-Type"));
assertEquals("text/plain", entity.getHeaders().getFirst("Content-Type"));
}
}

View File

@ -37,6 +37,7 @@ import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.MockHttpInputMessage;
import org.springframework.http.MockHttpOutputMessage;
@ -109,7 +110,9 @@ public class FormHttpMessageConverterTests {
Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg");
parts.add("logo", logo);
Source xml = new StreamSource(new StringReader("<root><child/></root>"));
HttpEntity<Source> entity = new HttpEntity<Source>(xml, MediaType.TEXT_XML);
HttpHeaders entityHeaders = new HttpHeaders();
entityHeaders.setContentType(MediaType.TEXT_XML);
HttpEntity<Source> entity = new HttpEntity<Source>(xml, entityHeaders);
parts.add("xml", entity);
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();

View File

@ -52,7 +52,9 @@ import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.CommonsClientHttpRequestFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
@ -109,10 +111,11 @@ public class RestTemplateIntegrationTests {
@Test
public void getEntity() {
HttpEntity<String> entity = template.getForEntity(URI + "/{method}", String.class, "get");
ResponseEntity<String> entity = template.getForEntity(URI + "/{method}", String.class, "get");
assertEquals("Invalid content", helloWorld, entity.getBody());
assertFalse("No headers", entity.getHeaders().isEmpty());
assertEquals("Invalid content-type", contentType, entity.getHeaders().getContentType());
assertEquals("Invalid status code", HttpStatus.OK, entity.getStatusCode());
}
@Test
@ -129,7 +132,9 @@ public class RestTemplateIntegrationTests {
@Test
public void postForLocationEntity() throws URISyntaxException {
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, new MediaType("text", "plain", Charset.forName("ISO-8859-15")));
HttpHeaders entityHeaders = new HttpHeaders();
entityHeaders.setContentType(new MediaType("text", "plain", Charset.forName("ISO-8859-15")));
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, entityHeaders);
URI location = template.postForLocation(URI + "/{method}", entity, "post");
assertEquals("Invalid location", new URI(URI + "/post/1"), location);
}
@ -183,7 +188,7 @@ public class RestTemplateIntegrationTests {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("MyHeader", "MyValue");
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
HttpEntity<String> response =
ResponseEntity<String> response =
template.exchange(URI + "/{method}", HttpMethod.GET, requestEntity, String.class, "get");
assertEquals("Invalid content", helloWorld, response.getBody());
}

View File

@ -33,6 +33,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
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;
@ -194,14 +195,16 @@ public class RestTemplateTests {
expect(converter.canRead(String.class, textPlain)).andReturn(true);
String expected = "Hello World";
expect(converter.read(String.class, response)).andReturn(expected);
expect(response.getStatusCode()).andReturn(HttpStatus.OK);
response.close();
replayMocks();
HttpEntity<String> result = template.getForEntity("http://example.com", String.class);
ResponseEntity<String> result = template.getForEntity("http://example.com", String.class);
assertEquals("Invalid GET result", expected, result.getBody());
assertEquals("Invalid Accept header", textPlain.toString(), requestHeaders.getFirst("Accept"));
assertEquals("Invalid Content-Type header", textPlain, result.getHeaders().getContentType());
assertEquals("Invalid status code", HttpStatus.OK, result.getStatusCode());
verifyMocks();
}
@ -265,7 +268,9 @@ public class RestTemplateTests {
replayMocks();
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, contentType);
HttpHeaders entityHeaders = new HttpHeaders();
entityHeaders.setContentType(contentType);
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, entityHeaders);
URI result = template.postForLocation("http://example.com", entity);
assertEquals("Invalid POST result", expected, result);
@ -291,7 +296,9 @@ public class RestTemplateTests {
replayMocks();
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, Collections.singletonMap("MyHeader", "MyValue"));
HttpHeaders entityHeaders = new HttpHeaders();
entityHeaders.set("MyHeader", "MyValue");
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, entityHeaders);
URI result = template.postForLocation("http://example.com", entity);
assertEquals("Invalid POST result", expected, result);
@ -387,14 +394,16 @@ public class RestTemplateTests {
Integer expected = 42;
expect(converter.canRead(Integer.class, textPlain)).andReturn(true);
expect(converter.read(Integer.class, response)).andReturn(expected);
expect(response.getStatusCode()).andReturn(HttpStatus.OK);
response.close();
replayMocks();
HttpEntity<Integer> result = template.postForEntity("http://example.com", request, Integer.class);
ResponseEntity<Integer> result = template.postForEntity("http://example.com", request, Integer.class);
assertEquals("Invalid POST result", expected, result.getBody());
assertEquals("Invalid Content-Type", textPlain, result.getHeaders().getContentType());
assertEquals("Invalid Accept header", textPlain.toString(), requestHeaders.getFirst("Accept"));
assertEquals("Invalid status code", HttpStatus.OK, result.getStatusCode());
verifyMocks();
}
@ -439,13 +448,15 @@ public class RestTemplateTests {
expect(response.getHeaders()).andReturn(responseHeaders).times(2);
expect(converter.canRead(Integer.class, textPlain)).andReturn(true);
expect(converter.read(Integer.class, response)).andReturn(null);
expect(response.getStatusCode()).andReturn(HttpStatus.OK);
response.close();
replayMocks();
HttpEntity<Integer> result = template.postForEntity("http://example.com", null, Integer.class);
ResponseEntity<Integer> result = template.postForEntity("http://example.com", null, Integer.class);
assertFalse("Invalid POST result", result.hasBody());
assertEquals("Invalid Content-Type", textPlain, result.getHeaders().getContentType());
assertEquals("Invalid content length", 0, requestHeaders.getContentLength());
assertEquals("Invalid status code", HttpStatus.OK, result.getStatusCode());
verifyMocks();
}
@ -557,16 +568,20 @@ public class RestTemplateTests {
Integer expected = 42;
expect(converter.canRead(Integer.class, textPlain)).andReturn(true);
expect(converter.read(Integer.class, response)).andReturn(expected);
expect(response.getStatusCode()).andReturn(HttpStatus.OK);
response.close();
replayMocks();
HttpEntity<String> requestEntity = new HttpEntity<String>(body, Collections.singletonMap("MyHeader", "MyValue"));
HttpEntity<Integer> result = template.exchange("http://example.com", HttpMethod.POST, requestEntity, Integer.class);
HttpHeaders entityHeaders = new HttpHeaders();
entityHeaders.set("MyHeader", "MyValue");
HttpEntity<String> requestEntity = new HttpEntity<String>(body, entityHeaders);
ResponseEntity<Integer> result = template.exchange("http://example.com", HttpMethod.POST, requestEntity, Integer.class);
assertEquals("Invalid POST result", expected, result.getBody());
assertEquals("Invalid Content-Type", textPlain, result.getHeaders().getContentType());
assertEquals("Invalid Accept header", textPlain.toString(), requestHeaders.getFirst("Accept"));
assertEquals("Invalid custom header", "MyValue", requestHeaders.getFirst("MyHeader"));
assertEquals("Invalid status code", HttpStatus.OK, result.getStatusCode());
verifyMocks();
}

View File

@ -218,6 +218,17 @@
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.apache.commons/com.springsource.org.apache.commons.io/1.4.0/com.springsource.org.apache.commons.io-1.4.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.apache.commons/com.springsource.org.apache.commons.io/1.4.0/com.springsource.org.apache.commons.io-sources-1.4.0.jar!/" />
</SOURCES>
</library>
</orderEntry>
</component>
<component name="copyright">
<Base>

View File

@ -1154,7 +1154,8 @@ public class RelativePathUriTemplateController {
</listitem>
<listitem>
<para>A <classname>HttpEntity&lt;?&gt;</classname>} object
<para>A <classname>HttpEntity&lt;?&gt;</classname> or
<classname>ResponseEntity&lt;?&gt;</classname> object
to access to the Servlet reponse HTTP headers and contents. The entity body will
be converted to the response stream using
<interfacename>HttpMessageConverter</interfacename>s. See <xref
@ -1328,24 +1329,25 @@ public String helloWorld() {
<para>The <classname>HttpEntity</classname> is similar to
<interfacename>@RequestBody</interfacename> and
<interfacename>@ResponseBody</interfacename>. Besides getting
access to the request and response body, the <classname>HttpEntity</classname>
access to the request and response body, <classname>HttpEntity</classname>
(and the response-specific subclass <classname>ResponseEntity</classname>)
also allows access to the request and response headers, like so:</para>
<programlisting language="java">@RequestMapping("/something")
public HttpEntity&lt;String&gt; handle(HttpEntity&lt;byte[]&gt; requestEntity) throws UnsupportedEncodingException {
public ResponseEntity&lt;String&gt; handle(HttpEntity&lt;byte[]&gt; requestEntity) throws UnsupportedEncodingException {
String requestHeader = requestEntity.getHeaders().getFirst("MyRequestHeader"));
byte[] requestBody = requestEntity.getBody();
// do something with request header and body
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new HttpEntity&lt;String&gt;("Hello World", responseHeaders);
return new ResponseEntity&lt;String&gt;("Hello World", responseHeaders, HttpStatus.CREATED);
}</programlisting>
<para>The above example gets the value of the "MyRequestHeader" request
header, and reads the body as a byte array. It adds the "MyResponseHeader"
to the response, and writes <literal>Hello World</literal> to the response
stream.</para>
to the response, writes <literal>Hello World</literal> to the response
stream, and sets the response status code to 201 (Created).</para>
<para>As with <interfacename>@RequestBody</interfacename> and
<interfacename>@ResponseBody</interfacename>, Spring