Details
-
Type:
New Feature
-
Status:
Open
-
Priority:
Minor
-
Resolution: Unresolved
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: Deserializer
-
Labels:None
-
Number of attachments :
Description
Jackson deserializes any primitive JSON value to a String, if requested to do so. (By default, a JSON null value is deserialized to a null reference, even if a String were requested.)
Similar functionality for JSON arrays and objects to be forced to String types using the databinding API is not currently available.
Jackson should be enhanced to provide functionality to allow the user to accept any arbitrary JSON structure as a String. One possible mechanism for the user to specify that such processing is desired could be as a DeserializationConfig Feature. The following code demonstrates use of such a feature, as well as some of the current relevant behavior.
ObjectMapper mapper = new ObjectMapper(); String json1 = "1"; System.out.println(mapper.readValue(json1, String.class)); String json2 = "true"; System.out.println(mapper.readValue(json2, String.class)); String json3 = "null"; String result3 = mapper.readValue(json3, String.class); System.out.println(result3); System.out.println(result3 == null); // true // input: {"one":1} String json4 = "{\"one\":1}"; // throws JsonMappingException, complaining: // Can not deserialize instance of java.lang.String // out of START_OBJECT token // System.out.println(mapper.readValue(json4, String.class)); // prefer a String with value {"one":1} String json5 = "[42]"; // throws JsonMappingException, complaining: // Can not deserialize instance of java.lang.String // out of START_ARRAY token // System.out.println(mapper.readValue(json5, String.class)); // prefer a String with value [42] mapper.configure(DeserializationConfig.Feature.ACCEPT_ALL_AS_STRING, true); System.out.println(mapper.readValue(json4, String.class)); // output: {"one":1} System.out.println(mapper.readValue(json4, String.class).length()); // output: 9 System.out.println(mapper.readValue(json5, String.class)); // output: [42] System.out.println(mapper.readValue(json5, String.class).length()); // output: 4 // To explain with demonstration that this feature request is not just for root level processing... // input: {"one":1,"two":{"three":"3","four":false}} String json6 = "{\"one\":1,\"two\":{\"three\":\"3\",\"four\":false}}"; Example6 ex6 = mapper.readValue(json6, Example6.class); System.out.println(ex6); // output: {one:1, two:{"three":"3","four":false}}
For per-field configurability of this feature, an annotation should also be introduced to turn the functionality on or off. If the ObjectMapper were configured with DeserializationConfig.Feature.ACCEPT_ALL_AS_STRING as false, then the annotation could turn it on for a particular field. If the ObjectMapper were configured with DeserializationConfig.Feature.ACCEPT_ALL_AS_STRING as true, then the annotation could turn it off for a particular field.
For even greater configurability, similar class level annotation processing should be introduced.