jsonp-api icon indicating copy to clipboard operation
jsonp-api copied to clipboard

Provide API to define behavior of JsonObjectBuilder.add when value is null

Open wesleyegberto opened this issue 7 years ago • 2 comments

Hi All I don't know if any one have already requested this (I couldn't find).

Would be nice to have a way to define the default behavior of the methods JsonObjectBuilder.add(Strig name, XXX value) when the received value is NULL.

3 behaviors could be provided:

  • Throw exception: current behavior, it should be default;
  • Ignore: the call wouldn't have any effect (just return);
  • Serialize null

Motivation

I often have to wrap the JsonObjectBuilder or create helper methods to handle the null value of my object. E.g.:

Json.createObjectBuilder()
    .add("nickname", Helper.emptyIfNull(person.getNickname()))
    .add("email", Helper.jsonNullIfNull(person.getEmail()))
    .build();
CustomObjectBuilder.from(Json.createObjectBuilder())
    .add("nickname", person.getNickname())
    .add("email", person.getEmail())
    .build();
JsonObjectBuilder builder = Json.createObjectBuilder();
if (person.getNickname() != null)
    builder.add("nickname", person.getNickname());
else
    builder.add("nickname", "");
if (person.getEmail() != null)
    builder.add("email", person.getEmail());

Proposal

Provide new methods on JsonObjectBuilder to define the behavior.

1 - Ignore null

This should set the JsonObjectBuilder to ignore the call when the value is null.

Code:

Json.createObjectBuilder()
    .ignoreNull()
    .add("name", "John Due")
    .add("nickname", null)
    .build();

Expected output:

{
  "name": "John Due"
}

2 - Serialize null

This should set the JsonObjectBuilder to serialize the JsonValue.NULL when the value is null.

Code:

Json.createObjectBuilder()
    .serializeNull()
    .add("name", "John Due")
    .add("nickname", null)
    .build();

Expected output:

{
  "name": "John Due",
  "nickname": null
}

3 - Throw exception

This is the current behavior and should be the default behavior to keep compatibilities.

Code:

Json.createObjectBuilder()
    .forbidNull()
    .add("nickname", null)
    .build();

Expected: NullPointerException

This is something I miss on Json-P because I use it often to avoid DTO.

Thank you

wesleyegberto avatar Jul 07 '18 19:07 wesleyegberto

If throwing a NPE is the default, then .forbidNull() seems irrelevant. If you don't do anything and null is given it would throw an exception. The others look reasonable at least IMO.

keilw avatar Jul 09 '18 13:07 keilw

Hi,

I know is too soon but I was trying to start a basic implementation and a doubt come up.

Can we use JDK 8 features like lambda or we should keep the JDK 5/6/7 (if there is such restriction)?

I started implementing it on JsonObjectBuilder.add(String, String) and with Lambda we could simplify so much:

Instead of repeat the following structure:

@Override
public JsonObjectBuilder add(String name, String value) {
    validateName(name);
    if (shouldIgnore(value)) {
    	return this;
    }
    if (shouldAddNull(value)) {
    	return addNull(name);
    }
    validateValue(value);
    putValueMap(name, new JsonStringImpl(value));
    return this;
}

We could just use:

@Override
public JsonObjectBuilder add(String name, String value) {
    validateName(name);
    return handleAndAddValue(name, value, JsonStringImpl::new);
}

private <T, R extends JsonValue> JsonObjectBuilder handleAndAddValue(String name, T value, Function<T, R> valueTransformer) {
    JsonValue valueToAdd = null;
    if (value == null) {
        switch (nullValueSerializationBehavior) {
            case IGNORE:
                return this;
            case SERIALIZE:
                valueToAdd = JsonValue.NULL;
                break;
            default:
                throw new NullPointerException(JsonMessages.OBJBUILDER_VALUE_NULL());
        }
    } else {
        valueToAdd = valueTransformer.apply(value);
    }
    putValueMap(name, valueToAdd);
    return this;
}

Here you can see a commit the code and test cases.

Thank you

wesleyegberto avatar Oct 04 '18 04:10 wesleyegberto