DATAREST-506 - NotModified responses now return headers, too.
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.
This commit is contained in:
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
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;
|
||||
@@ -132,18 +133,24 @@ class AbstractRepositoryRestController {
|
||||
* @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;
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.core.convert.ConversionService;
|
||||
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;
|
||||
@@ -319,9 +320,10 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
|
||||
|
||||
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
|
||||
@@ -332,7 +334,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,17 @@ public final class ETag {
|
||||
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.
|
||||
@@ -160,17 +171,6 @@ public final class ETag {
|
||||
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
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.rest.webmvc.mongodb;
|
||||
|
||||
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.*;
|
||||
|
||||
@@ -292,10 +293,12 @@ public class MongoWebTests extends CommonWebTests {
|
||||
|
||||
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())));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user