further HATEOAS work
This commit is contained in:
parent
00ef9f688c
commit
71122adb3e
|
@ -6,6 +6,8 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Spring Security Expressions - hasRole Example](http://www.baeldung.com/spring-security-expressions-basic)
|
- [Spring Security Expressions - hasRole Example](http://www.baeldung.com/spring-security-expressions-basic)
|
||||||
- [REST Pagination in Spring](http://www.baeldung.com/2012/01/18/rest-pagination-in-spring/)
|
- [REST Pagination in Spring](http://www.baeldung.com/2012/01/18/rest-pagination-in-spring/)
|
||||||
|
- [HATEOAS for a Spring REST Service](http://www.baeldung.com/2011/11/13/rest-service-discoverability-with-spring-part-5/)
|
||||||
|
- [REST API Discoverability and HATEOAS](2011/11/06/restful-web-service-discoverability-part-4/)
|
||||||
|
|
||||||
|
|
||||||
### Build the Project
|
### Build the Project
|
||||||
|
|
|
@ -48,8 +48,9 @@ public class FooController {
|
||||||
|
|
||||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
|
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Foo findOne(@PathVariable("id") final Long id, final UriComponentsBuilder uriBuilder, final HttpServletRequest request, final HttpServletResponse response) {
|
public Foo findById(@PathVariable("id") final Long id, final HttpServletRequest request, final HttpServletResponse response) {
|
||||||
final Foo resourceById = RestPreconditions.checkFound(service.findOne(id));
|
final Foo resourceById = RestPreconditions.checkFound(service.findOne(id));
|
||||||
|
|
||||||
eventPublisher.publishEvent(new SingleResourceRetrieved(this, request, response));
|
eventPublisher.publishEvent(new SingleResourceRetrieved(this, request, response));
|
||||||
return resourceById;
|
return resourceById;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.baeldung.web.hateoas;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
public class ResourceCreated extends ApplicationEvent {
|
||||||
|
private final HttpServletResponse response;
|
||||||
|
private final HttpServletRequest request;
|
||||||
|
private final long idOfNewResource;
|
||||||
|
|
||||||
|
public ResourceCreated(final Object source, final HttpServletRequest request, final HttpServletResponse response, final long idOfNewResource) {
|
||||||
|
super(source);
|
||||||
|
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
this.idOfNewResource = idOfNewResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpServletResponse getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpServletRequest getRequest() {
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getIdOfNewResource() {
|
||||||
|
return idOfNewResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.baeldung.web.hateoas;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
public class SingleResourceRetrieved extends ApplicationEvent {
|
||||||
|
private final HttpServletResponse response;
|
||||||
|
private final HttpServletRequest request;
|
||||||
|
|
||||||
|
public SingleResourceRetrieved(final Object source, final HttpServletRequest request, final HttpServletResponse response) {
|
||||||
|
super(source);
|
||||||
|
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpServletResponse getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpServletRequest getRequest() {
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.net.HttpHeaders;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class SingleResourceRetrievedDiscoverabilityListener implements ApplicationListener<SingleResourceRetrieved> {
|
class SingleResourceRetrievedDiscoverabilityListener implements ApplicationListener<SingleResourceRetrieved> {
|
||||||
|
@ -26,7 +27,7 @@ class SingleResourceRetrievedDiscoverabilityListener implements ApplicationListe
|
||||||
final String uriForResourceCreation = requestURL.substring(0, positionOfLastSlash);
|
final String uriForResourceCreation = requestURL.substring(0, positionOfLastSlash);
|
||||||
|
|
||||||
final String linkHeaderValue = LinkUtil.createLinkHeader(uriForResourceCreation, "collection");
|
final String linkHeaderValue = LinkUtil.createLinkHeader(uriForResourceCreation, "collection");
|
||||||
response.addHeader("Link", linkHeaderValue);
|
response.addHeader(HttpHeaders.LINK, linkHeaderValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ package org.baeldung.common.web;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
|
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
|
||||||
import static org.baeldung.web.util.HTTPLinkHeaderUtil.extractURIByRel;
|
import static org.baeldung.web.util.HTTPLinkHeaderUtil.extractURIByRel;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
@ -12,6 +13,7 @@ import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.baeldung.test.IMarshaller;
|
import org.baeldung.test.IMarshaller;
|
||||||
|
import org.hamcrest.core.AnyOf;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
@ -36,6 +38,18 @@ public abstract class AbstractLiveTest<T extends Serializable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests
|
// tests
|
||||||
|
@Test
|
||||||
|
public void whenInvalidPOSTIsSentToValidURIOfResource_thenAllowHeaderListsTheAllowedActions() {
|
||||||
|
// Given
|
||||||
|
final String uriOfExistingResource = createAsUri();
|
||||||
|
|
||||||
|
// When
|
||||||
|
final Response res = givenAuth().post(uriOfExistingResource);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
final String allowHeader = res.getHeader(HttpHeaders.ALLOW);
|
||||||
|
assertThat(allowHeader, AnyOf.<String> anyOf(containsString("GET"), containsString("PUT"), containsString("DELETE")));
|
||||||
|
}
|
||||||
|
|
||||||
// find - one
|
// find - one
|
||||||
|
|
||||||
|
@ -111,11 +125,13 @@ public abstract class AbstractLiveTest<T extends Serializable> {
|
||||||
|
|
||||||
public abstract void create();
|
public abstract void create();
|
||||||
|
|
||||||
|
public abstract String createAsUri();
|
||||||
|
|
||||||
protected final void create(final T resource) {
|
protected final void create(final T resource) {
|
||||||
createAsUri(resource);
|
createAsUri(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String createAsUri(final T resource) {
|
protected final String createAsUri(final T resource) {
|
||||||
final Response response = createAsResponse(resource);
|
final Response response = createAsResponse(resource);
|
||||||
Preconditions.checkState(response.getStatusCode() == 201, "create operation: " + response.getStatusCode());
|
Preconditions.checkState(response.getStatusCode() == 201, "create operation: " + response.getStatusCode());
|
||||||
|
|
||||||
|
|
|
@ -25,4 +25,9 @@ public class FooLiveTest extends AbstractLiveTest<Foo> {
|
||||||
create(new Foo(randomAlphabetic(6)));
|
create(new Foo(randomAlphabetic(6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String createAsUri() {
|
||||||
|
return createAsUri(new Foo(randomAlphabetic(6)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue