diff --git a/src/main/java/org/springframework/hateoas/Link.java b/src/main/java/org/springframework/hateoas/Link.java index 4916432d..4b898129 100755 --- a/src/main/java/org/springframework/hateoas/Link.java +++ b/src/main/java/org/springframework/hateoas/Link.java @@ -221,18 +221,6 @@ public class Link implements Serializable { return !getUriTemplate().getVariables().isEmpty(); } - /** - * This no-op setter is required to deserialize a link that contains a templated URL. It allows Jackson to - * "set" the property, but since {@code templated} is a virtual property, the injected value {@code true} or - * {@code false) is ignored. - * - * The method is kept private so no one attempts to actually use it. - * - * @param __ - don't care what value is passed in. The true value {@link #isTemplated()} is based upon the {@link UriTemplate}. - */ - private void setTemplated(boolean __) { - } - /** * Turns the current template into a {@link Link} by expanding it using the given parameters. * diff --git a/src/main/java/org/springframework/hateoas/hal/LinkMixin.java b/src/main/java/org/springframework/hateoas/hal/LinkMixin.java index b6e46235..c9ec76d1 100644 --- a/src/main/java/org/springframework/hateoas/hal/LinkMixin.java +++ b/src/main/java/org/springframework/hateoas/hal/LinkMixin.java @@ -30,7 +30,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; * @author Oliver Gierke * @author Greg Turnquist */ -@JsonIgnoreProperties({ "rel", "media", "affordances", "template" }) +@JsonIgnoreProperties(value = { "rel", "media", "affordances", "template" }, ignoreUnknown = true) public abstract class LinkMixin extends Link { private static final long serialVersionUID = 4720588561299667409L; diff --git a/src/test/java/org/springframework/hateoas/hal/forms/Jackson2HalFormsIntegrationTest.java b/src/test/java/org/springframework/hateoas/hal/forms/Jackson2HalFormsIntegrationTest.java index 6cd2e024..18ddd869 100644 --- a/src/test/java/org/springframework/hateoas/hal/forms/Jackson2HalFormsIntegrationTest.java +++ b/src/test/java/org/springframework/hateoas/hal/forms/Jackson2HalFormsIntegrationTest.java @@ -15,8 +15,7 @@ */ package org.springframework.hateoas.hal.forms; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.assertj.core.api.Assertions.*; import java.io.IOException; import java.util.ArrayList; @@ -75,8 +74,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling ResourceSupport resourceSupport = new ResourceSupport(); resourceSupport.add(new Link("localhost")); - assertThat(write(resourceSupport), - is(MappingUtils.read(new ClassPathResource("single-link-reference.json", getClass())))); + assertThat(write(resourceSupport)) + .isEqualTo(MappingUtils.read(new ClassPathResource("single-link-reference.json", getClass()))); } @Test @@ -85,9 +84,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling ResourceSupport expected = new ResourceSupport(); expected.add(new Link("localhost")); - assertThat( - read(MappingUtils.read(new ClassPathResource("single-link-reference.json", getClass())), ResourceSupport.class), - is(expected)); + assertThat(read(MappingUtils.read(new ClassPathResource("single-link-reference.json", getClass())), ResourceSupport.class)) + .isEqualTo(expected); } @Test @@ -97,8 +95,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling resourceSupport.add(new Link("localhost")); resourceSupport.add(new Link("localhost2")); - assertThat(write(resourceSupport), - is(MappingUtils.read(new ClassPathResource("list-link-reference.json", getClass())))); + assertThat(write(resourceSupport)) + .isEqualTo(MappingUtils.read(new ClassPathResource("list-link-reference.json", getClass()))); } @Test @@ -108,9 +106,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling expected.add(new Link("localhost")); expected.add(new Link("localhost2")); - assertThat( - read(MappingUtils.read(new ClassPathResource("list-link-reference.json", getClass())), ResourceSupport.class), - is(expected)); + assertThat(read(MappingUtils.read(new ClassPathResource("list-link-reference.json", getClass())), ResourceSupport.class)) + .isEqualTo(expected); } @Test @@ -118,8 +115,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling Resource resource = new Resource<>(new SimplePojo("test1", 1), new Link("localhost")); - assertThat(write(resource), - is(MappingUtils.read(new ClassPathResource("simple-resource-unwrapped.json", getClass())))); + assertThat(write(resource)) + .isEqualTo(MappingUtils.read(new ClassPathResource("simple-resource-unwrapped.json", getClass()))); } @Test @@ -131,7 +128,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling MappingUtils.read(new ClassPathResource("simple-resource-unwrapped.json", getClass())), mapper.getTypeFactory().constructParametricType(Resource.class, SimplePojo.class)); - assertThat(result, is(expected)); + assertThat(result).isEqualTo(expected); } @Test @@ -144,8 +141,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling Resources resources = new Resources<>(content); resources.add(new Link("localhost")); - assertThat(write(resources), - is(MappingUtils.read(new ClassPathResource("simple-embedded-resource-reference.json", getClass())))); + assertThat(write(resources)) + .isEqualTo(MappingUtils.read(new ClassPathResource("simple-embedded-resource-reference.json", getClass()))); } @Test @@ -162,7 +159,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling MappingUtils.read(new ClassPathResource("simple-embedded-resource-reference.json", getClass())), mapper.getTypeFactory().constructParametricType(Resources.class, String.class)); - assertThat(result, is(expected)); + assertThat(result).isEqualTo(expected); } @@ -175,8 +172,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling Resources> resources = new Resources<>(content); resources.add(new Link("localhost")); - assertThat(write(resources), - is(MappingUtils.read(new ClassPathResource("single-embedded-resource-reference.json", getClass())))); + assertThat(write(resources)) + .isEqualTo(MappingUtils.read(new ClassPathResource("single-embedded-resource-reference.json", getClass()))); } @Test @@ -193,7 +190,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling mapper.getTypeFactory().constructParametricType(Resources.class, mapper.getTypeFactory().constructParametricType(Resource.class, SimplePojo.class))); - assertThat(result, is(expected)); + assertThat(result).isEqualTo(expected); } @Test @@ -202,8 +199,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling Resources> resources = setupResources(); resources.add(new Link("localhost")); - assertThat(write(resources), - is(MappingUtils.read(new ClassPathResource("multiple-resource-resources.json", getClass())))); + assertThat(write(resources)) + .isEqualTo(MappingUtils.read(new ClassPathResource("multiple-resource-resources.json", getClass()))); } @Test @@ -217,7 +214,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling mapper.getTypeFactory().constructParametricType(Resources.class, mapper.getTypeFactory().constructParametricType(Resource.class, SimplePojo.class))); - assertThat(result, is(expected)); + assertThat(result).isEqualTo(expected); } @Test @@ -229,8 +226,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling Resources> resources = new Resources<>(content); resources.add(new Link("localhost")); - assertThat(write(resources), - is(MappingUtils.read(new ClassPathResource("annotated-resource-resources.json", getClass())))); + assertThat(write(resources)) + .isEqualTo(MappingUtils.read(new ClassPathResource("annotated-resource-resources.json", getClass()))); } @Test @@ -247,13 +244,13 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling mapper.getTypeFactory().constructParametricType(Resources.class, mapper.getTypeFactory().constructParametricType(Resource.class, SimpleAnnotatedPojo.class))); - assertThat(result, is(expected)); + assertThat(result).isEqualTo(expected); } @Test public void serializesMultipleAnnotatedResourceResourcesAsEmbedded() throws Exception { - assertThat(write(setupAnnotatedResources()), - is(MappingUtils.read(new ClassPathResource("annotated-embedded-resources-reference.json", getClass())))); + assertThat(write(setupAnnotatedResources())) + .isEqualTo(MappingUtils.read(new ClassPathResource("annotated-embedded-resources-reference.json", getClass()))); } @Test @@ -264,13 +261,13 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling mapper.getTypeFactory().constructParametricType(Resources.class, mapper.getTypeFactory().constructParametricType(Resource.class, SimpleAnnotatedPojo.class))); - assertThat(result, is(setupAnnotatedResources())); + assertThat(result).isEqualTo(setupAnnotatedResources()); } @Test public void serializesPagedResource() throws Exception { - assertThat(write(setupAnnotatedPagedResources()), - is(MappingUtils.read(new ClassPathResource("annotated-paged-resources.json", getClass())))); + assertThat(write(setupAnnotatedPagedResources())) + .isEqualTo(MappingUtils.read(new ClassPathResource("annotated-paged-resources.json", getClass()))); } @Test @@ -280,7 +277,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling mapper.getTypeFactory().constructParametricType(PagedResources.class, mapper.getTypeFactory().constructParametricType(Resource.class, SimpleAnnotatedPojo.class))); - assertThat(result, is(setupAnnotatedPagedResources())); + assertThat(result).isEqualTo(setupAnnotatedPagedResources()); } @Test @@ -289,16 +286,16 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling Resources resources = new Resources<>(Collections.emptySet(), new Link("foo"), new Link("bar", "myrel")); - assertThat(getCuriedObjectMapper().writeValueAsString(resources), - is(MappingUtils.read(new ClassPathResource("curied-document.json", getClass())))); + assertThat(getCuriedObjectMapper().writeValueAsString(resources)) + .isEqualTo(MappingUtils.read(new ClassPathResource("curied-document.json", getClass()))); } @Test public void doesNotRenderCuriesIfNoLinkIsPresent() throws Exception { Resources resources = new Resources<>(Collections.emptySet()); - assertThat(getCuriedObjectMapper().writeValueAsString(resources), - is(MappingUtils.read(new ClassPathResource("empty-document.json", getClass())))); + assertThat(getCuriedObjectMapper().writeValueAsString(resources)) + .isEqualTo(MappingUtils.read(new ClassPathResource("empty-document.json", getClass()))); } @Test @@ -307,8 +304,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling Resources resources = new Resources<>(Collections.emptySet()); resources.add(new Link("foo")); - assertThat(getCuriedObjectMapper().writeValueAsString(resources), - is(MappingUtils.read(new ClassPathResource("single-non-curie-document.json", getClass())))); + assertThat(getCuriedObjectMapper().writeValueAsString(resources)) + .isEqualTo(MappingUtils.read(new ClassPathResource("single-non-curie-document.json", getClass()))); } @Test @@ -317,7 +314,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling ResourceSupport support = new ResourceSupport(); support.add(new Link("/foo{?bar}", "search")); - assertThat(write(support), is(MappingUtils.read(new ClassPathResource("link-template.json", getClass())))); + assertThat(write(support)).isEqualTo(MappingUtils.read(new ClassPathResource("link-template.json", getClass()))); } @Test @@ -333,8 +330,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling } }; - assertThat(getCuriedObjectMapper(provider, null).writeValueAsString(resources), - is(MappingUtils.read(new ClassPathResource("multiple-curies-document.json", getClass())))); + assertThat(getCuriedObjectMapper(provider, null).writeValueAsString(resources)) + .isEqualTo(MappingUtils.read(new ClassPathResource("multiple-curies-document.json", getClass()))); } @Test @@ -347,7 +344,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling Resources resources = new Resources<>(values); - assertThat(write(resources), is(MappingUtils.read(new ClassPathResource("empty-embedded-pojos.json", getClass())))); + assertThat(write(resources)).isEqualTo(MappingUtils.read(new ClassPathResource("empty-embedded-pojos.json", getClass()))); } @Test @@ -360,6 +357,26 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling verifyResolvedTitle("_links.foobar.title"); } + /** + * @see #667 + */ + @Test + public void handleTemplatedLinksOnDeserialization() throws IOException { + + ResourceSupport original = new ResourceSupport(); + original.add(new Link("/orders{?id}", "order")); + + String serialized = mapper.writeValueAsString(original); + + String expected = "{\n \"_links\" : {\n \"order\" : {\n \"href\" : \"/orders{?id}\",\n \"templated\" : true\n }\n }\n}"; + + assertThat(serialized).isEqualTo(expected); + + ResourceSupport deserialized = mapper.readValue(serialized, ResourceSupport.class); + + assertThat(deserialized).isEqualTo(original); + } + private void verifyResolvedTitle(String resourceBundleKey) throws Exception { LocaleContextHolder.setLocale(Locale.US); @@ -372,8 +389,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling ResourceSupport resource = new ResourceSupport(); resource.add(new Link("target", "ns:foobar")); - assertThat(objectMapper.writeValueAsString(resource), - is(MappingUtils.read(new ClassPathResource("link-with-title.json", getClass())))); + assertThat(objectMapper.writeValueAsString(resource)) + .isEqualTo(MappingUtils.read(new ClassPathResource("link-with-title.json", getClass()))); } private static Resources> setupResources() {