Hi all,

This is a request for feedback on how to distinquish null from empty string 
for LocalDate and LocalDateTime deserialization, issue #114 
<https://github.com/FasterXML/jackson-modules-java8/issues/114>

To summarize the issue and possible solutions:

beytun (issue submitter) writes:
 

> For LocalDate and LocalDateTime deserialization, empty string is mapped to 
>> null by LocalDateDeserializer 
>> <https://github.com/FasterXML/jackson-modules-java8/blob/master/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java>
>>  
>> and LocalDateTimeDeserializer 
>> <https://github.com/FasterXML/jackson-modules-java8/blob/master/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserializer.java>
>>  
>> respectively. So something like {"date": null} can't be distinguished from 
>> {"date": ""}. From the view of a strict API, the latter is an error.
>>
>> It would be good to add some feature to treat empty string as invalid 
>> format, that LocalDateDeserializer and LocalDateTimeDeserializer could 
>> report this as an error instead of mapping to null.
>>
>
Tatu writes:

*Perhaps use of DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT 
> would work here, although my main concern is that since default value is 
> false, adding a check would make formerly accepted values invalid with 
> 2.10...*
>
> *Alternative way would be to add a new option/feature in JavaTimeModule, 
> where it could be locally enabled/disabled.*
>

Now, given beytun's point about 'strict', perhaps another solution is to 
use the lenient/strict setting here? That is already used in 
LocalDateDeserializer to throw an exception:

 if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
   if (!isLenient()) {
     return _failForNotLenient(parser, context, JsonToken.VALUE_STRING);
   }
   return LocalDate.ofEpochDay(parser.getLongValue());
 }


Test case to illustrate issue:

private final TypeReference<Map<String, LocalDate>> MAP_TYPE_REF = new 
TypeReference<Map<String, LocalDate>>() { };
private final ObjectMapper LOCAL_DATE_MAPPER = newMapper();
private final ObjectReader LOCAL_DATE_READER = 
LOCAL_DATE_MAPPER.readerFor(MAP_TYPE_REF);

@Test
public void testDeserializationNullAndEmptyString() throws Exception {
 String dateValAsNullStr = null;

 String valueFromNullStr = LOCAL_DATE_MAPPER.writeValueAsString(asMap("date", 
dateValAsNullStr));
 Map<String, LocalDate> actualMapFromNullStr = 
LOCAL_DATE_READER.readValue(valueFromNullStr);
 assertNull(actualMapFromNullStr.get("date"));

 String dateValAsEmptyStr = "";
 String valueFromEmptyStr = LOCAL_DATE_MAPPER.writeValueAsString(asMap("date", 
dateValAsEmptyStr));
 Map<String, LocalDate> actualMapFromEmptyStr = 
LOCAL_DATE_READER.readValue(valueFromEmptyStr);
 // this test fails!
 assertNotEquals(actualMapFromEmptyStr,actualMapFromNullStr);
}



Researching a bit, there doesn't seem to be anything in the spec that says *not 
*to do it as beytun suggests:

https://stackoverflow.com/questions/9619852/what-is-the-convention-in-json-for-empty-vs-null?noredirect=1&lq=1
https://www.ibm.com/support/knowledgecenter/SSTLXK_7.5.1/com.ibm.wbpm.wid.integ.doc/topics/rjsonnullunsempprops.html

Speaking of nulls, Tony Hoare calls this his "billion-dollar" mistake. 
Initially I disagreed but now I'm not so sure :)
https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/



-- 
You received this message because you are subscribed to the Google Groups 
"jackson-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jackson-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jackson-dev/f98b3a71-c408-4eb9-a029-743dcf1f73af%40googlegroups.com.

Reply via email to