Skip to content

Commit

Permalink
DATAREST-506 - NotModified responses now return headers, too.
Browse files Browse the repository at this point in the history
Responses for item resources that result in 304 Not Modifier now also return the headers they'd return if a 200 Ok would've been returned.
  • Loading branch information
odrotbohm committed Apr 12, 2015
1 parent 7264746 commit bb93323
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.springframework.data.auditing.AuditableBeanWrapper;
import org.springframework.data.auditing.AuditableBeanWrapperFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.rest.core.mapping.ResourceMetadata;
import org.springframework.data.rest.webmvc.support.ETag;
import org.springframework.data.web.PagedResourcesAssembler;
Expand Down Expand Up @@ -132,18 +133,24 @@ protected Resources<Resource<Object>> entitiesToResources(Iterable<Object> entit
* @return
*/
protected HttpHeaders prepareHeaders(PersistentEntityResource resource) {
return resource == null ? new HttpHeaders() : prepareHeaders(resource.getPersistentEntity(), resource.getContent());
}

HttpHeaders headers = new HttpHeaders();

if (resource == null) {
return headers;
}
/**
* Retruns the default headers to be returned for the given {@link PersistentEntity} and value. Will set {@link ETag}
* and {@code Last-Modified} headers if applicable.
*
* @param entity must not be {@literal null}.
* @param value must not be {@literal null}.
* @return
*/
protected HttpHeaders prepareHeaders(PersistentEntity<?, ?> entity, Object value) {

// Add ETag
headers = ETag.from(resource).addTo(headers);
HttpHeaders headers = ETag.from(entity, value).addTo(new HttpHeaders());

// Add Last-Modified
AuditableBeanWrapper wrapper = getAuditableBeanWrapper(resource.getContent());
AuditableBeanWrapper wrapper = getAuditableBeanWrapper(value);

if (wrapper == null) {
return headers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.springframework.data.auditing.AuditableBeanWrapper;
import org.springframework.data.auditing.AuditableBeanWrapperFactory;
import org.springframework.data.domain.Sort;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
import org.springframework.data.repository.support.Repositories;
Expand Down Expand Up @@ -319,9 +320,10 @@ public ResponseEntity<Resource<?>> getItemResource(RootResourceInformation resou

List<String> ifNoneMatch = headers.getIfNoneMatch();
ETag eTag = ifNoneMatch.isEmpty() ? ETag.NO_ETAG : ETag.from(ifNoneMatch.get(0));
PersistentEntity<?, ?> entity = resourceInformation.getPersistentEntity();

if (eTag.matches(resourceInformation.getPersistentEntity(), domainObj)) {
return new ResponseEntity<Resource<?>>(HttpStatus.NOT_MODIFIED);
if (eTag.matches(entity, domainObj)) {
return new ResponseEntity<Resource<?>>(prepareHeaders(entity, domainObj), HttpStatus.NOT_MODIFIED);
}

// Check last modification for If-Modfied-Since
Expand All @@ -332,7 +334,7 @@ public ResponseEntity<Resource<?>> getItemResource(RootResourceInformation resou
long current = wrapper.getLastModifiedDate().getTimeInMillis() / 1000 * 1000;

if (current <= headers.getIfModifiedSince()) {
return new ResponseEntity<Resource<?>>(HttpStatus.NOT_MODIFIED);
return new ResponseEntity<Resource<?>>(prepareHeaders(entity, domainObj), HttpStatus.NOT_MODIFIED);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ public static ETag from(PersistentEntityResource resource) {
return resource == null ? NO_ETAG : from(resource.getPersistentEntity(), resource.getContent());
}

/**
* Creates a new {@link ETag} from the given {@link PersistentEntity} and target bean.
*
* @param entity must not be {@literal null}.
* @param bean must not be {@literal null}.
* @return
*/
public static ETag from(PersistentEntity<?, ?> entity, Object bean) {
return from(getVersionInformation(entity, bean));
}

/**
* Verifies the ETag to be created for the given target bean with the current one and raises a
* {@link ETagDoesntMatchException} in case they don't match.
Expand Down Expand Up @@ -160,17 +171,6 @@ public int hashCode() {
return value.hashCode();
}

/**
* Creates a new {@link ETag} from the given {@link PersistentEntity} and target bean.
*
* @param entity
* @param bean
* @return
*/
private static ETag from(PersistentEntity<?, ?> entity, Object bean) {
return from(getVersionInformation(entity, bean));
}

/**
* Returns the quoted version property of a domain object, returns null if it doesn't contains the property
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.http.HttpHeaders.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

Expand Down Expand Up @@ -292,10 +293,12 @@ public void supportsConditionalGetsOnItemResource() throws Exception {

Link receiptLink = client.getDiscoverer(response).findLinkWithRel("self", response.getContentAsString());

mvc.perform(get(receiptLink.getHref()).header("If-Modified-Since", response.getHeader("Last-Modified"))).//
andExpect(status().isNotModified());
mvc.perform(get(receiptLink.getHref()).header(IF_MODIFIED_SINCE, response.getHeader(LAST_MODIFIED))).//
andExpect(status().isNotModified()).//
andExpect(header().string(ETAG, is(notNullValue())));

mvc.perform(get(receiptLink.getHref()).header("If-None-Match", response.getHeader("ETag"))).//
andExpect(status().isNotModified());
mvc.perform(get(receiptLink.getHref()).header(IF_NONE_MATCH, response.getHeader(ETAG))).//
andExpect(status().isNotModified()).//
andExpect(header().string(ETAG, is(notNullValue())));
}
}

0 comments on commit bb93323

Please sign in to comment.