Skip to content

Commit 0e31167

Browse files
authored
RFE-4650: Single string value primitive array deserialization improvement (#5022)
1 parent a4c82c8 commit 0e31167

File tree

3 files changed

+62
-5
lines changed

3 files changed

+62
-5
lines changed

release-notes/VERSION-2.x

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Project: jackson-databind
2020
(contributed by Geoffrey G)
2121
#4388: Allow using `@JsonPropertyOrder` with "any" (`@JsonAnyGetter`) properties
2222
(fix by Joo-Hyuk K)
23+
#4650: `PrimitiveArrayDeserializers` should deal with single String value if
24+
`DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY` enabled
25+
(reported, fix suggested by @eeren-bm)
2326
#4674: Allow setting global enum naming strategy similar to property naming strategy
2427
(requested by @hajdamak)
2528
(contributed by Konstantin M)

src/main/java/com/fasterxml/jackson/databind/deser/std/PrimitiveArrayDeserializers.java

+11-5
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,19 @@ public T deserialize(JsonParser p, DeserializationContext ctxt, T existing) thro
213213
@SuppressWarnings("unchecked")
214214
protected T handleNonArray(JsonParser p, DeserializationContext ctxt) throws IOException
215215
{
216-
// Empty String can become null...
217-
if (p.hasToken(JsonToken.VALUE_STRING)) {
218-
return _deserializeFromString(p, ctxt);
219-
}
220-
boolean canWrap = (_unwrapSingle == Boolean.TRUE) ||
216+
217+
final boolean canWrap = (_unwrapSingle == Boolean.TRUE) ||
221218
((_unwrapSingle == null) &&
222219
ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
220+
// 12-Mar-2025, tatu: as per [databind#4650] things get bit tricky with
221+
// single-element wrapping of a String value
222+
// Let's still call _deserializeFromString() for empty strings no matter what,
223+
// and for all values if wrapping not enabled
224+
if (p.hasToken(JsonToken.VALUE_STRING)) {
225+
if (!canWrap || _isBlank(p.getText())) {
226+
return _deserializeFromString(p, ctxt);
227+
}
228+
}
223229
if (canWrap) {
224230
return handleSingleElementUnwrapped(p, ctxt);
225231
}

src/test/java/com/fasterxml/jackson/databind/deser/jdk/ArrayDeserializationTest.java

+48
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
1313
import com.fasterxml.jackson.databind.module.SimpleModule;
1414

15+
import static com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY;
1516
import static org.junit.jupiter.api.Assertions.*;
1617

1718
import static com.fasterxml.jackson.databind.testutil.DatabindTestUtil.a2q;
@@ -542,6 +543,53 @@ public void testFloatArray() throws Exception
542543
}
543544
}
544545

546+
@Test
547+
public void testSingleStringToPrimitiveArray() throws JsonProcessingException {
548+
MAPPER.enable(ACCEPT_SINGLE_VALUE_AS_ARRAY);
549+
assertLengthValue(MAPPER.readValue("\"true\"", boolean[].class), true);
550+
assertLengthValue(MAPPER.readValue("\"a\"", char[].class), 'a');
551+
assertLengthValue(MAPPER.readValue("\"1\"", short[].class), (short) 1);
552+
assertLengthValue(MAPPER.readValue("\"1\"", int[].class), 1);
553+
assertLengthValue(MAPPER.readValue("\"1\"", long[].class), 1L);
554+
assertLengthValue(MAPPER.readValue("\"7.038531e-26\"", float[].class), 7.038531e-26f);
555+
assertLengthValue(MAPPER.readValue("\"1.5555\"", double[].class), 1.5555d);
556+
}
557+
558+
private void assertLengthValue(boolean[] arr, boolean expt) {
559+
assertEquals(1, arr.length);
560+
assertEquals(expt, arr[0]);
561+
}
562+
563+
private void assertLengthValue(char[] arr, char expt) {
564+
assertEquals(1, arr.length);
565+
assertEquals(expt, arr[0]);
566+
}
567+
568+
private void assertLengthValue(short[] arr, short expt) {
569+
assertEquals(1, arr.length);
570+
assertEquals(expt, arr[0]);
571+
}
572+
573+
private void assertLengthValue(int[] arr, int expt) {
574+
assertEquals(1, arr.length);
575+
assertEquals(expt, arr[0]);
576+
}
577+
578+
private void assertLengthValue(long[] arr, long expt) {
579+
assertEquals(1, arr.length);
580+
assertEquals(expt, arr[0]);
581+
}
582+
583+
private void assertLengthValue(float[] arr, float expt) {
584+
assertEquals(1, arr.length);
585+
assertEquals(expt, arr[0]);
586+
}
587+
588+
private void assertLengthValue(double[] arr, double expt) {
589+
assertEquals(1, arr.length);
590+
assertEquals(expt, arr[0]);
591+
}
592+
545593
/*
546594
/**********************************************************
547595
/* Tests for Bean arrays

0 commit comments

Comments
 (0)