Skip to content

RFE-4650: Single string value primitive array deserialization improvement #5022

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
3 changes: 3 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Project: jackson-databind
(contributed by Geoffrey G)
#4388: Allow using `@JsonPropertyOrder` with "any" (`@JsonAnyGetter`) properties
(fix by Joo-Hyuk K)
#4650: `PrimitiveArrayDeserializers` should deal with single String value if
`DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY` enabled
(reported, fix suggested by @eeren-bm)
#4674: Allow setting global enum naming strategy similar to property naming strategy
(requested by @hajdamak)
(contributed by Konstantin M)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,19 @@ public T deserialize(JsonParser p, DeserializationContext ctxt, T existing) thro
@SuppressWarnings("unchecked")
protected T handleNonArray(JsonParser p, DeserializationContext ctxt) throws IOException
{
// Empty String can become null...
if (p.hasToken(JsonToken.VALUE_STRING)) {
return _deserializeFromString(p, ctxt);
}
boolean canWrap = (_unwrapSingle == Boolean.TRUE) ||

final boolean canWrap = (_unwrapSingle == Boolean.TRUE) ||
((_unwrapSingle == null) &&
ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
// 12-Mar-2025, tatu: as per [databind#4650] things get bit tricky with
// single-element wrapping of a String value
// Let's still call _deserializeFromString() for empty strings no matter what,
// and for all values if wrapping not enabled
if (p.hasToken(JsonToken.VALUE_STRING)) {
if (!canWrap || _isBlank(p.getText())) {
return _deserializeFromString(p, ctxt);
}
}
if (canWrap) {
return handleSingleElementUnwrapped(p, ctxt);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

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

import static com.fasterxml.jackson.databind.testutil.DatabindTestUtil.a2q;
Expand Down Expand Up @@ -542,6 +543,53 @@ public void testFloatArray() throws Exception
}
}

@Test
public void testSingleStringToPrimitiveArray() throws JsonProcessingException {
MAPPER.enable(ACCEPT_SINGLE_VALUE_AS_ARRAY);
assertLengthValue(MAPPER.readValue("\"true\"", boolean[].class), true);
assertLengthValue(MAPPER.readValue("\"a\"", char[].class), 'a');
assertLengthValue(MAPPER.readValue("\"1\"", short[].class), (short) 1);
assertLengthValue(MAPPER.readValue("\"1\"", int[].class), 1);
assertLengthValue(MAPPER.readValue("\"1\"", long[].class), 1L);
assertLengthValue(MAPPER.readValue("\"7.038531e-26\"", float[].class), 7.038531e-26f);
assertLengthValue(MAPPER.readValue("\"1.5555\"", double[].class), 1.5555d);
}

private void assertLengthValue(boolean[] arr, boolean expt) {
assertEquals(1, arr.length);
assertEquals(expt, arr[0]);
}

private void assertLengthValue(char[] arr, char expt) {
assertEquals(1, arr.length);
assertEquals(expt, arr[0]);
}

private void assertLengthValue(short[] arr, short expt) {
assertEquals(1, arr.length);
assertEquals(expt, arr[0]);
}

private void assertLengthValue(int[] arr, int expt) {
assertEquals(1, arr.length);
assertEquals(expt, arr[0]);
}

private void assertLengthValue(long[] arr, long expt) {
assertEquals(1, arr.length);
assertEquals(expt, arr[0]);
}

private void assertLengthValue(float[] arr, float expt) {
assertEquals(1, arr.length);
assertEquals(expt, arr[0]);
}

private void assertLengthValue(double[] arr, double expt) {
assertEquals(1, arr.length);
assertEquals(expt, arr[0]);
}

/*
/**********************************************************
/* Tests for Bean arrays
Expand Down