[En] Custom Field Serialization with JSON-B and JAX-RS / JAVA EE 8 / Payara 5

In JSON-B private fields of an object are not serialized by default. Beyond that, you would want to serialize your custom fields according to your business logic. Let’s start with an example:

public class Picture {

private String name;

private int size;

private String content;

  public Picture(String name, int size, String content) {
    this.name = name;
    this.size = size;
    this.content = content;
  }

}

Let’s say you want to show “name” and “size” but you don’t want to show your “content” field.  All three variables are private so in order to make a distiction, you could use self-made annotation.

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MetaData {

}

After that, you could use MetaData self-made annotation class in Picture class.

public class Picture {

@MetaData
private String name;

@MetaData
private int size;

private String content;

   public Picture(String name, int size, String content) {
     this.name = name;
     this.size = size;
     this.content = content;
   }
}

Let’s implement business strategy

public class AljoschaStrategy implements PropertyVisibilityStrategy {

   private boolean everything;

   public AljoschaStrategy(boolean everything) {
     this.everything = everything;
   }

   @Override
   public boolean isVisible(Field field) {

      if (this.everything) {
        return true;
      }

      return field.isAnnotationPresent(MetaData.class);
   }

   @Override
   public boolean isVisible(Method method) {
    return false;
   }
}

In order to activate the business strategy, we have to implement ContextResolver. Please don’t forget to use generics

@Provider
public class Strategy implements ContextResolver<Jsonb>{

@Override
public Jsonb getContext(Class type) {

   JsonbConfig config = new JsonbConfig().
    withPropertyVisibilityStrategy
      (new AljoschaStrategy(false));

   return JsonbBuilder.newBuilder().
     withConfig(config).
     build();
  }
}

And last our JAX-RS rest services

@Path("ping")
@Produces(MediaType.APPLICATION_JSON)
public class PingResource { 

   @GET
   public JsonObject ping() {
     return new Ping("duke", "istanbul").toJson(); 
   }

   @GET
   @Path("picture")
   public Picture picture(@Context HttpHeaders headers) {
     return new Picture("aljoscha", 42, "nice face");
   }
}

In order to run

curl -i localhost:8080/advanced/resources/ping/picture

Result :

{“name”:”aljoscha”,”size”:42}%

 

 

1 Comment
  • Ola
    Posted at 18:47, 31/05/2019

    Or you could just use @JsonbTransient on the field to be ignored..

Post a Comment

Comment
Name
Email
Website