ResponseEntity allows for setting non-standard status code
Issue: SPR-14205
This commit is contained in:
parent
e5d52a96a7
commit
d06188ed4d
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
|
@ -392,17 +392,17 @@ public enum HttpStatus {
|
|||
NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");
|
||||
|
||||
|
||||
|
||||
private final int value;
|
||||
|
||||
private final String reasonPhrase;
|
||||
|
||||
|
||||
private HttpStatus(int value, String reasonPhrase) {
|
||||
HttpStatus(int value, String reasonPhrase) {
|
||||
this.value = value;
|
||||
this.reasonPhrase = reasonPhrase;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the integer value of this status code.
|
||||
*/
|
||||
|
|
@ -414,7 +414,7 @@ public enum HttpStatus {
|
|||
* Return the reason phrase of this status code.
|
||||
*/
|
||||
public String getReasonPhrase() {
|
||||
return reasonPhrase;
|
||||
return this.reasonPhrase;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -423,7 +423,7 @@ public enum HttpStatus {
|
|||
* This is a shortcut for checking the value of {@link #series()}.
|
||||
*/
|
||||
public boolean is1xxInformational() {
|
||||
return (Series.INFORMATIONAL.equals(series()));
|
||||
return Series.INFORMATIONAL.equals(series());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -432,7 +432,7 @@ public enum HttpStatus {
|
|||
* This is a shortcut for checking the value of {@link #series()}.
|
||||
*/
|
||||
public boolean is2xxSuccessful() {
|
||||
return (Series.SUCCESSFUL.equals(series()));
|
||||
return Series.SUCCESSFUL.equals(series());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -441,7 +441,7 @@ public enum HttpStatus {
|
|||
* This is a shortcut for checking the value of {@link #series()}.
|
||||
*/
|
||||
public boolean is3xxRedirection() {
|
||||
return (Series.REDIRECTION.equals(series()));
|
||||
return Series.REDIRECTION.equals(series());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -451,7 +451,7 @@ public enum HttpStatus {
|
|||
* This is a shortcut for checking the value of {@link #series()}.
|
||||
*/
|
||||
public boolean is4xxClientError() {
|
||||
return (Series.CLIENT_ERROR.equals(series()));
|
||||
return Series.CLIENT_ERROR.equals(series());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -460,7 +460,7 @@ public enum HttpStatus {
|
|||
* This is a shortcut for checking the value of {@link #series()}.
|
||||
*/
|
||||
public boolean is5xxServerError() {
|
||||
return (Series.SERVER_ERROR.equals(series()));
|
||||
return Series.SERVER_ERROR.equals(series());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -476,7 +476,7 @@ public enum HttpStatus {
|
|||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Integer.toString(value);
|
||||
return Integer.toString(this.value);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -497,10 +497,10 @@ public enum HttpStatus {
|
|||
|
||||
|
||||
/**
|
||||
* Java 5 enumeration of HTTP status series.
|
||||
* Enumeration of HTTP status series.
|
||||
* <p>Retrievable via {@link HttpStatus#series()}.
|
||||
*/
|
||||
public static enum Series {
|
||||
public enum Series {
|
||||
|
||||
INFORMATIONAL(1),
|
||||
SUCCESSFUL(2),
|
||||
|
|
@ -510,7 +510,7 @@ public enum HttpStatus {
|
|||
|
||||
private final int value;
|
||||
|
||||
private Series(int value) {
|
||||
Series(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
|
@ -534,7 +534,6 @@ public enum HttpStatus {
|
|||
public static Series valueOf(HttpStatus status) {
|
||||
return valueOf(status.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
|
@ -21,6 +21,7 @@ import java.util.Arrays;
|
|||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
|
|
@ -65,45 +66,55 @@ import org.springframework.util.ObjectUtils;
|
|||
*/
|
||||
public class ResponseEntity<T> extends HttpEntity<T> {
|
||||
|
||||
private final HttpStatus statusCode;
|
||||
private final Object statusCode;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code ResponseEntity} with the given status code, and no body nor headers.
|
||||
* @param statusCode the status code
|
||||
* @param status the status code
|
||||
*/
|
||||
public ResponseEntity(HttpStatus statusCode) {
|
||||
super();
|
||||
this.statusCode = statusCode;
|
||||
public ResponseEntity(HttpStatus status) {
|
||||
this(null, null, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param status the status code
|
||||
*/
|
||||
public ResponseEntity(T body, HttpStatus statusCode) {
|
||||
super(body);
|
||||
this.statusCode = statusCode;
|
||||
public ResponseEntity(T body, HttpStatus status) {
|
||||
this(body, null, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param status the status code
|
||||
*/
|
||||
public ResponseEntity(MultiValueMap<String, String> headers, HttpStatus statusCode) {
|
||||
super(headers);
|
||||
this.statusCode = statusCode;
|
||||
public ResponseEntity(MultiValueMap<String, String> headers, HttpStatus status) {
|
||||
this(null, headers, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param status the status code
|
||||
*/
|
||||
public ResponseEntity(T body, MultiValueMap<String, String> headers, HttpStatus statusCode) {
|
||||
public ResponseEntity(T body, MultiValueMap<String, String> headers, HttpStatus status) {
|
||||
super(body, headers);
|
||||
Assert.notNull(status, "HttpStatus must not be null");
|
||||
this.statusCode = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code HttpEntity} with the given body, headers, and status code.
|
||||
* Just used behind the nested builder API.
|
||||
* @param body the entity body
|
||||
* @param headers the entity headers
|
||||
* @param statusCode the status code (as {@code HttpStatus} or as {@code Integer} value)
|
||||
*/
|
||||
private ResponseEntity(T body, MultiValueMap<String, String> headers, Object statusCode) {
|
||||
super(body, headers);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
|
@ -111,10 +122,29 @@ public class ResponseEntity<T> extends HttpEntity<T> {
|
|||
|
||||
/**
|
||||
* Return the HTTP status code of the response.
|
||||
* @return the HTTP status as an HttpStatus enum value
|
||||
* @return the HTTP status as an HttpStatus enum entry
|
||||
*/
|
||||
public HttpStatus getStatusCode() {
|
||||
return this.statusCode;
|
||||
if (this.statusCode instanceof HttpStatus) {
|
||||
return (HttpStatus) this.statusCode;
|
||||
}
|
||||
else {
|
||||
return HttpStatus.valueOf((Integer) this.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the HTTP status code of the response.
|
||||
* @return the HTTP status as an int value
|
||||
* @since 4.3
|
||||
*/
|
||||
public int getStatusCodeValue() {
|
||||
if (this.statusCode instanceof HttpStatus) {
|
||||
return ((HttpStatus) this.statusCode).value();
|
||||
}
|
||||
else {
|
||||
return (Integer) this.statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -139,8 +169,10 @@ public class ResponseEntity<T> extends HttpEntity<T> {
|
|||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(this.statusCode.toString());
|
||||
builder.append(' ');
|
||||
builder.append(this.statusCode.getReasonPhrase());
|
||||
if (this.statusCode instanceof HttpStatus) {
|
||||
builder.append(' ');
|
||||
builder.append(((HttpStatus) this.statusCode).getReasonPhrase());
|
||||
}
|
||||
builder.append(',');
|
||||
T body = getBody();
|
||||
HttpHeaders headers = getHeaders();
|
||||
|
|
@ -167,6 +199,7 @@ public class ResponseEntity<T> extends HttpEntity<T> {
|
|||
* @since 4.1
|
||||
*/
|
||||
public static BodyBuilder status(HttpStatus status) {
|
||||
Assert.notNull(status, "HttpStatus must not be null");
|
||||
return new DefaultBuilder(status);
|
||||
}
|
||||
|
||||
|
|
@ -177,7 +210,7 @@ public class ResponseEntity<T> extends HttpEntity<T> {
|
|||
* @since 4.1
|
||||
*/
|
||||
public static BodyBuilder status(int status) {
|
||||
return status(HttpStatus.valueOf(status));
|
||||
return new DefaultBuilder(status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -388,12 +421,12 @@ public class ResponseEntity<T> extends HttpEntity<T> {
|
|||
|
||||
private static class DefaultBuilder implements BodyBuilder {
|
||||
|
||||
private final HttpStatus status;
|
||||
private final Object statusCode;
|
||||
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
public DefaultBuilder(HttpStatus status) {
|
||||
this.status = status;
|
||||
public DefaultBuilder(Object statusCode) {
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -473,12 +506,12 @@ public class ResponseEntity<T> extends HttpEntity<T> {
|
|||
|
||||
@Override
|
||||
public ResponseEntity<Void> build() {
|
||||
return new ResponseEntity<Void>(null, this.headers, this.status);
|
||||
return body(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ResponseEntity<T> body(T body) {
|
||||
return new ResponseEntity<T>(body, this.headers, this.status);
|
||||
return new ResponseEntity<T>(body, this.headers, this.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
|
@ -73,6 +73,7 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
|||
|
||||
@Override
|
||||
public void setStatusCode(HttpStatus status) {
|
||||
Assert.notNull(status, "HttpStatus must not be null");
|
||||
this.servletResponse.setStatus(status.value());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
|
@ -252,4 +252,22 @@ public class ResponseEntityTests {
|
|||
assertThat(cacheControlHeader, Matchers.equalTo("no-store"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void statusCodeAsInt() {
|
||||
Integer entity = new Integer(42);
|
||||
ResponseEntity<Integer> responseEntity = ResponseEntity.status(200).body(entity);
|
||||
|
||||
assertEquals(200, responseEntity.getStatusCode().value());
|
||||
assertEquals(entity, responseEntity.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customStatusCode() {
|
||||
Integer entity = new Integer(42);
|
||||
ResponseEntity<Integer> responseEntity = ResponseEntity.status(299).body(entity);
|
||||
|
||||
assertEquals(299, responseEntity.getStatusCodeValue());
|
||||
assertEquals(entity, responseEntity.getBody());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,9 +184,8 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
|||
}
|
||||
}
|
||||
|
||||
Object body = responseEntity.getBody();
|
||||
if (responseEntity instanceof ResponseEntity) {
|
||||
outputMessage.setStatusCode(((ResponseEntity<?>) responseEntity).getStatusCode());
|
||||
outputMessage.getServletResponse().setStatus(((ResponseEntity<?>) responseEntity).getStatusCodeValue());
|
||||
HttpMethod method = inputMessage.getMethod();
|
||||
boolean isGetOrHead = (HttpMethod.GET == method || HttpMethod.HEAD == method);
|
||||
if (isGetOrHead && isResourceNotModified(inputMessage, outputMessage)) {
|
||||
|
|
@ -197,6 +196,8 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Object body = responseEntity.getBody();
|
||||
if (inputMessage.getHeaders().containsKey(HttpHeaders.RANGE) &&
|
||||
Resource.class.isAssignableFrom(body.getClass())) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -130,9 +130,9 @@ public class ResponseBodyEmitterReturnValueHandler implements AsyncHandlerMethod
|
|||
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
|
||||
ServerHttpResponse outputMessage = new ServletServerHttpResponse(response);
|
||||
|
||||
if (ResponseEntity.class.isAssignableFrom(returnValue.getClass())) {
|
||||
if (returnValue instanceof ResponseEntity) {
|
||||
ResponseEntity<?> responseEntity = (ResponseEntity<?>) returnValue;
|
||||
outputMessage.setStatusCode(responseEntity.getStatusCode());
|
||||
response.setStatus(responseEntity.getStatusCodeValue());
|
||||
outputMessage.getHeaders().putAll(responseEntity.getHeaders());
|
||||
returnValue = responseEntity.getBody();
|
||||
if (returnValue == null) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
|
@ -13,11 +13,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
|
@ -33,7 +33,6 @@ import org.springframework.web.filter.ShallowEtagHeaderFilter;
|
|||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
|
||||
/**
|
||||
* Supports return values of type
|
||||
* {@link org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody}
|
||||
|
|
@ -68,11 +67,10 @@ public class StreamingResponseBodyReturnValueHandler implements HandlerMethodRet
|
|||
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
|
||||
ServerHttpResponse outputMessage = new ServletServerHttpResponse(response);
|
||||
|
||||
if (ResponseEntity.class.isAssignableFrom(returnValue.getClass())) {
|
||||
if (returnValue instanceof ResponseEntity) {
|
||||
ResponseEntity<?> responseEntity = (ResponseEntity<?>) returnValue;
|
||||
outputMessage.setStatusCode(responseEntity.getStatusCode());
|
||||
response.setStatus(responseEntity.getStatusCodeValue());
|
||||
outputMessage.getHeaders().putAll(responseEntity.getHeaders());
|
||||
|
||||
returnValue = responseEntity.getBody();
|
||||
if (returnValue == null) {
|
||||
mavContainer.setRequestHandled(true);
|
||||
|
|
@ -97,7 +95,6 @@ public class StreamingResponseBodyReturnValueHandler implements HandlerMethodRet
|
|||
|
||||
private final StreamingResponseBody streamingBody;
|
||||
|
||||
|
||||
public StreamingResponseBodyTask(OutputStream outputStream, StreamingResponseBody streamingBody) {
|
||||
this.outputStream = outputStream;
|
||||
this.streamingBody = streamingBody;
|
||||
|
|
|
|||
Loading…
Reference in New Issue