-
-
Notifications
You must be signed in to change notification settings - Fork 819
Closed
Milestone
Description
Since 2.10.1, it is not possible to filter out object arrays anymore.
The regression has been introduced by this (jackson-databind) commit which changed the array serialization implementation (more specifically the writeStartArray methods used):
FasterXML/jackson-databind@ca1867e
So it seems that the root cause is that the FilteringGeneratorDelegate (jackson-core) should override all JsonGenerator::writeStartArray methods.
Here is a maven project with 1 test class that reproduces the bug and offers a workaround :
filterGeneratorBug.zip
Test class :
package test;
import java.io.IOException;
import java.io.StringWriter;
import org.junit.Assert;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.filter.FilteringGeneratorDelegate;
import com.fasterxml.jackson.core.filter.JsonPointerBasedFilter;
import com.fasterxml.jackson.core.filter.TokenFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ArrayFilteringBugTest {
private static final ArrayWrapper ARRAY_WRAPPER = new ArrayWrapper(new String[] { "foo", "bar" });
static class ArrayWrapper {
@JsonProperty
private final String[] stringArray;
ArrayWrapper(String[] stringArray) {
this.stringArray = stringArray;
}
}
@Test
public void arrayFilterOut_failing() throws IOException {
StringWriter output = new StringWriter();
JsonGenerator jg = new JsonFactory().createGenerator(output);
FilteringGeneratorDelegate filteringGeneratorDelegate = new FilteringGeneratorDelegate(jg, new JsonPointerBasedFilter("/noMatch"), true, true);
new ObjectMapper().writeValue(filteringGeneratorDelegate, ARRAY_WRAPPER);
Assert.assertEquals("", output.toString());
}
@Test
public void arrayFilterOut_workaroundFix() throws IOException {
StringWriter output = new StringWriter();
JsonGenerator jg = new JsonFactory().createGenerator(output);
FilteringGeneratorDelegate filteringGeneratorDelegate = new FixedFilteringGeneratorDelegate(jg, new JsonPointerBasedFilter("/noMatch"), true, true);
new ObjectMapper().writeValue(filteringGeneratorDelegate, ARRAY_WRAPPER);
Assert.assertEquals("", output.toString());
}
static class FixedFilteringGeneratorDelegate extends FilteringGeneratorDelegate {
public FixedFilteringGeneratorDelegate(JsonGenerator d, TokenFilter f, boolean includePath, boolean allowMultipleMatches) {
super(d, f, includePath, allowMultipleMatches);
}
// !! This method may also need overriding when called by other binders !!
// @Override
// public void writeStartArray(Object forValue) throws IOException;
@Override
public void writeStartArray(Object forValue, int size) throws IOException
{
// First things first: whole-sale skipping easy
if (_itemFilter == null) {
_filterContext = _filterContext.createChildArrayContext(null, false);
return;
}
if (_itemFilter == TokenFilter.INCLUDE_ALL) { // include the whole sub-tree?
_filterContext = _filterContext.createChildArrayContext(_itemFilter, true);
delegate.writeStartArray(forValue, size);
return;
}
// Ok; regular checking state then
_itemFilter = _filterContext.checkValue(_itemFilter);
if (_itemFilter == null) {
_filterContext = _filterContext.createChildArrayContext(null, false);
return;
}
if (_itemFilter != TokenFilter.INCLUDE_ALL) {
_itemFilter = _itemFilter.filterStartArray();
}
if (_itemFilter == TokenFilter.INCLUDE_ALL) {
_checkParentPath();
_filterContext = _filterContext.createChildArrayContext(_itemFilter, true);
delegate.writeStartArray(forValue, size);
} else {
_filterContext = _filterContext.createChildArrayContext(_itemFilter, false);
}
}
}
}
Metadata
Metadata
Assignees
Labels
No labels