DATAREST-301 - Fixed location header creation for self links containing URI templates.

We now consistently expand the self links created before adding them as location header to make sure we can create a URI instance successfully.
This commit is contained in:
Oliver Gierke
2014-05-06 12:10:55 +02:00
parent fe3c10bead
commit ca3b3bb354
2 changed files with 43 additions and 3 deletions

View File

@@ -19,7 +19,6 @@ import static org.springframework.data.rest.core.support.DomainObjectMerger.Null
import static org.springframework.http.HttpMethod.*;
import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -53,6 +52,7 @@ import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.ResourceSupport;
import org.springframework.hateoas.Resources;
import org.springframework.hateoas.UriTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
@@ -319,7 +319,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
HttpHeaders headers = new HttpHeaders();
if (PUT.equals(httpMethod)) {
headers.setLocation(URI.create(assembler.getSelfLinkFor(obj).getHref()));
addLocationHeader(headers, assembler, obj);
}
if (config.isReturnBodyOnUpdate()) {
@@ -344,10 +344,24 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
publisher.publishEvent(new AfterCreateEvent(savedObject));
HttpHeaders headers = new HttpHeaders();
headers.setLocation(URI.create(assembler.getSelfLinkFor(savedObject).expand().getHref()));
addLocationHeader(headers, assembler, savedObject);
PersistentEntityResource<Object> resource = config.isReturnBodyOnCreate() ? assembler.toResource(savedObject)
: null;
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, headers, resource);
}
/**
* Sets the location header pointing to the resource representing the given instance. Will make sure we properly
* expand the URI template potentially created as self link.
*
* @param headers must not be {@literal null}.
* @param assembler must not be {@literal null}.
* @param source must not be {@literal null}.
*/
private void addLocationHeader(HttpHeaders headers, PersistentEntityResourceAssembler assembler, Object source) {
String selfLink = assembler.getSelfLinkFor(source).getHref();
headers.setLocation(new UriTemplate(selfLink).expand());
}
}

View File

@@ -15,11 +15,19 @@
*/
package org.springframework.data.rest.webmvc;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.jpa.Address;
import org.springframework.data.rest.webmvc.jpa.AddressRepository;
import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig;
import org.springframework.data.rest.webmvc.jpa.Order;
import org.springframework.data.rest.webmvc.jpa.Person;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.HttpRequestMethodNotSupportedException;
@@ -35,6 +43,9 @@ public class RepositoryEntityControllerIntegrationTests extends AbstractControll
@Autowired RepositoryEntityController controller;
@Autowired AddressRepository repository;
@Autowired RepositoryRestConfiguration configuration;
@Autowired PersistentEntityResourceAssembler assembler;
@Autowired PersistentEntities entities;
/**
* @see DATAREST-217
@@ -58,4 +69,19 @@ public class RepositoryEntityControllerIntegrationTests extends AbstractControll
controller.postCollectionResource(request, null, null);
}
/**
* @see DATAREST-301
*/
@Test
public void setsExpandedSelfUriInLocationHeader() throws Exception {
RootResourceInformation information = getResourceInformation(Order.class);
PersistentEntityResource<Object> persistentEntityResource = new PersistentEntityResource<Object>(
entities.getPersistentEntity(Order.class), new Order(new Person()));
ResponseEntity<?> entity = controller.putItemResource(information, persistentEntityResource, 1L, assembler);
assertThat(entity.getHeaders().getLocation().toString(), not(endsWith("{?projection}")));
}
}