Skip to content

Commit

Permalink
Add JavaDoc and test wrt custom JsonDeserializers null handling (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
JooHyukKim authored Jun 22, 2024
1 parent 8d96e83 commit f8c1363
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/main/java/com/fasterxml/jackson/databind/JsonDeserializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,17 @@ public abstract class JsonDeserializer<T>
* fails, event that was not recognized or usable, which may be
* the same event as the one it pointed to upon call).
*<p>
* Note that this method is never called for JSON null literal,
* and thus deserializers need (and should) not check for it.
* <strong>Handling null values (JsonToken.VALUE_NULL)</strong>
* <br>
* : Note that this method is never called for the JSON {@code null} literal to avoid
* every deserializer from having to handle null values. Instead, the
* {@link JsonDeserializer#getNullValue(DeserializationContext)} method
* is called to produce a null value. To influence null handling,
* custom deserializers should override
* {@link JsonDeserializer#getNullValue(DeserializationContext)}
* and usually also {@link JsonDeserializer#getNullAccessPattern()}.
*
* @param p Parsed used for reading JSON content
* @param p Parser used for reading JSON content
* @param ctxt Context that can be used to access information about
* this deserialization activity.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.fasterxml.jackson.databind.deser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Test to check that getNullValue for deserializer is not cached, by default.
*/
public class CustomDeserializers4225NullCacheTest extends DatabindTestUtil
{
static class CustomListDeserializer extends JsonDeserializer<List<String>> {

private static int getNullValueInvocationCount = 0;

@Override
public List<String> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
return makeList("regular");
}

@Override
public List<String> getNullValue(DeserializationContext ctxt) throws JsonMappingException {
// Increment invocation count
getNullValueInvocationCount++;
return makeList("nullVal_" + getNullValueInvocationCount);
}

public List<String> makeList(String content) {
List<String> randomList = new ArrayList<>();
randomList.add(content);
return randomList;
}
}

static class Bean4225 {
@JsonDeserialize(using = CustomListDeserializer.class)
public List<String> myList;
}

@Test
public void testGetNullValueIsCached() throws Exception
{
ObjectMapper mapper = newJsonMapper();

// First time deserializing null
verifyGetNullValueInvokedTimes(mapper, 1);
// Second time deserializing null, should be invoked twice
verifyGetNullValueInvokedTimes(mapper, 2);
}

private void verifyGetNullValueInvokedTimes(ObjectMapper mapper, int times)
throws Exception
{
Bean4225 someBean = mapper.readValue(a2q("{'myList': null}"), Bean4225.class);

assertThat(someBean.myList).hasSize(1);
assertThat(someBean.myList.get(0)).isEqualTo("nullVal_" + times);
assertThat(CustomListDeserializer.getNullValueInvocationCount).isEqualTo(times);
}
}

0 comments on commit f8c1363

Please sign in to comment.