Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,19 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt)
if (_skipNullValues) {
continue;
}
value = _nullProvider.getNullValue(ctxt);
value = null;
} else {
value = _deserializeNoNullChecks(p, ctxt);
}

if (value == null) {
value = _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
continue;
}
}

if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
ix = 0;
Expand Down Expand Up @@ -275,10 +284,19 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt,
if (_skipNullValues) {
continue;
}
value = _nullProvider.getNullValue(ctxt);
value = null;
} else {
value = _deserializeNoNullChecks(p, ctxt);
}

if (value == null) {
value = _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
continue;
}
}

if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
ix = 0;
Expand Down Expand Up @@ -346,7 +364,7 @@ protected Object handleNonArray(JsonParser p, DeserializationContext ctxt)
if (_skipNullValues) {
return _emptyValue;
}
value = _nullProvider.getNullValue(ctxt);
value = null;
} else {
if (p.hasToken(JsonToken.VALUE_STRING)) {
String textValue = p.getText();
Expand All @@ -371,6 +389,15 @@ protected Object handleNonArray(JsonParser p, DeserializationContext ctxt)

value = _deserializeNoNullChecks(p, ctxt);
}

if (value == null) {
value = _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
return _emptyValue;
}
}

// Ok: bit tricky, since we may want T[], not just Object[]
Object[] result;

Expand Down Expand Up @@ -399,4 +426,3 @@ protected Object _deserializeNoNullChecks(JsonParser p, DeserializationContext c
return _elementDeserializer.deserializeWithType(p, ctxt, _elementTypeDeserializer);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,17 @@ public String[] deserialize(JsonParser p, DeserializationContext ctxt) throws IO
if (_skipNullValues) {
continue;
}
value = (String) _nullProvider.getNullValue(ctxt);
} else {
value = _parseString(p, ctxt, _nullProvider);
}

if (value == null) {
value = (String) _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
continue;
}
}
}
if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
Expand Down Expand Up @@ -219,13 +226,22 @@ private String[] _deserializeCustom(JsonParser p, DeserializationContext ctxt,
if (_skipNullValues) {
continue;
}
value = (String) _nullProvider.getNullValue(ctxt);
value = null;
} else {
value = deser.deserialize(p, ctxt);
}
} else {
value = deser.deserialize(p, ctxt);
}

if (value == null) {
value = (String) _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
continue;
}
}

if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
ix = 0;
Expand Down Expand Up @@ -283,10 +299,17 @@ public String[] deserialize(JsonParser p, DeserializationContext ctxt,
if (_skipNullValues) {
return NO_STRINGS;
}
value = (String) _nullProvider.getNullValue(ctxt);
} else {
value = _parseString(p, ctxt, _nullProvider);
}

if (value == null) {
value = (String) _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
continue;
}
}
}
if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,18 @@ public Collection<String> deserialize(JsonParser p, DeserializationContext ctxt,
if (_skipNullValues) {
continue;
}
value = (String) _nullProvider.getNullValue(ctxt);
} else {
value = _parseString(p, ctxt, _nullProvider);
}

if (value == null) {
value = (String) _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
continue;
}
}

result.add(value);
}
} catch (Exception e) {
Expand Down Expand Up @@ -246,13 +254,22 @@ private Collection<String> deserializeUsingCustom(JsonParser p, DeserializationC
if (_skipNullValues) {
continue;
}
value = (String) _nullProvider.getNullValue(ctxt);
value = null;
} else {
value = deser.deserialize(p, ctxt);
}
} else {
value = deser.deserialize(p, ctxt);
}

if (value == null) {
value = (String) _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
continue;
}
}

result.add(value);
}
} catch (Exception e) {
Expand Down Expand Up @@ -297,7 +314,7 @@ private final Collection<String> handleNonArray(JsonParser p, DeserializationCon
if (_skipNullValues) {
return result;
}
value = (String) _nullProvider.getNullValue(ctxt);
value = null;
} else {
if (p.hasToken(JsonToken.VALUE_STRING)) {
String textValue = p.getText();
Expand Down Expand Up @@ -326,6 +343,15 @@ private final Collection<String> handleNonArray(JsonParser p, DeserializationCon
throw JsonMappingException.wrapWithPath(e, result, result.size());
}
}

if (value == null) {
value = (String) _nullProvider.getNullValue(ctxt);

if (value == null && _skipNullValues) {
return result;
}
}

result.add(value);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.fasterxml.jackson.databind.deser.jdk;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.InvalidNullException;
import com.fasterxml.jackson.databind.json.JsonMapper;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

// For [databind#5165]
public class ObjectArrayDeserializer5165Test
{
static class Dst {
private Integer[] array;

public Integer[] getArray() {
return array;
}

public void setArray(Integer[] array) {
this.array = array;
}
}

@Test
public void nullsFailTest() {
ObjectMapper mapper = JsonMapper.builder()
.defaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.FAIL))
.build();

assertThrows(
InvalidNullException.class,
() -> mapper.readValue("{\"array\":[\"\"]}", new TypeReference<Dst>(){})
);
}

@Test
public void nullsSkipTest() throws Exception {
ObjectMapper mapper = JsonMapper.builder()
.defaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.SKIP))
.build();

Dst dst = mapper.readValue("{\"array\":[\"\"]}", new TypeReference<Dst>() {});

assertEquals(0, dst.getArray().length, "Null values should be skipped");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.fasterxml.jackson.databind.deser.jdk;

import java.io.IOException;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidNullException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

// For [databind#5165]
public class StringArrayDeserializer5165Test
{
static class Dst {
private String[] array;

public String[] getArray() {
return array;
}

public void setArray(String[] array) {
this.array = array;
}
}

// Custom deserializer that converts empty strings to null
static class EmptyStringToNullDeserializer extends StdDeserializer<String> {
private static final long serialVersionUID = 1L;

public EmptyStringToNullDeserializer() {
super(String.class);
}

@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getValueAsString();
if (value != null && value.isEmpty()) {
return null;
}
return value;
}
}

private ObjectMapper createMapperWithCustomDeserializer() {
SimpleModule module = new SimpleModule();
module.addDeserializer(String.class, new EmptyStringToNullDeserializer());

return JsonMapper.builder()
.addModule(module)
.defaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.FAIL))
.build();
}

@Test
public void nullsFailTest() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as with Object[], no nulls exists in test JSON; test does not trigger handling at all.

ObjectMapper mapper = createMapperWithCustomDeserializer();

assertThrows(
InvalidNullException.class,
() -> mapper.readValue("{\"array\":[\"\"]}", new TypeReference<Dst>(){})
);
}

@Test
public void nullsSkipTest() throws Exception {
SimpleModule module = new SimpleModule();
module.addDeserializer(String.class, new EmptyStringToNullDeserializer());

ObjectMapper mapper = JsonMapper.builder()
.addModule(module)
.defaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.SKIP))
.build();

Dst dst = mapper.readValue("{\"array\":[\"\"]}", new TypeReference<Dst>() {});

assertEquals(0, dst.getArray().length, "Null values should be skipped");
}
}
Loading