Private Fields Serialization with JSON-B and JAX-RS 2.1 / Java EE 8
JSON-B from Java EE 8 serializes public fields or properties as default. For private field serialization:
public class Workshop {
private String name;
private int duration;
public Workshop(String name, int duration) {
this.name = name;
this.duration = duration;
}
}
you will have to implement a PropertyVisibilityStrategy (checkout Java EE 8: Serializing POJOs with JSON-B):
public class PrivateVisibilityStrategy implements PropertyVisibilityStrategy {
@Override
public boolean isVisible(Field field) {
return true;
}
@Override
public boolean isVisible(Method method) {
return false;
}
}
...pass your custom configuration to the JsonbBuilder and return the instance with a ContextResolver:
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
@Provider
public class JSONConfigurator implements ContextResolver {
@Override
public Jsonb getContext(Class> type) {
JsonbConfig config = new JsonbConfig().
withPropertyVisibilityStrategy(new PrivateVisibilityStrategy());
return JsonbBuilder.newBuilder().
withConfig(config).
build();
}
}
Now your POJO's private fields are going to be used for JSON-mapping:
@Path("workshops")
public class WorkshopsResource {
@GET
public Workshop workshop() {
return new Workshop("Java EE 8", 42);
}
}
Result: {"duration":42,"name":"Java EE 8"}
Tested with Payara 5.
See you at Java EE Workshops at MUC Airport, particularly at the Effective Java EE 8 workshop
Shouldn't it have a type parameter `... implements ContextResolver<Jsonb>`?
Posted by Rüdiger on October 19, 2018 at 06:13 AM CEST #
I use wildfly 14
If I create this Provider it is not used to deserialize the Classes. What am I doing wrong? Any suggestions?
Posted by chris on October 23, 2018 at 02:15 PM CEST #
Thanx for the tip!
I'd like to ask if there is a way to obtain the same Jsonb instance that we create in the ContextResolver when we want to use it programmatically?
My use case is that JSON arrives at a JAX-RS resource as form data (application/x-www-form-urlencoded)
and I'd like to use the same, configured Jsonb instance instead of re-creating another one ad-hoc.
Posted by Vagelis on January 22, 2019 at 05:33 PM CET #
@chris, @adam
This is not mentioned in the jax-rs 2.x specifications. This is just a Payara-only-Feature and shouldn't have been tagged JavaEE8.
See this issue on openliberty: https://github.com/OpenLiberty/open-liberty/issues/5903
Posted by Ben M. on February 11, 2019 at 09:08 AM CET #
My class had collections, which seems to require a public getter. Of course, now also the methods need to be visible to access the getter.
public class PrivateVisibilityStrategy implements PropertyVisibilityStrategy {
@Override public boolean isVisible(Field field) { return true; }
@Override public boolean isVisible(Method method) { return true; }
}
public class MyWorkshop extends Workshop {
private List<String> attendees;
public List<String> getAttendees() {
if ( attendees == null ) { attendees = new ArrayList<String>(); }
return attendees;
}
}
Posted by Mikko on March 06, 2019 at 02:59 PM CET #
Is it possible to have different jsonbconfig for different jaxrs resources?
I have two jaxrs resources. In the first I would like binary data to be encoded with BASE64 strategy. In the second, I wouldn't like that.
Posted by wxqy on December 04, 2019 at 07:19 AM CET #