jsonb-api
jsonb-api copied to clipboard
Automatically Apply jsonbadapaters
In the spirits of what JPA has done with AttributeConverter(autoApply=true)
- I would suggest the following changes and implementation of the JsonbtypeAdapter:
@JsonbAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD,ElementType.TYPE})
public @interface JsonbTypeAdapter {
//Defines if the runtime should automatically use the following adapter
//for all types as defined by the adapter implementation generic-type
//default is false
boolean autoApply() default false;
}
- The adapter interface adaptation
//Where generic-type V determines the actual type for which this adapter is associated.
public interface JsonbAdapter<V, B> {
//Adapts the user property specified to a marshallable json capable type
B adaptTo(V value);
V adaptFrom(B value)
}
- Then an example usages:
//In this case, the jsonb runtime should apply this adapter to all properties and types, for which the type is Normaltype.
//These adapters could technically be registered on application startup (for javaee)
@JsonTypeAdapter(autoApply=true)
public class CustomTypeAdapater implements JsonbAdapter<NormalType, Customtype> {
}
// example
public class CustomObject {
//Automatically, the json runtime will apply the CustomTypeAdapater without user explicitly specifying the values.
private NormalType2 normaltype;
}
- and, from which the user has to specifically annotate the field with
@JsonTypeAdapter(autoApply=false)
public class CustomTypeAdapater2 implements JsonbAdapter<NormalType2, Customtype2> {
}
// and interface
public interface JsnobAdapted {
Class<? extends JsonbAdapter> adapter();
}
//Example usage
public class CustomObject2 {
@JsnobAdapted(CustomTypeAdapater2.class)
private NormalType2 normaltype;
}
- Issue Imported From: https://github.com/javaee/jsonb-spec/issues/35
- Original Issue Raised By:@glassfishrobot
- Original Issue Assigned To: @glassfishrobot
@glassfishrobot Commented Reported by marembo2008
@glassfishrobot Commented rmannibucau said: Jsonb relies on a config instance which can hold this. JPA supports it cause it supports scanning of (explicit or not) managed types. For me this JPA spirit doesnt match jsonb even if the "global" need needs to be there.
@glassfishrobot Commented This issue was imported from java.net JIRA JSONB_SPEC-35
I like this suggestion, perhaps there is an opportunity for CDI integration here? If we were to apply some sort of bean-defining annotation on a JSON-B adapter, then JSON-B could automatically discover it, for example:
@ApplicationScoped
public class CustomTypeAdapater2 implements JsonbAdapter<NormalType2, Customtype2> {
}
+1 with an explicit registration like in other specs, @RegisterAdapter maybe. Note it can be on methods and fields too for producers.
Something like this to auto register adapter would be nice:
@JsonBAdapter
public class UserAdapter implements JsonbAdapter<User, JsonObject> {
@Override
public JsonObject adaptToJson(User user) throws Exception {
return Json.createObjectBuilder()
...
.build();
}
@Override
public User adaptFromJson(JsonObject jsonObject) throws Exception {
User user = new User();
..
return user;
}
}
and then couple it with the class:
// with this, no need to do new JsonbConfig().withAdapters(new UserAdapter());
@JsonBAdapter(class=UserAdapter.class)
public class User {
}
OK, lets discuss this issue a bit since it is scheduled to 3.0. I see no point in having this. I do believe this behavior should be already supported.
- When Adapter is registered via configuration it should be used automatically on every occurrences of the type it adapts.
- If the one registered via configuration does not suit you or there is none registered, you can overwrite it with the direct annotation
@JsonTypeAdapter
on specific field, which would contain the adapter to be used instead.
If the one registered via configuration would be marked as auto-apply=false, what is the point of registering it in the first place since it will never be picked?
Because of that I believe that this auto-apply usecase is/should already be supported. Am I missing something?
@Verdent point is to make it working out of the box. I think the misunderstanding between your two statement and this issue is 1 since you assume you control JsonbConfig but there is nothing in jakarta for that and this issue is exactly about being able to contribute to the jsonbconfig implicitly (without having).
If you prefer a jsonb config driven approach the proposal would be something along "jsonb cdi integration will fire a JsonbConfigInitialization CDI event after CDI container startup (AfterValidation phase) enabling to customize JsonbConfig (we can assume initialization even provides a getJsonbConfig or so). Then Jsonb default cdi extension must register a jsonb instance with this config in cdi context (take care it must NOT use default qualifier since it would break most apps so it should likely use a jsonb specific qualifer) and all other spec must use as default jsonb instance this CDI instance (thinking to jaxrs).
This alternative feature would also solve that thread and avoids the need for any new annotation/implicit registration.
The nice thing with this alternative approach is that it also solves the conflicts since observers of the events will have priority support - this issue does not so @JsonbAutoAdapter
should be combined with @Priority
which would bring jakarta.annotation
to jsonb which is maybe undesired.
So to answer your point: no, auto-apply is not yet supported and an issue in several spec overlapping requiring custom not portable code - or to redo what the spec (not always jsonb but jaxrs or others) do to be portable which is a big issue and any jakarta project.
Hope it makes sense.
Oh I see. Thank you for clarifying :-) For some reason I got an impression that it is just an option for adapter to choose whether it should be automatically used to the type it handles when it is registered. This is probably something I need to think about a bit :-)