Created
May 14, 2014 18:21
-
-
Save philwebb/e416792b93274d7eec70 to your computer and use it in GitHub Desktop.
ResponseEntityBuilder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2002-2014 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 sample; | |
import java.net.URI; | |
import java.util.Set; | |
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; | |
/** | |
* A builder for {@link ResponseEntity} objects. Enforces common HTTP response practices | |
* through a fluent API. | |
* | |
* <p>This class is typically used in @Controller methods through a static import. | |
* For instance: | |
* <pre class="code"> | |
* import static org.springframework.http.ResponseEntityBuilder.*; | |
* | |
* @Controller | |
* public class MyController { | |
* | |
* @RequestMapping(value="/entity", method=RequestMethod.GET) | |
* public ResponseEntity<MyEntity> myBean() { | |
* MyEntity entity = ... | |
* long lastModifiedDate = ... | |
* ResponseEntity<MyEntity> responseEntity = status(HttpStatus.OK) | |
* .header("Last-Modified", lastModifiedDate).body(entity); | |
* return responseEntity; | |
* } | |
* }</pre> | |
* | |
* Or, using some of the convenience methods: | |
* | |
* <pre class="code"> | |
* ok().lastModified(lastModifiedDate).body(entity); | |
* </pre> | |
* | |
* @author Arjen Poutsma | |
* @since 4.1 | |
* @see ResponseEntity | |
*/ | |
public abstract class ResponseEntityBuilder<B extends ResponseEntityBuilder<B>> { | |
private final HttpStatus status; | |
private final HttpHeaders headers = new HttpHeaders(); | |
private Object body = null; | |
protected ResponseEntityBuilder(HttpStatus status) { | |
this.status = status; | |
} | |
/** | |
* Add the given, single header value under the given name. | |
* @param headerName the header name | |
* @param headerValue the header value(s) | |
* @return this builder | |
* @see HttpHeaders#add(String, String) | |
*/ | |
public B header(String headerName, String... headerValues) { | |
for (String headerValue : headerValues) { | |
getHeaders().add(headerName, headerValue); | |
} | |
return thisBuilder(); | |
} | |
/** | |
* Set the set of allowed {@link HttpMethod HTTP methods}, as specified by the | |
* {@code Allow} header. | |
* @param allowedMethods the allowed methods | |
* @return this builder | |
* @see HttpHeaders#setAllow(Set) | |
*/ | |
public B allow(Set<HttpMethod> allowedMethods) { | |
getHeaders().setAllow(allowedMethods); | |
return thisBuilder(); | |
} | |
/** | |
* Sets the entity tag of the body, as specified by the {@code ETag} header. | |
* @param eTag the new entity tag | |
* @return this builder | |
* @see HttpHeaders#setETag(String) | |
*/ | |
public B eTag(String eTag) { | |
getHeaders().setETag(eTag); | |
return thisBuilder(); | |
} | |
/** | |
* Sets the time the resource was last changed, as specified by the {@code | |
* Last-Modified} header. <p>The date should be specified as the number of | |
* milliseconds since January 1, 1970 GMT. | |
* @param lastModified the last modified date | |
* @return this builder | |
* @see HttpHeaders#setLastModified(long) | |
*/ | |
public B lastModified(long lastModified) { | |
getHeaders().setLastModified(lastModified); | |
return thisBuilder(); | |
} | |
/** | |
* Set the location of a resource, as specified by the {@code Location} header. | |
* @param location the location | |
* @return this builder | |
* @see HttpHeaders#setLocation(URI) | |
*/ | |
public B location(URI location) { | |
getHeaders().setLocation(location); | |
return thisBuilder(); | |
} | |
protected final HttpHeaders getHeaders() { | |
// FIXME, should this be public? will users need access to it, have we missed any | |
return headers; | |
} | |
@SuppressWarnings("unchecked") | |
protected final B thisBuilder() { | |
return (B) this; | |
} | |
/** | |
* Builds the response entity without a body. | |
* @return the response entity | |
* @see ResponseEntityBodyBuilder#body(Object) | |
*/ | |
public ResponseEntity<Void> build() { | |
return new ResponseEntity<Void>(null, headers, status); | |
} | |
protected <T> ResponseEntity<T> build(T body) { | |
return new ResponseEntity<T>(body, headers, status); | |
} | |
/** | |
* Defines a builder that adds a body to the response entity. | |
*/ | |
public static class ResponseEntityBodyBuilder | |
extends ResponseEntityBuilder<ResponseEntityBodyBuilder> { | |
protected ResponseEntityBodyBuilder(HttpStatus status) { | |
super(status); | |
} | |
/** | |
* Set the length of the body in bytes, as specified by the {@code Content-Length} | |
* header. | |
* @param contentLength the content length | |
* @return this builder | |
* @see HttpHeaders#setContentLength(long) | |
*/ | |
public ResponseEntityBodyBuilder contentLength(long contentLength) { | |
getHeaders().setContentLength(contentLength); | |
return this; | |
} | |
/** | |
* Set the {@linkplain MediaType media type} of the body, as specified by the | |
* {@code Content-Type} header. | |
* @param contentType the content type | |
* @return this builder | |
* @see HttpHeaders#setContentType(MediaType) | |
*/ | |
public ResponseEntityBodyBuilder contentType(MediaType contentType) { | |
getHeaders().setContentType(contentType); | |
return this; | |
} | |
/** | |
* Sets the body of the response entity and returns it. | |
* @param body the body of the response entity | |
* @param <T> the type of the body | |
* @return the built response entity | |
*/ | |
public <T> ResponseEntity<T> build(T body) { | |
return super.build(body); | |
} | |
} | |
public static class ResponseEntityHeadersBuilder | |
extends ResponseEntityBuilder<ResponseEntityHeadersBuilder> { | |
protected ResponseEntityHeadersBuilder(HttpStatus status) { | |
super(status); | |
} | |
} | |
/** | |
* Creates a new {@code ResponseEntityBuilder} with the given status. | |
* @param status the response status | |
* @return the new response entity builder | |
*/ | |
public static ResponseEntityBodyBuilder status(HttpStatus status) { | |
return new ResponseEntityBodyBuilder(status); | |
} | |
/** | |
* Creates a new {@code ResponseEntityBuilder} with the given status. | |
* @param status the response status | |
* @return the new response entity builder | |
*/ | |
public static ResponseEntityBodyBuilder status(int status) { | |
return status(HttpStatus.valueOf(status)); | |
} | |
/** | |
* Creates a new {@code ResponseEntityBuilder} with the status set to | |
* {@linkplain HttpStatus#OK OK}. | |
* @return the new response entity builder | |
*/ | |
public static ResponseEntityBodyBuilder ok() { | |
return status(HttpStatus.OK); | |
} | |
/** | |
* Creates a new {@code ResponseEntity} with the given body and the status set to | |
* {@linkplain HttpStatus#OK OK}. | |
* @return the new response entity | |
*/ | |
public static <T> ResponseEntity<T> ok(T body) { | |
return ok().build(body); | |
} | |
/** | |
* Creates a new {@code ResponseEntityBuilder} with a | |
* {@linkplain HttpStatus#CREATED CREATED} status and a location header set to the | |
* given URI. | |
* @param location the location URI | |
* @return the new response entity builder | |
*/ | |
public static ResponseEntityBodyBuilder created(URI location) { | |
return status(HttpStatus.CREATED).location(location); | |
} | |
/** | |
* Creates a new {@code ResponseEntityBuilder} with an | |
* {@link HttpStatus#ACCEPTED ACCEPTED} status. | |
* @return the new response entity builder | |
*/ | |
public static ResponseEntityBodyBuilder accepted() { | |
return status(HttpStatus.ACCEPTED); | |
} | |
/** | |
* Creates a new {@code ResponseEntityBuilder} with an | |
* {@link HttpStatus#NO_CONTENT NO_CONTENT} status. | |
* @return the new response entity builder | |
*/ | |
public static ResponseEntityHeadersBuilder noContent() { | |
return new ResponseEntityHeadersBuilder(HttpStatus.NO_CONTENT); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sample; | |
import static sample.ResponseEntityBuilder.ok; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
public class ResponseEntityBuilderUsage { | |
public ResponseEntity<Void> a() { | |
return ok().build(); | |
} | |
public ResponseEntity<?> a2() { | |
return ok().build(); | |
} | |
public ResponseEntity<String> b() { | |
return ok("test"); | |
} | |
public ResponseEntity<String> c() { | |
String body = ""; | |
return ok().contentType(MediaType.APPLICATION_JSON).build(body); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment