DATAREST-117 - Added support to detect @JsonIgnore and @JsonIgnoreProperties.
Wrote test cases to verify it handles class level and attribute level annotations to ignore properties when rendering PersistentEntityResources. Original pull request: #135.
This commit is contained in:
committed by
Oliver Gierke
parent
b3b091e309
commit
171ab2583e
@@ -16,6 +16,8 @@
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -44,6 +46,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.Version;
|
||||
@@ -133,6 +136,17 @@ public class PersistentEntityJackson2Module extends SimpleModule {
|
||||
|
||||
final Map<String, Object> model = new LinkedHashMap<String, Object>();
|
||||
|
||||
String[] fieldsToIgnore = new String[]{};
|
||||
|
||||
for (Annotation annotation : entity.getType().getAnnotations()) {
|
||||
if (annotation.annotationType().equals(JsonIgnoreProperties.class)) {
|
||||
JsonIgnoreProperties ann = (JsonIgnoreProperties)annotation;
|
||||
fieldsToIgnore = ann.value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
final String[] finalFieldsToIgnore = fieldsToIgnore;
|
||||
|
||||
try {
|
||||
|
||||
entity.doWithProperties(new SimplePropertyHandler() {
|
||||
@@ -151,6 +165,24 @@ public class PersistentEntityJackson2Module extends SimpleModule {
|
||||
return;
|
||||
}
|
||||
|
||||
final Method getter = property.getGetter();
|
||||
if (getter != null) {
|
||||
final Annotation[] annotations = getter.getAnnotations();
|
||||
for (Annotation annotation : annotations) {
|
||||
if (annotation.annotationType().equals(JsonIgnore.class)) {
|
||||
if (((JsonIgnore)annotation).value()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String fieldToIgnore : finalFieldsToIgnore) {
|
||||
if (property.getName().equals(fieldToIgnore)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Property is a normal or non-managed property.
|
||||
model.put(property.getName(), wrapper.getProperty(property));
|
||||
}
|
||||
|
||||
@@ -262,7 +262,16 @@ public abstract class AbstractWebIntegrationTests {
|
||||
return (T) jsonPathResult;
|
||||
}
|
||||
|
||||
protected String assertJsonPathEquals(String path, MockHttpServletResponse response, String expected)
|
||||
protected void assertJsonPathDoesntExist(String path, MockHttpServletResponse response) throws Exception {
|
||||
|
||||
try {
|
||||
JsonPath.read(response.getContentAsString(), path);
|
||||
fail(path + " should have failed");
|
||||
} catch (InvalidPathException e) {
|
||||
}
|
||||
}
|
||||
|
||||
protected String assertJsonPathEquals(String path, String expected, MockHttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
String jsonQueryResults = assertHasJsonPathValue(path, response);
|
||||
|
||||
@@ -176,6 +176,29 @@ public class JpaWebTests extends AbstractWebIntegrationTests {
|
||||
).andExpect(status().isCreated());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-117
|
||||
*/
|
||||
@Test
|
||||
public void createPersonThenVerifyIgnoredAttributesDontExist() throws Exception {
|
||||
|
||||
Link peopleLink = discoverUnique("people");
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
Person frodo = new Person("Frodo", "Baggins");
|
||||
frodo.setAge(77);
|
||||
frodo.setHeight(42);
|
||||
frodo.setWeight(75);
|
||||
String frodoString = mapper.writeValueAsString(frodo);
|
||||
|
||||
MockHttpServletResponse response = postAndGet(peopleLink, frodoString, MediaType.APPLICATION_JSON);
|
||||
|
||||
assertJsonPathEquals("$.firstName", "Frodo", response);
|
||||
assertJsonPathEquals("$.lastName", "Baggins", response);
|
||||
assertJsonPathDoesntExist("$.age", response);
|
||||
assertJsonPathDoesntExist("$.height", response);
|
||||
assertJsonPathDoesntExist("$.weight", response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-95
|
||||
*/
|
||||
@@ -354,14 +377,14 @@ public class JpaWebTests extends AbstractWebIntegrationTests {
|
||||
MockHttpServletResponse createdPerson = postAndGet(peopleLink, frodoString, MediaType.APPLICATION_JSON);
|
||||
|
||||
Link frodoLink = assertHasLinkWithRel("self", createdPerson);
|
||||
assertJsonPathEquals("$.firstName", createdPerson, "Frodo");
|
||||
assertJsonPathEquals("$.firstName", "Frodo", createdPerson);
|
||||
|
||||
String bilboWithFrodosLinks = createdPerson.getContentAsString().replace("Frodo", "Bilbo");
|
||||
|
||||
MockHttpServletResponse overwrittenResponse = putAndGet(frodoLink, bilboWithFrodosLinks, MediaType.APPLICATION_JSON);
|
||||
|
||||
assertHasLinkWithRel("self", overwrittenResponse);
|
||||
assertJsonPathEquals("$.firstName", overwrittenResponse, "Bilbo");
|
||||
assertJsonPathEquals("$.firstName", "Bilbo", overwrittenResponse);
|
||||
}
|
||||
|
||||
private List<Link> preparePersonResources(Person primary, Person... persons) throws Exception {
|
||||
|
||||
@@ -14,14 +14,19 @@ import javax.persistence.ManyToOne;
|
||||
import javax.persistence.PrePersist;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreType;
|
||||
import org.springframework.data.rest.core.annotation.Description;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
/**
|
||||
* An entity that represents a person.
|
||||
*
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Entity
|
||||
@JsonIgnoreProperties({"height", "weight"})
|
||||
public class Person {
|
||||
|
||||
private Long id;
|
||||
@@ -30,6 +35,9 @@ public class Person {
|
||||
@Description("A person's siblings") private List<Person> siblings = Collections.emptyList();
|
||||
private Person father;
|
||||
@Description("Timestamp this person object was created") private Date created;
|
||||
private int age;
|
||||
private int height;
|
||||
private int weight;
|
||||
|
||||
public Person() {}
|
||||
|
||||
@@ -102,4 +110,28 @@ public class Person {
|
||||
this.created = Calendar.getInstance().getTime();
|
||||
}
|
||||
|
||||
}
|
||||
@JsonIgnore
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(int weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user