jackson-databind icon indicating copy to clipboard operation
jackson-databind copied to clipboard

RFE : PrimitiveArrayDeserializers to deal with single String value

Open cowtowncoder opened this issue 1 year ago • 2 comments

Discussed in https://github.com/FasterXML/jackson-databind/discussions/4649

Originally posted by eeren-bm July 25, 2024 I think there's a bit of asymmetry when the lib is used to deserialized into primitive array vs List of objects. Please see the below example

        String longPrim = "2247483647";
        List<String> list1 = List.of("2247483647", "2247483648");
        Long longObj = 2247483647L;
        List<Long> longList = List.of(2247483647L, 2247483648L);

        String longPrimJson = "\"2247483647\"";
        String listStringJson = "[\"2247483647\", \"2247483648\"]";
        String longObjJson = "2247483647";
        String longListJson = "[2247483647, 2247483648]";

        ObjectMapper om = new ObjectMapper();
        om.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

//long[] primResult = om.convertValue(longPrim, long[].class);
        long[] primResult2 = om.convertValue(list1, long[].class);
        long[] primResult3 = om.convertValue(longObj, long[].class);
        long[] primResult4 = om.convertValue(longList, long[].class);

//long[] primResultFromJson = om.readValue(longPrimJson, long[].class);
        long[] primResult2FromJson = om.readValue(listStringJson, long[].class);
        long[] primResult3FromJson = om.readValue(longObjJson, long[].class);
        long[] primResult4FromJson = om.readValue(longListJson, long[].class);

        List<Long> longListResult = om.convertValue(longPrim, List.class);
        List<Long> longListResult2 = om.convertValue(list1, List.class);
        List<Long> longListResult3 = om.convertValue(longObj, List.class);
        List<Long> longListResult4 = om.convertValue(longList, List.class);

        List<Long> longListResultFromJson = om.readValue(longPrimJson, List.class);
        List<Long> longListResult2FromJson = om.readValue(listStringJson, List.class);
        List<Long> longListResult3FromJson = om.readValue(longObjJson, List.class);
        List<Long> longListResult4FromJson = om.readValue(longListJson, List.class);

The commented lines are lines I would expect to generate the similar results as List<Long> without throwing exceptions.

I believe the simple fix is to remove below lines from PrimitiveArrayDeserializers class' handleNonArray() method

// Empty String can become null...
        if (p.hasToken(JsonToken.VALUE_STRING)) {
            return _deserializeFromString(p, ctxt);
        }

as they would almost certainly throw exception as getValueInstantiator() method is not being overriden to generate a sensible result. And a single string value will be dealt with correctly without above lines.

Thanks for looking ! Please kindly let me know your thoughts

cowtowncoder avatar Jul 26 '24 15:07 cowtowncoder