#27 - Added support for Jackson 2.

Added Jackson 2 dependencies. Doubly annotated representation model classes with both Jackson 1 and Jackson 2 annotations. Added Integration tests for Jackson 2 marshaling provided by Jon. Polished template.mf.
This commit is contained in:
Oliver Gierke
2012-11-16 21:32:47 +01:00
parent 04be1871c3
commit 40b486cb43
10 changed files with 247 additions and 23 deletions

21
pom.xml
View File

@@ -58,7 +58,8 @@
<properties>
<spring.version>3.1.2.RELEASE</spring.version>
<jackson.version>1.9.10</jackson.version>
<jackson1.version>1.9.10</jackson1.version>
<jackson2.version>2.1.1</jackson2.version>
<jaxrs.version>1.0</jaxrs.version>
<bundlor.failOnWarnings>true</bundlor.failOnWarnings>
</properties>
@@ -100,7 +101,14 @@
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>${jackson.version}</version>
<version>${jackson1.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson2.version}</version>
<optional>true</optional>
</dependency>
@@ -114,7 +122,14 @@
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
<version>${jackson1.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson2.version}</version>
<scope>test</scope>
</dependency>

View File

@@ -22,9 +22,6 @@ import java.util.Collection;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.util.Assert;
/**
@@ -33,10 +30,12 @@ import org.springframework.util.Assert;
* @author Oliver Gierke
*/
@XmlRootElement(name = "entities")
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@org.codehaus.jackson.annotate.JsonAutoDetect(fieldVisibility = org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.ANY)
@com.fasterxml.jackson.annotation.JsonAutoDetect(fieldVisibility = com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY)
public class PagedResources<T> extends Resources<T> {
@JsonProperty("page")
@org.codehaus.jackson.annotate.JsonProperty("page")
@com.fasterxml.jackson.annotation.JsonProperty("page")
private PageMetadata metadata;
/**
@@ -145,23 +144,28 @@ public class PagedResources<T> extends Resources<T> {
*
* @author Oliver Gierke
*/
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@org.codehaus.jackson.annotate.JsonAutoDetect(fieldVisibility = org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.ANY)
@com.fasterxml.jackson.annotation.JsonAutoDetect(fieldVisibility = com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY)
public static class PageMetadata {
@XmlAttribute
@JsonProperty
@org.codehaus.jackson.annotate.JsonProperty
@com.fasterxml.jackson.annotation.JsonProperty
private long size;
@XmlAttribute
@JsonProperty
@org.codehaus.jackson.annotate.JsonProperty
@com.fasterxml.jackson.annotation.JsonProperty
private long totalElements;
@XmlAttribute
@JsonProperty
@org.codehaus.jackson.annotate.JsonProperty
@com.fasterxml.jackson.annotation.JsonProperty
private long totalPages;
@XmlAttribute
@JsonProperty
@org.codehaus.jackson.annotate.JsonProperty
@com.fasterxml.jackson.annotation.JsonProperty
private long number;
protected PageMetadata() {

View File

@@ -19,7 +19,6 @@ import java.util.Arrays;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonUnwrapped;
import org.springframework.util.Assert;
/**
@@ -30,7 +29,8 @@ import org.springframework.util.Assert;
@XmlRootElement
public class Resource<T> extends ResourceSupport {
@JsonUnwrapped
@org.codehaus.jackson.annotate.JsonUnwrapped
@com.fasterxml.jackson.annotation.JsonUnwrapped
private final T content;
/**

View File

@@ -21,8 +21,6 @@ import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.util.Assert;
/**
@@ -33,7 +31,8 @@ import org.springframework.util.Assert;
public class ResourceSupport implements Identifiable<Link> {
@XmlElement(name = "link", namespace = Link.ATOM_NAMESPACE)
@JsonProperty("links")
@org.codehaus.jackson.annotate.JsonProperty("links")
@com.fasterxml.jackson.annotation.JsonProperty("links")
private final List<Link> links;
public ResourceSupport() {
@@ -43,7 +42,8 @@ public class ResourceSupport implements Identifiable<Link> {
/**
* Returns the {@link Link} with a rel of {@link Link#REL_SELF}.
*/
@JsonIgnore
@org.codehaus.jackson.annotate.JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Link getId() {
return getLink(Link.REL_SELF);
}

View File

@@ -25,7 +25,6 @@ import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.util.Assert;
/**
@@ -38,7 +37,8 @@ public class Resources<T> extends ResourceSupport implements Iterable<T> {
@XmlAnyElement
@XmlElementWrapper
@JsonProperty("content")
@org.codehaus.jackson.annotate.JsonProperty("content")
@com.fasterxml.jackson.annotation.JsonProperty("content")
private final Collection<T> content;
/**

View File

@@ -0,0 +1,34 @@
package org.springframework.hateoas;
import java.io.StringWriter;
import java.io.Writer;
import org.junit.Before;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Base class to test objects against the Jackson 2.0 {@link ObjectMapper}.
*
* @author Oliver Gierke
* @author Jon Brisbin
*/
public abstract class AbstractJackson2MarshallingIntegrationTests {
ObjectMapper mapper;
@Before
public void setUp() {
mapper = new ObjectMapper();
}
protected String write(Object object) throws Exception {
Writer writer = new StringWriter();
mapper.writeValue(writer, object);
return writer.toString();
}
protected <T> T read(String source, Class<T> targetType) throws Exception {
return mapper.readValue(source, targetType);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.hateoas;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* Integration tests for {@link org.springframework.hateoas.Link} marshaling.
*
* @author Oliver Gierke
* @author Jon Brisbin
*/
public class Jackson2LinkIntegrationTest extends AbstractJackson2MarshallingIntegrationTests {
private static final String REFERENCE = "{\"rel\":\"something\",\"href\":\"location\"}";
/**
* @see #27
*/
@Test
public void writesLinkCorrectly() throws Exception {
assertThat(write(new Link("location", "something")), is(REFERENCE));
}
/**
* @see #27
*/
@Test
public void readsLinkCorrectly() throws Exception {
Link result = read(REFERENCE, Link.class);
assertThat(result.getHref(), is("location"));
assertThat(result.getRel(), is("something"));
}
}

View File

@@ -0,0 +1,65 @@
package org.springframework.hateoas;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
/**
* Integration tests for {@link Resource}.
*
* @author Oliver Gierke
* @author Jon Brisbin
*/
public class Jackson2ResourceIntegrationTest extends AbstractJackson2MarshallingIntegrationTests {
static final String REFERENCE = "{\"links\":[{\"rel\":\"self\",\"href\":\"localhost\"}],\"firstname\":\"Dave\",\"lastname\":\"Matthews\"}";
/**
* @see #27
* @throws Exception
*/
@Test
public void inlinesContent() throws Exception {
Person person = new Person();
person.firstname = "Dave";
person.lastname = "Matthews";
Resource<Person> resource = new Resource<Person>(person);
resource.add(new Link("localhost"));
assertThat(write(resource), is(REFERENCE));
}
/**
* @see #27
*/
@Test
public void readsResourceSupportCorrectly() throws Exception {
PersonResource result = read(REFERENCE, PersonResource.class);
assertThat(result.getLinks(), hasSize(1));
assertThat(result.getLinks(), hasItem(new Link("localhost")));
assertThat(result.getContent().firstname, is("Dave"));
assertThat(result.getContent().lastname, is("Matthews"));
}
static class PersonResource extends Resource<Person> {
public PersonResource() {
}
}
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
static class Person {
String firstname;
String lastname;
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.hateoas;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* Integration tests for {@link org.springframework.hateoas.ResourceSupport}.
*
* @author Oliver Gierke
*/
public class Jackson2ResourceSupportIntegrationTest extends AbstractJackson2MarshallingIntegrationTests {
static final String REFERENCE = "{\"links\":[{\"rel\":\"self\",\"href\":\"localhost\"}]}";
/**
* @see #27
*/
@Test
public void doesNotRenderId() throws Exception {
ResourceSupport resourceSupport = new ResourceSupport();
resourceSupport.add(new Link("localhost"));
assertThat(write(resourceSupport), is(REFERENCE));
}
/**
* @see #27
*/
@Test
public void readResourceSupportCorrectly() throws Exception {
ResourceSupport result = read(REFERENCE, ResourceSupport.class);
assertThat(result.getLinks(), hasSize(1));
assertThat(result.getLinks(), hasItem(new Link("localhost")));
}
}

View File

@@ -3,7 +3,8 @@ Bundle-Name: Spring HATEOAS
Bundle-Vendor: SpringSource
Bundle-ManifestVersion: 2
Import-Template:
com.fasterxml.jackson.*;version="${jackson2.version:[=.=.=,+1.0.0)}";resolution:=optional,
javax.ws.rs.*;version="${jaxrs.version:[=.=.=,+1.0.0)}";resolution:=optional,
javax.xml.bind.*;version="0",
org.springframework.*;version="${spring.version:[=.=.=,+1.0.0)}";resolution:=optional,
org.codehaus.jackson.*;version="${jackson.version:[=.=.=,+1.0.0)}";resolution:=optional,
javax.ws.rs.*;version="${jaxrs.version:[=.=.=,+1.0.0)}";resolution:=optional
org.codehaus.jackson.*;version="${jackson1.version:[=.=.=,+1.0.0)}";resolution:=optional