下面列出了怎么用com.fasterxml.jackson.annotation.Nulls的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
Boolean unwrapSingle = findFormatFeature(ctxt, property, _valueClass,
JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
NullValueProvider nuller = null;
Nulls nullStyle = findContentNullStyle(ctxt, property);
if (nullStyle == Nulls.SKIP) {
nuller = NullsConstantProvider.skipper();
} else if (nullStyle == Nulls.FAIL) {
if (property == null) {
nuller = NullsFailProvider.constructForRootValue(ctxt.constructType(_valueClass));
} else {
nuller = NullsFailProvider.constructForProperty(property);
}
}
if ((unwrapSingle == _unwrapSingle) && (nuller == _nuller)) {
return this;
}
return withResolved(nuller, unwrapSingle);
}
public void testFailOnNullWithDefaults() throws Exception
{
// also: config overrides by type should work
String json = aposToQuotes("{'name':null}");
NullsForString def = MAPPER.readValue(json, NullsForString.class);
assertNull(def.getName());
ObjectMapper mapper = afterburnerMapperBuilder()
.withConfigOverride(String.class,
o -> o.setNullHandling(JsonSetter.Value.forValueNulls(Nulls.FAIL)))
.build();
try {
mapper.readValue(json, NullsForString.class);
fail("Should not pass");
} catch (InvalidNullException e) {
verifyException(e, "property \"name\"");
}
}
public void testNullsToEmptyScalar() throws Exception
{
NullAsEmpty result = MAPPER.readValue(aposToQuotes("{'nullAsEmpty':'foo', 'nullsOk':null}"),
NullAsEmpty.class);
assertEquals("foo", result.nullAsEmpty);
assertNull(result.nullsOk);
// and then see that nulls are not ok for non-nullable
result = MAPPER.readValue(aposToQuotes("{'nullAsEmpty':null}"),
NullAsEmpty.class);
assertEquals("", result.nullAsEmpty);
// also: config overrides by type should work
String json = aposToQuotes("{'name':null}");
NullsForString def = MAPPER.readValue(json, NullsForString.class);
assertNull(def.getName());
ObjectMapper mapper = afterburnerMapperBuilder()
.withConfigOverride(String.class,
o -> o.setNullHandling(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)))
.build();
NullsForString named = mapper.readValue(json, NullsForString.class);
assertEquals("", named.getName());
}
public void testNullsAsEmptyUsingDefaults() throws Exception
{
final String JSON = aposToQuotes("{'values':[null]}");
TypeReference<NullContentUndefined<List<Integer>>> listType = new TypeReference<NullContentUndefined<List<Integer>>>() { };
// Let's see defaulting in action
ObjectMapper mapper = afterburnerMapperBuilder()
.changeDefaultNullHandling(n -> n.withContentNulls(Nulls.AS_EMPTY))
.build();
NullContentUndefined<List<Integer>> result = mapper.readValue(JSON, listType);
assertEquals(1, result.values.size());
assertEquals(Integer.valueOf(0), result.values.get(0));
// or configured for type:
mapper = afterburnerMapperBuilder()
.withConfigOverride(List.class,
o -> o.setNullHandling(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY)))
.build();
result = mapper.readValue(JSON, listType);
assertEquals(1, result.values.size());
assertEquals(Integer.valueOf(0), result.values.get(0));
}
public void testNullsSkipUsingDefaults() throws Exception
{
final String JSON = aposToQuotes("{'values':[null]}");
TypeReference<NullContentUndefined<List<Long>>> listType = new TypeReference<NullContentUndefined<List<Long>>>() { };
// Let's see defaulting in action
ObjectMapper mapper = afterburnerMapperBuilder()
.changeDefaultNullHandling(n -> n.withContentNulls(Nulls.SKIP))
.build();
NullContentUndefined<List<Long>> result = mapper.readValue(JSON, listType);
assertEquals(0, result.values.size());
// or configured for type:
mapper = afterburnerMapperBuilder()
.withConfigOverride(List.class,
o -> o.setNullHandling(JsonSetter.Value.forContentNulls(Nulls.SKIP)))
.build();
result = mapper.readValue(JSON, listType);
assertEquals(0, result.values.size());
}
public void testNullsSkipWithOverrides() throws Exception
{
final String JSON = aposToQuotes("{'values':[null]}");
TypeReference<NullContentSkip<List<Long>>> listType = new TypeReference<NullContentSkip<List<Long>>>() { };
ObjectMapper mapper = afterburnerMapperBuilder()
// defaults call for fail; but POJO specifies "skip"; latter should win
.changeDefaultNullHandling(n -> n.withContentNulls(Nulls.FAIL))
.build();
NullContentSkip<List<Long>> result = mapper.readValue(JSON, listType);
assertEquals(0, result.values.size());
// ditto for per-type defaults
mapper = afterburnerMapperBuilder()
.withConfigOverride(List.class,
o -> o.setNullHandling(JsonSetter.Value.forContentNulls(Nulls.FAIL)))
.build();
result = mapper.readValue(JSON, listType);
assertEquals(0, result.values.size());
}
/**
* @since 2.9
*/
protected PropertyMetadata(Boolean req, String desc, Integer index, String def,
MergeInfo mergeInfo, Nulls valueNulls, Nulls contentNulls)
{
_required = req;
_description = desc;
_index = index;
_defaultValue = (def == null || def.isEmpty()) ? null : def;
_mergeInfo = mergeInfo;
_valueNulls = valueNulls;
_contentNulls = contentNulls;
}
/**
* Method called to find {@link NullValueProvider} for a contents of a structured
* primary property (Collection, Map, array), using
* "content nulls" setting. If no provider found (not defined),
* will return given value deserializer (which is a null value provider itself).
*
* @since 2.9
*/
protected NullValueProvider findContentNullProvider(DeserializationContext ctxt,
BeanProperty prop, JsonDeserializer<?> valueDeser)
throws JsonMappingException
{
final Nulls nulls = findContentNullStyle(ctxt, prop);
if (nulls == Nulls.SKIP) {
return NullsConstantProvider.skipper();
}
NullValueProvider prov = _findNullProvider(ctxt, prop, nulls, valueDeser);
if (prov != null) {
return prov;
}
return valueDeser;
}
protected Nulls findContentNullStyle(DeserializationContext ctxt, BeanProperty prop)
throws JsonMappingException
{
if (prop != null) {
return prop.getMetadata().getContentNulls();
}
return null;
}
public void testBeanMergingWithNullDefault() throws Exception
{
// By default `null` should simply overwrite value
ConfigDefault config = MAPPER.readerForUpdating(new ConfigDefault(5, 7))
.readValue(aposToQuotes("{'loc':null}"));
assertNotNull(config);
assertNull(config.loc);
// but it should be possible to override setting to, say, skip
// First: via specific type override
// important! We'll specify for value type to be merged
ObjectMapper mapper = afterburnerMapperBuilder()
.withConfigOverride(AB.class,
o -> o.setNullHandling(JsonSetter.Value.forValueNulls(Nulls.SKIP)))
.build();
config = mapper.readerForUpdating(new ConfigDefault(137, -3))
.readValue(aposToQuotes("{'loc':null}"));
assertNotNull(config.loc);
assertEquals(137, config.loc.a);
assertEquals(-3, config.loc.b);
// Second: by global defaults
mapper = afterburnerMapperBuilder()
.changeDefaultNullHandling(n -> n.withValueNulls(Nulls.SKIP))
.build();
config = mapper.readerForUpdating(new ConfigDefault(12, 34))
.readValue(aposToQuotes("{'loc':null}"));
assertNotNull(config.loc);
assertEquals(12, config.loc.a);
assertEquals(34, config.loc.b);
}
public void testSkipNullWithDefaults() throws Exception
{
String json = aposToQuotes("{'value':null}");
StringValue result = MAPPER.readValue(json, StringValue.class);
assertNull(result.value);
ObjectMapper mapper = afterburnerMapperBuilder()
.withConfigOverride(String.class,
o -> o.setNullHandling(JsonSetter.Value.forValueNulls(Nulls.SKIP)))
.build();
result = mapper.readValue(json, StringValue.class);
assertEquals("default", result.value);
}
public SyncopeXmlMapper() {
super();
registerModule(new AfterburnerModule());
registerModule(new JavaTimeModule());
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
configOverride(Set.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
configOverride(Map.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
}
@JsonSetter(nulls = Nulls.FAIL, contentNulls = Nulls.FAIL)
List<EnumValueDefinition> values();
@JsonSetter(nulls = Nulls.FAIL, contentNulls = Nulls.FAIL)
Map<FieldName, FieldDefinition> union();
@JsonSetter(nulls = Nulls.FAIL, contentNulls = Nulls.FAIL)
Map<FieldName, FieldDefinition> fields();
/**
* @since 2.9
*/
public PropertyMetadata withNulls(Nulls valueNulls,
Nulls contentNulls) {
return new PropertyMetadata(_required, _description, _index, _defaultValue,
_mergeInfo, valueNulls, contentNulls);
}
protected final NullValueProvider _findNullProvider(DeserializationContext ctxt,
BeanProperty prop, Nulls nulls, JsonDeserializer<?> valueDeser)
throws JsonMappingException
{
if (nulls == Nulls.FAIL) {
if (prop == null) {
return NullsFailProvider.constructForRootValue(ctxt.constructType(valueDeser.handledType()));
}
return NullsFailProvider.constructForProperty(prop);
}
if (nulls == Nulls.AS_EMPTY) {
// cannot deal with empty values if there is no value deserializer that
// can indicate what "empty value" is:
if (valueDeser == null) {
return null;
}
// Let's first do some sanity checking...
// NOTE: although we could use `ValueInstantiator.Gettable` in general,
// let's not since that would prevent being able to use custom impls:
if (valueDeser instanceof BeanDeserializerBase) {
ValueInstantiator vi = ((BeanDeserializerBase) valueDeser).getValueInstantiator();
if (!vi.canCreateUsingDefault()) {
final JavaType type = prop.getType();
ctxt.reportBadDefinition(type,
String.format("Cannot create empty instance of %s, no default Creator", type));
}
}
// Second: can with pre-fetch value?
{
AccessPattern access = valueDeser.getEmptyAccessPattern();
if (access == AccessPattern.ALWAYS_NULL) {
return NullsConstantProvider.nuller();
}
if (access == AccessPattern.CONSTANT) {
return NullsConstantProvider.forValue(valueDeser.getEmptyValue(ctxt));
}
}
return new NullsAsEmptyProvider(valueDeser);
}
if (nulls == Nulls.SKIP) {
return NullsConstantProvider.skipper();
}
return null;
}
@JsonSetter(nulls = Nulls.AS_EMPTY)
public void setVersions(List<String> versions) {
this.versions = versions;
}
@JsonSetter(nulls=Nulls.SKIP)
public void setNoNulls(String v) {
_noNulls = v;
}
@JsonSetter(nulls=Nulls.AS_EMPTY)
public void setValue(T v) {
value = v;
}
/**
* @since 2.9
*/
public Nulls getValueNulls() { return _valueNulls; }
/**
* @since 2.9
*/
public Nulls getContentNulls() { return _contentNulls; }