users@jsonb-spec.java.net

[jsonb-spec users] [jsr367-experts] Re: JSONB De/Serializers proposal

From: Romain Manni-Bucau <rmannibucau_at_tomitribe.com>
Date: Wed, 27 Apr 2016 14:43:29 +0200

Hi Roman,

Few points but globally I think we move in the right direction!

- "extends JsonXXX" I'd replace the extends by a delegation to keep the
fluent API typed (= return type is JsonbXXX and not JsonXXX) and control
over jsonb API.
- I don't fully get the difference between context and JsonbXXX, i'd merge
them (otherwise we would just using jsonp API but as mentionned in previous
point it has the drawback to loose all the control.
- deserialization: we still need the type found by the runtime (reflection)
otherwise we can't allow generic serializers at all



Romain Manni-Bucau
@rmannibucau
http://www.tomitribe.com
http://rmannibucau.wordpress.com
https://github.com/rmannibucau

2016-04-27 14:33 GMT+02:00 Roman Grigoriadi <roman.grigoriadi_at_oracle.com>:

> Hi experts,
>
> following previous discussions for including de/serializers in JSONB along
> with adapters, here is proposal for interfaces in JSONB API:
>
> public interface JsonbSerializer<T> { void serialize(T obj, JsonbGenerator generator, SerializationContext ctx);
> }
>
> public interface JsonbDeserializer<T> { T deserialize(JsonbParser parser, DeserializationContext ctx);
> }
> /** * Jsonb decorator for JSONP generator. Includes validation for writing END_OBJECT / END_ARRAY checking level of closed JSON structure.
> * Helper generator methods may be added here. */public interface JsonbGenerator extends JsonGenerator {
> }
>
> /** * Jsonb decorator for JSONP parser. Includes validation of cursor
> position after leaving deserializer, alters hasNext() behavior. * Helper
> parser methods may be added here. */ public interface JsonbParser extends
> JsonParser { }
>
> public interface SerializationContext { /** * Serializes arbitrary object
> to JSON with JSONB, using current {_at_link javax.json.stream.JsonGenerator}
> instance. */ <T> void serialize(String key, T object); /** * Checks if
> type is supported for conversion to string by JSONB. */ boolean supportsConversion(Class<?>
> clazz); /** * Converts string value into provided type. String value has
> to be single JSON value, not a part * of a JSON document representing
> JSON object / array. */ <T> String convertDefault(T obj); }
>
> public interface DeserializationContext { /** * Deserializes JSON stream
> into instance of provided class with JSONB using {_at_link javax.json.stream.JsonParser}.
> * JsonParser cursor have to be at KEY_NAME before START_OBJECT to call
> this method. */ <T> T deserialize(Class<T> clazz); /** * Similar as above
> for generic types. */ <T> T deserialize(TypeInfo<T> typeInfo); /** *
> Checks if type is supported for conversion from string by JSONB. */ boolean
> supportsConversion(Class<?> toClass); /** * Converts string value into
> provided type. String value has to be single JSON value, not a part * of
> a JSON document representing JSON object. */ <T> T convertDefault(Class<T>
> toClass, String value); } JsonbParser / JsonbGenerator objects are supposed
> to decorate JSONP behavior. For example in case of JsonParser hasNext()
> call may be altered to return false if currently deserialized object has
> ended in the stream. Helper methods (like nextKey(String), isKey(String),
> etc for json processing may be included here. In addition to
> Generators/Parsers, (De)SerializationContexts are intended to provide JSONB
> functionality such as (de)serialization of arbitrary java types, conversion
> to/from string of known types such are Dates or Numbers. We could also add
> some insight into introspected customization from JSONB annotations based
> on a Class and property name. An example of how implementation of such
> (de)serializer may look: public class CrateSerializer implements JsonbSerializer<Crate>
> { @Override public void serialize(Crate obj, JsonbGenerator generator,
> SerializationContext ctx) { generator.write("crateStr", "REPLACED");
> ctx.serialize("crateInner", obj.crateInner); ctx.serialize(
> "crateInnerList", obj.crateInnerList); generator.write("date-converted",
> dateValue); } } public class CrateDeserializer implements JsonbDeserializer<Crate>
> { @Override public Crate deserialize(JsonbParser jsonParser,
> DeserializationContext ctx) { Crate crate = new Crate(); while (jsonParser.hasNext())
> { JsonParser.Event next = jsonParser.next(); if
> (next.equals(JsonParser.Event.KEY_NAME) && jsonParser.getString().equals(
> "crateInner")) { //invokes JSONB processing for a CrateInner as a root
> type with "shared" instance of JsonParser //may invoke other serializer
> or adapter instances inside crate.crateInner = ctx.deserialize(CrateInner.
> class); next = jsonParser.next(); } if (next.equals(JsonParser.Event.
> KEY_NAME) && jsonParser.getString().equals("crateInnerList")) { //invokes
> JSONB processing for a List<CrateInner> as a root type with "shared"
> instance of JsonParser //may invoke other serializer or adapter instances
> inside crate.crateInnerList = ctx.deserialize(new TypeToken<List<CrateInner>>()
> {}); } if (next.equals(JsonParser.Event.KEY_NAME) &&
> jsonParser.getString().equals("date-converted")) { jsonParser.next(); //don't
> have context of processing here, no annotation customizations applied. Date
> converted = ctx.convertDefault(Date.class, jsonParser.getString()); crate.date
> = converted; } } return crate; } }
>
> @Romain, this is similar to what you have suggested first time. In
> addition JsonbAdapters may be used to convert From / To JsonObject or
> JsonArray, but auto conversion between unknown JavaTypes and JsonStructure
> will not be supported, at least in first version of a spec.
>
> WDYT? Thanks, Roman
>
>