Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,22 @@ public JsonValueSerializer(AnnotatedMember accessor,
_dynamicSerializers = PropertySerializerMap.emptyForProperties();
}

@SuppressWarnings("unchecked")
public JsonValueSerializer(AnnotatedMember accessor,
TypeSerializer vts, JsonSerializer<?> ser,
Set<String> ignoredProperties, boolean forceTypeInformation)
{
super(accessor.getType());
_accessor = accessor;
_valueType = accessor.getType();
_valueTypeSerializer = vts;
_valueSerializer = (JsonSerializer<Object>) ser;
_property = null;
_forceTypeInformation = forceTypeInformation; // gets reconsidered when we are contextualized
_ignoredProperties = ignoredProperties;
_dynamicSerializers = PropertySerializerMap.emptyForProperties();
}

@Deprecated // since 2.16
public JsonValueSerializer(AnnotatedMember accessor,
TypeSerializer vts, JsonSerializer<?> ser)
Expand Down Expand Up @@ -161,7 +177,8 @@ public static JsonValueSerializer construct(SerializationConfig config,
.findPropertyIgnoralByName(config, accessor);
final Set<String> ignoredProperties = ignorals.findIgnoredForSerialization();
ser = _withIgnoreProperties(ser, ignoredProperties);
return new JsonValueSerializer(accessor, vts, ser, ignoredProperties);
// TODO Try `_forceTypeInformation` with false as default
return new JsonValueSerializer(accessor, vts, ser, ignoredProperties, false);
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -311,7 +328,10 @@ public void serializeWithType(Object bean, JsonGenerator gen, SerializerProvider
JsonSerializer<Object> ser = _valueSerializer;
if (ser == null) { // no serializer yet? Need to fetch
ser = _findDynamicSerializer(ctxt, value.getClass());
} else {
}

// TODO `_forceTypeInformation` should be checked even if ser is not null
// else {
// 09-Dec-2010, tatu: To work around natural type's refusal to add type info, we do
// this (note: type is for the wrapper type, not enclosed value!)
if (_forceTypeInformation) {
Expand All @@ -322,13 +342,14 @@ public void serializeWithType(Object bean, JsonGenerator gen, SerializerProvider
typeSer0.writeTypeSuffix(gen, typeIdDef);

return;
}
}
} else {
// }
// 28-Sep-2016, tatu: As per [databind#1385], we do need to do some juggling
// to use different Object for type id (logical type) and actual serialization
// (delegate type).
TypeSerializerRerouter rr = new TypeSerializerRerouter(typeSer0, bean);
ser.serializeWithType(value, gen, ctxt, rr);
}
}

/*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.fasterxml.jackson.databind.ser.benoit;

import java.util.Locale;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestIntConstructor_Enum_WeirdSerialization {

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type",
defaultImpl = NativeOption.class)
public interface SomeOption {
}

public static enum NativeOption implements SomeOption {
A, B;

@JsonCreator
public static NativeOption forValue(String value) {
return NativeOption.valueOf(value.toUpperCase(Locale.US));
}

}

public static enum CustomOption implements SomeOption {
C, D;

@JsonCreator
public static NativeOption forValue(String value) {
return NativeOption.valueOf(value.toUpperCase(Locale.US));
}

}

@Test
public void testNative_string() throws JsonProcessingException {
NativeOption matcher = NativeOption.A;

ObjectMapper objectMapper = new ObjectMapper();

String asString = objectMapper.writeValueAsString(matcher);
Assertions.assertThat(asString).isEqualTo("A");
}

@Test
public void testCustom_string() throws JsonProcessingException {
CustomOption matcher = CustomOption.C;

ObjectMapper objectMapper = new ObjectMapper();

String asString = objectMapper.writeValueAsString(matcher);
Assertions.assertThat(asString).isEqualTo("type: CustomOption, value: A");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.fasterxml.jackson.databind.ser.benoit;

import java.util.Map;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

// https://github.com/FasterXML/jackson-databind/issues/5035
public class TestIntConstructor_WeirdSerialization {

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type",
defaultImpl = AroundString.class)
@JsonSubTypes({ @JsonSubTypes.Type(value = AroundString.class, name = "string"),
@JsonSubTypes.Type(value = AroundObject.class, name = "object") })
public interface AroundSomething {
Object getInner();
}

public static class AroundString implements AroundSomething {
@JsonValue
String inner; // <-- Turning this to Object will make the test passes

@Override
public Object getInner() {
return inner;
}

public void setInner(String inner) {
this.inner = inner;
}

}

public static class AroundObject implements AroundSomething {
@JsonValue
Object inner; // <-- Turning this to Object will make the test passes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already declared object?


@Override
public Object getInner() {
return inner;
}

public void setInner(String inner) {
this.inner = inner;
}

}

public static class HasFromObject {
AroundSomething c;

public AroundSomething getC() {
return c;
}

public void setC(AroundSomething c) {
this.c = c;
}
}

@Test
public void test_aroundString_convertValue() throws JsonProcessingException {
AroundString matcher = new AroundString();
matcher.setInner("foo");

HasFromObject wrapper = new HasFromObject();
wrapper.setC(matcher);

ObjectMapper objectMapper = new ObjectMapper();

Map asMap = objectMapper.convertValue(wrapper, Map.class);
Assertions.assertThat(asMap.toString()).isEqualTo("{c=foo}");
}

@Test
public void test_aroundString_writeValueAsString() throws JsonProcessingException {
AroundString matcher = new AroundString();
matcher.setInner("foo");

HasFromObject wrapper = new HasFromObject();
wrapper.setC(matcher);

ObjectMapper objectMapper = new ObjectMapper();

String asString = objectMapper.writeValueAsString(wrapper);
Assertions.assertThat(asString).isEqualTo("{\"c\":\"foo\"}"); // FAILs with `"{"c":["from","foo"]}"`
}

@Test
public void test_aroundObject_convertValue() throws JsonProcessingException {
AroundObject matcher = new AroundObject();
matcher.setInner("foo");

HasFromObject wrapper = new HasFromObject();
wrapper.setC(matcher);

ObjectMapper objectMapper = new ObjectMapper();

Map asMap = objectMapper.convertValue(wrapper, Map.class);
Assertions.assertThat(asMap.toString()).isEqualTo("{c=foo}");
}

@Test
public void test_aroundObject_writeValueAsString() throws JsonProcessingException {
AroundObject matcher = new AroundObject();
matcher.setInner("foo");

HasFromObject wrapper = new HasFromObject();
wrapper.setC(matcher);

ObjectMapper objectMapper = new ObjectMapper();

String asString = objectMapper.writeValueAsString(wrapper);
Assertions.assertThat(asString).isEqualTo("{\"c\":\"foo\"}"); // FAILs with `"{"c":["from","foo"]}"`
}
}
Loading