Skip to content

Commit c4ecc01

Browse files
committed
Fix #2129
1 parent 06cf17d commit c4ecc01

File tree

8 files changed

+101
-68
lines changed

8 files changed

+101
-68
lines changed

release-notes/CREDITS-2.x

+4
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,10 @@ Joe Barnett (josephlbarnett@github)
884884
ignored when creator properties are buffered
885885
(2.9.10)
886886

887+
Zihui Ren (renzihui@github)
888+
* Suggested #2129: Add `SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX`, separate from value setting
889+
(2.10.0)
890+
887891
Yiqiu Huang (huangyq23@github
888892
* Reported #2164: `FactoryBasedEnumDeserializer` does not respect
889893
`DeserializationFeature.WRAP_EXCEPTIONS`

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Project: jackson-databind
66

77
2.10.0-final (not yet released)
88

9+
#2129: Add `SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX`, separate from value setting
10+
(suggested by renzihui@github)
911
#2149: Add `MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES`
1012
(suggested by Craig P)
1113
#2164: `FactoryBasedEnumDeserializer` does not respect

src/main/java/com/fasterxml/jackson/databind/SerializationFeature.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ public enum SerializationFeature implements ConfigFeature
257257
WRITE_ENUMS_USING_TO_STRING(false),
258258

259259
/**
260-
* Feature that determines whethere Java Enum values are serialized
260+
* Feature that determines whether Java Enum values are serialized
261261
* as numbers (true), or textual values (false). If textual values are
262262
* used, other settings are also considered.
263263
* If this feature is enabled,
@@ -267,10 +267,27 @@ public enum SerializationFeature implements ConfigFeature
267267
* Note that this feature has precedence over {@link #WRITE_ENUMS_USING_TO_STRING},
268268
* which is only considered if this feature is set to false.
269269
*<p>
270+
* Note that since 2.10, this does NOT apply to {@link Enum}s written as
271+
* keys of {@link java.util.Map} values, which has separate setting,
272+
* {@link #WRITE_ENUM_KEYS_USING_INDEX}.
273+
*<p>
270274
* Feature is disabled by default.
271275
*/
272276
WRITE_ENUMS_USING_INDEX(false),
273277

278+
/**
279+
* Feature that determines whether {link Enum}s
280+
* used as {@link java.util.Map} keys are serialized
281+
* as using {@link Enum#ordinal()} or not.
282+
* Similar to {@link #WRITE_ENUMS_USING_INDEX} used when writing
283+
* {@link Enum}s as regular values.
284+
*<p>
285+
* Feature is disabled by default.
286+
*
287+
* @since 2.10
288+
*/
289+
WRITE_ENUM_KEYS_USING_INDEX(false),
290+
274291
/**
275292
* Feature that determines whether Map entries with null values are
276293
* to be serialized (true) or not (false).

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

-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ public JsonSerializer<?> createContextual(SerializerProvider serializers,
119119
public final void serialize(Enum<?> en, JsonGenerator gen, SerializerProvider serializers)
120120
throws IOException
121121
{
122-
// [JACKSON-684]: serialize as index?
123122
if (_serializeAsIndex(serializers)) {
124123
gen.writeNumber(en.ordinal());
125124
return;

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ public void serialize(Object value, JsonGenerator g, SerializerProvider provider
166166
key = value.toString();
167167
} else {
168168
Enum<?> e = (Enum<?>) value;
169-
if (provider.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX)) {
169+
// 14-Sep-2019, tatu: [databind#2129] Use this specific feature
170+
if (provider.isEnabled(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX)) {
170171
key = String.valueOf(e.ordinal());
171172
} else {
172173
key = e.name();
@@ -293,7 +294,8 @@ public void serialize(Object value, JsonGenerator g, SerializerProvider serializ
293294
return;
294295
}
295296
Enum<?> en = (Enum<?>) value;
296-
if (serializers.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX)) {
297+
// 14-Sep-2019, tatu: [databind#2129] Use this specific feature
298+
if (serializers.isEnabled(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX)) {
297299
g.writeFieldName(String.valueOf(en.ordinal()));
298300
return;
299301
}

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,14 @@ public void testMapWithEnumKeys() throws Exception
288288
assertEquals("{\"map\":{\"b\":3}}", json);
289289

290290
// [databind#1570]
291+
292+
// 14-Sep-2019, tatu: as per [databind#2129], must NOT use this feature but
293+
// instead new `WRITE_ENUM_KEYS_USING_INDEX` added in 2.10
291294
json = MAPPER.writer()
292295
.with(SerializationFeature.WRITE_ENUMS_USING_INDEX)
293296
.writeValueAsString(bean);
294-
assertEquals(aposToQuotes("{'map':{'"+TestEnum.B.ordinal()+"':3}}"), json);
297+
// assertEquals(aposToQuotes("{'map':{'"+TestEnum.B.ordinal()+"':3}}"), json);
298+
assertEquals(aposToQuotes("{'map':{'B':3}}"), json);
295299
}
296300

297301
public void testAsIndex() throws Exception

src/test/java/com/fasterxml/jackson/failing/EnumAsIndexMapKey1877Test.java

-63
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.fasterxml.jackson.failing;
2+
3+
import java.util.*;
4+
5+
import com.fasterxml.jackson.databind.*;
6+
7+
public class EnumAsIndexMapKey2129Test extends BaseMapTest
8+
{
9+
// [databind#2129]
10+
public enum Type {
11+
FIRST,
12+
SECOND;
13+
}
14+
15+
static class TypeContainer {
16+
public Map<Type, Integer> values;
17+
18+
public TypeContainer(Type type, int value) {
19+
values = Collections.singletonMap(type, value);
20+
}
21+
}
22+
23+
final ObjectMapper MAPPER = newJsonMapper();
24+
25+
// [databind#2129]
26+
public void testEnumAsIndexForRootMap() throws Exception
27+
{
28+
final Map<Type, Integer> input = Collections.singletonMap(Type.FIRST, 3);
29+
30+
// by default, write using name()
31+
assertEquals(aposToQuotes("{'FIRST':3}"),
32+
MAPPER.writeValueAsString(input));
33+
34+
// but change with setting
35+
assertEquals(aposToQuotes("{'0':3}"),
36+
MAPPER.writer()
37+
.with(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX)
38+
.writeValueAsString(input));
39+
40+
// but NOT with value settings
41+
assertEquals(aposToQuotes("{'FIRST':3}"),
42+
MAPPER.writer()
43+
.with(SerializationFeature.WRITE_ENUMS_USING_INDEX)
44+
.writeValueAsString(input));
45+
}
46+
47+
// [databind#2129]
48+
public void testEnumAsIndexForValueMap() throws Exception
49+
{
50+
final TypeContainer input = new TypeContainer(Type.SECOND, 72);
51+
52+
// by default, write using name()
53+
assertEquals(aposToQuotes("{'values':{'SECOND':72}}"),
54+
MAPPER.writeValueAsString(input));
55+
56+
// but change with setting
57+
assertEquals(aposToQuotes("{'values':{'1':72}}"),
58+
MAPPER.writer()
59+
.with(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX)
60+
.writeValueAsString(input));
61+
62+
// but NOT with value settings
63+
assertEquals(aposToQuotes("{'values':{'SECOND':72}}"),
64+
MAPPER.writer()
65+
.with(SerializationFeature.WRITE_ENUMS_USING_INDEX)
66+
.writeValueAsString(input));
67+
}
68+
}

0 commit comments

Comments
 (0)