Skip to content

Commit 9c63a10

Browse files
committed
Fix #2822
1 parent 50d4faa commit 9c63a10

File tree

5 files changed

+63
-15
lines changed

5 files changed

+63
-15
lines changed

release-notes/CREDITS-2.x

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,12 +1145,15 @@ Daniel Hrabovcak (TheSpiritXIII@github)
11451145
* Reported #2796: `TypeFactory.constructType()` does not take `TypeBindings` correctly
11461146
(2.11.2)
11471147
1148-
Daniel Wu (DanielYWoo@github)
1149-
* Reported #2840: `ObjectMapper.activateDefaultTypingAsProperty()` is not using
1150-
(2.11.3)
1151-
11521148
Lari Hotari (lhotari@github)
1153-
11541149
* Reported #2821: Json serialization fails or a specific case that contains generics and
11551150
static methods with generic parameters (2.11.1 -> 2.11.2 regression)
11561151
(2.11.3)
1152+
1153+
Nils Christian Ehmke (nils-christian@github)
1154+
* Reported #2822: Using JsonValue and JsonFormat on one field does not work as expected
1155+
(2.11.3)
1156+
1157+
Daniel Wu (DanielYWoo@github)
1158+
* Reported #2840: `ObjectMapper.activateDefaultTypingAsProperty()` is not using
1159+
(2.11.3)

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Project: jackson-databind
1010
#2821: Json serialization fails or a specific case that contains generics and
1111
static methods with generic parameters (2.11.1 -> 2.11.2 regression)
1212
(reported by Lari H)
13+
#2822: Using JsonValue and JsonFormat on one field does not work as expected
14+
(reported by Nils-Christian E)
1315
#2840: `ObjectMapper.activateDefaultTypingAsProperty()` is not using
1416
parameter `PolymorphicTypeValidator`
1517
(reported by Daniel W)

src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public JsonValueSerializer(JsonValueSerializer src, BeanProperty property,
9797
private final static Class<Object> _notNullClass(Class<?> cls) {
9898
return (cls == null) ? Object.class : (Class<Object>) cls;
9999
}
100-
100+
101101
public JsonValueSerializer withResolved(BeanProperty property,
102102
JsonSerializer<?> ser, boolean forceTypeInfo)
103103
{
@@ -125,9 +125,9 @@ public JsonSerializer<?> createContextual(SerializerProvider provider,
125125
{
126126
JsonSerializer<?> ser = _valueSerializer;
127127
if (ser == null) {
128-
/* Can only assign serializer statically if the declared type is final:
129-
* if not, we don't really know the actual type until we get the instance.
130-
*/
128+
// Can only assign serializer statically if the declared type is final:
129+
// if not, we don't really know the actual type until we get the instance.
130+
131131
// 10-Mar-2010, tatu: Except if static typing is to be used
132132
JavaType t = _accessor.getType();
133133
if (provider.isEnabled(MapperFeature.USE_STATIC_TYPING) || t.isFinal()) {
@@ -145,14 +145,18 @@ public JsonSerializer<?> createContextual(SerializerProvider provider,
145145
boolean forceTypeInformation = isNaturalTypeWithStdHandling(t.getRawClass(), ser);
146146
return withResolved(property, ser, forceTypeInformation);
147147
}
148+
// [databind#2822]: better hold on to "property", regardless
149+
if (property != _property) {
150+
return withResolved(property, ser, _forceTypeInformation);
151+
}
148152
} else {
149153
// 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
150154
ser = provider.handlePrimaryContextualization(ser, property);
151155
return withResolved(property, ser, _forceTypeInformation);
152156
}
153157
return this;
154158
}
155-
159+
156160
/*
157161
/**********************************************************
158162
/* Actual serialization
@@ -171,10 +175,10 @@ public void serialize(Object bean, JsonGenerator gen, SerializerProvider prov) t
171175
JsonSerializer<Object> ser = _valueSerializer;
172176
if (ser == null) {
173177
Class<?> c = value.getClass();
174-
/* 10-Mar-2010, tatu: Ideally we would actually separate out type
175-
* serializer from value serializer; but, alas, there's no access
176-
* to serializer factory at this point...
177-
*/
178+
// 10-Mar-2010, tatu: Ideally we would actually separate out type
179+
// serializer from value serializer; but, alas, there's no access
180+
// to serializer factory at this point...
181+
178182
// let's cache it, may be needed soon again
179183
ser = prov.findTypedValueSerializer(c, true, _property);
180184
}

src/test/java/com/fasterxml/jackson/databind/BaseMapTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ protected byte[] utf8Bytes(String str) {
354354
}
355355
}
356356

357+
// @since 2.11.3
358+
protected static String a2q(String json) {
359+
return json.replace("'", "\"");
360+
}
361+
357362
protected static String aposToQuotes(String json) {
358363
return json.replace("'", "\"");
359364
}

src/test/java/com/fasterxml/jackson/databind/ser/JsonValueTest.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.fasterxml.jackson.databind.ser;
22

33
import java.io.IOException;
4+
import java.math.BigDecimal;
45
import java.util.*;
56

67
import com.fasterxml.jackson.annotation.*;
8+
79
import com.fasterxml.jackson.core.JsonGenerator;
10+
811
import com.fasterxml.jackson.databind.*;
912
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
1013
import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -192,14 +195,37 @@ public void serialize(Bean838 value, JsonGenerator gen,
192195
gen.writeNumber(42);
193196
}
194197
}
198+
199+
// [databind#2822]
200+
@JsonPropertyOrder({ "description", "b" })
201+
static class A2822 {
202+
public final String description;
203+
204+
@JsonFormat(shape = JsonFormat.Shape.STRING)
205+
public final B2822 b;
206+
207+
public A2822(final String description, final B2822 b ) {
208+
this.description = description;
209+
this.b = b;
210+
}
211+
}
212+
213+
static class B2822 {
214+
@JsonValue
215+
private final BigDecimal value;
216+
217+
public B2822(final BigDecimal value ) {
218+
this.value = value;
219+
}
220+
}
195221

196222
/*
197223
/*********************************************************
198224
/* Test cases
199225
/*********************************************************
200226
*/
201227

202-
private final ObjectMapper MAPPER = new ObjectMapper();
228+
private final ObjectMapper MAPPER = newJsonMapper();
203229

204230
public void testSimpleMethodJsonValue() throws Exception
205231
{
@@ -295,4 +321,12 @@ public void testJsonValueWithCustomOverride() throws Exception
295321
);
296322
assertEquals("42", mapper.writeValueAsString(INPUT));
297323
}
324+
325+
// [databind#2822]
326+
public void testFormatWithJsonValue() throws Exception
327+
{
328+
final String json = MAPPER.writeValueAsString(new A2822("desc",
329+
new B2822(BigDecimal.ONE)));
330+
assertEquals(a2q("{'description':'desc','b':'1'}"), json);
331+
}
298332
}

0 commit comments

Comments
 (0)