#1435 - EntityModel now explicitly rejects types rendered as @JsonValue.

It doesn't make sense to wrap an object to be rendered as value into an EntityModel as the latter will end up as JSON Object and thus, the representation of the target object *needs* to consist of key-value pairs.

Previously we just produced invalid JSON which ultimately failed as well.
This commit is contained in:
Oliver Drotbohm
2021-01-18 16:44:27 +01:00
parent 9073286b6f
commit b5ce20a0fb
2 changed files with 30 additions and 1 deletions

View File

@@ -29,8 +29,10 @@ import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.JsonValueSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.databind.util.NameTransformer;
@@ -213,7 +215,14 @@ public class EntityModel<T> extends RepresentationModel<EntityModel<T>> {
return;
}
provider.findValueSerializer(value.getClass()) //
JsonSerializer<Object> serializer = provider.findValueSerializer(value.getClass());
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!");
}
serializer //
.unwrappingSerializer(NameTransformer.NOP) //
.serialize(value, gen, provider);
}

View File

@@ -21,6 +21,10 @@ import java.util.Collections;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Unit tests for {@link EntityModel}.
*
@@ -73,4 +77,20 @@ class EntityModelUnitTest {
EntityModel.of(Collections.emptyList());
});
}
@Test // #1371
void producesProperExceptionWhenRenderingAJsonValue() throws Exception {
EntityModel<?> model = EntityModel.of(new ValueType());
assertThatExceptionOfType(JsonMappingException.class)
.isThrownBy(() -> new ObjectMapper().writeValueAsString(model))
.withMessageContaining("@JsonValue");
}
// #1371
static class ValueType {
@JsonValue String type;
}
}