#1599 - Properly contextualize MapSuppressingUnwrappingSerializer.
According to FasterXML/jackson-databind#3272, we have to explicitly contextualize the delegate serializer we use for non-Map content in EntityModel.
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -29,9 +30,12 @@ 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.BeanProperty;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
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.ContextualSerializer;
|
||||
import com.fasterxml.jackson.databind.ser.std.JsonValueSerializer;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import com.fasterxml.jackson.databind.util.NameTransformer;
|
||||
@@ -197,10 +201,23 @@ public class EntityModel<T> extends RepresentationModel<EntityModel<T>> {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class MapSuppressingUnwrappingSerializer extends StdSerializer<Object> {
|
||||
private static class MapSuppressingUnwrappingSerializer extends StdSerializer<Object>
|
||||
implements ContextualSerializer {
|
||||
|
||||
private static final long serialVersionUID = -8367255762553946324L;
|
||||
|
||||
private final @Nullable BeanProperty property;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public MapSuppressingUnwrappingSerializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
private MapSuppressingUnwrappingSerializer(@Nullable BeanProperty property) {
|
||||
|
||||
super(Object.class);
|
||||
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -208,7 +225,9 @@ public class EntityModel<T> extends RepresentationModel<EntityModel<T>> {
|
||||
* @see com.fasterxml.jackson.databind.ser.std.StdSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)
|
||||
*/
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
@SuppressWarnings({ "null", "unchecked" })
|
||||
public void serialize(@Nullable Object value, @Nullable JsonGenerator gen, @NonNull SerializerProvider provider)
|
||||
throws IOException {
|
||||
|
||||
if (value == null || Map.class.isInstance(value)) {
|
||||
return;
|
||||
@@ -221,11 +240,25 @@ public class EntityModel<T> extends RepresentationModel<EntityModel<T>> {
|
||||
"@JsonValue rendered classes can not be directly nested in EntityModel as they do not produce a document key!");
|
||||
}
|
||||
|
||||
if (ContextualSerializer.class.isInstance(serializer)) {
|
||||
serializer = (JsonSerializer<Object>) ((ContextualSerializer) serializer).createContextual(provider, property);
|
||||
}
|
||||
|
||||
serializer //
|
||||
.unwrappingSerializer(NameTransformer.NOP) //
|
||||
.serialize(value, gen, provider);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.fasterxml.jackson.databind.ser.ContextualSerializer#createContextual(com.fasterxml.jackson.databind.SerializerProvider, com.fasterxml.jackson.databind.BeanProperty)
|
||||
*/
|
||||
@Override
|
||||
public JsonSerializer<?> createContextual(@Nullable SerializerProvider prov, @Nullable BeanProperty property)
|
||||
throws JsonMappingException {
|
||||
return new MapSuppressingUnwrappingSerializer(property);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.fasterxml.jackson.databind.JsonSerializer#isUnwrappingSerializer()
|
||||
|
||||
@@ -21,7 +21,9 @@ import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@@ -88,9 +90,23 @@ class EntityModelUnitTest {
|
||||
.withMessageContaining("@JsonValue");
|
||||
}
|
||||
|
||||
@Test // #1371
|
||||
void rendersTypeIdentifiersCorrectly() throws Exception {
|
||||
|
||||
EntityModel<?> model = EntityModel.of(new TypeWithId());
|
||||
|
||||
assertThatNoException()
|
||||
.isThrownBy(() -> new ObjectMapper().writeValueAsString(model));
|
||||
}
|
||||
|
||||
// #1371
|
||||
|
||||
static class ValueType {
|
||||
@JsonValue String type;
|
||||
}
|
||||
|
||||
@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class, property = "@jsonObjectId")
|
||||
static class TypeWithId {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user