diff --git a/src/main/java/org/springframework/hateoas/EntityModel.java b/src/main/java/org/springframework/hateoas/EntityModel.java index e1567bb8..abb9900d 100644 --- a/src/main/java/org/springframework/hateoas/EntityModel.java +++ b/src/main/java/org/springframework/hateoas/EntityModel.java @@ -33,9 +33,11 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.fasterxml.jackson.databind.ser.impl.UnknownSerializer; import com.fasterxml.jackson.databind.ser.std.JsonValueSerializer; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.databind.util.NameTransformer; @@ -225,6 +227,11 @@ public class EntityModel extends RepresentationModel> { JsonSerializer serializer = provider.findValueSerializer(value.getClass()); + if (UnknownSerializer.class.isInstance(serializer) + && !provider.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)) { + return; + } + if (JsonValueSerializer.class.isInstance(serializer)) { throw new IllegalStateException( "@JsonValue rendered classes can not be directly nested in EntityModel as they do not produce a document key!"); diff --git a/src/test/java/org/springframework/hateoas/EntityModelIntegrationTest.java b/src/test/java/org/springframework/hateoas/EntityModelIntegrationTest.java index 41479ae6..8c094e7e 100755 --- a/src/test/java/org/springframework/hateoas/EntityModelIntegrationTest.java +++ b/src/test/java/org/springframework/hateoas/EntityModelIntegrationTest.java @@ -21,6 +21,9 @@ import org.junit.jupiter.api.Test; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; /** * Integration tests for {@link EntityModel}. @@ -59,6 +62,22 @@ class EntityModelIntegrationTest extends AbstractJackson2MarshallingIntegrationT assertThat(result.getContent().lastname).isEqualTo("Matthews"); } + @Test // #1686 + void doesNotFailOnSerializingEmptyBean() { + + ObjectMapper mapper = MappingTestUtils.defaultObjectMapper(); + + // Fail if we're supposed to + assertThatExceptionOfType(JsonMappingException.class) // + .isThrownBy(() -> mapper.enable(SerializationFeature.FAIL_ON_EMPTY_BEANS) + .writeValueAsString(EntityModel.of(new Empty()))); + + // Ignore empty bean if we're supposed to + assertThatNoException() // + .isThrownBy(() -> mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) + .writeValueAsString(EntityModel.of(new Empty()))); + } + static class PersonModel extends EntityModel { public PersonModel(Person person) { @@ -74,4 +93,6 @@ class EntityModelIntegrationTest extends AbstractJackson2MarshallingIntegrationT String firstname; String lastname; } + + static class Empty {} }