Play Framework: rendering custom JSON objects

I am using Play Framework 1.2.4 with Java and am using JPA to persist database objects. I have several model classes that will render as JSON. But the problem is, I would like to customize these JSON responses and simplify the objects just before rendering as JSON.

For example, suppose I have an object named ComplexClass and has properties id, name, property1, ..., propertyN. In the JSON response, I would like to display only the id and name fields.

What's the most elegant way to do this? Writing custom binder objects or simple JSON mapping like using a template?

+3


source to share


2 answers


Use FlexJSON, it's very easy. It allows you to create JSONSerializers that can include / exclude the fields you want.

Check out this article for some examples of using this in Play! Framework.
Here's a simple example:

public ComplexClass {
   public Long id;
   public String name;
   // And lots of other fields you don't want

   public String toJsonString() {
     // Include id & name, exclude all others.
     JSONSerializer ser = new JSONSerializer().include(
            "id",
            "name",
     ).exclude("*");
    return ser.serialize(this);
  }

      

}

You can add it to your .yml dependencies like this:

require:
    - play
    - net.sf.flexjson -> flexjson 2.1

      

I usually write an interface for the models that implement the method toJSONString()

so that I can call renderJSON(someModel.toJSONString())

in the controller.



Link to the official website

EDIT : Additional example for lists / collections

Well, when you start serializing the list, you might get unexpected results. This is because the order of evaluation is important. The first include()

or exclude()

takes precedence over the next.

Here is an example of serializing the children of the parent object (OneToMany relationship).

JSONSerializer ser = new JSONSerializer();
// Exclude these standard fields from childs
ser.exclude(
    "*.persistent", 
    "*.class",
    "*.entityId"
);
// Include childs and all its other fields
ser.include(
    "childs",
    "childs.*"
);
// Exclude everything else
ser.exclude("*"); 
String data = ser.serialize(parent);

      

*

is a wildcard. This documentation explains it completely:
Exclude *.class

will match any path depth. Therefore, if flexjson serializes field loop "foo.bar.class", *

to *.class

be fit foo.bar.

+6


source


The Play Framework 1.2.4 is directly dependent on the library gson

, so you can use it to render JSON strings. All you have to do is use the gson annotation @Expose

. So in your example, you tag the fields you want in the JSON string like this:

public class ComplexClass {

    @Expose
    public Long id;

    @Expose
    public String name;

    ...
}

      

Then, in your controller, you simply do this:

public static void someActionMethod() {
    // get an instance of your ComplexClass here
    ComplexClass complex = ...
    Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
    String json = gson.toJson(complex);
    renderJson(json);
}

      

See the documentation here .



If the ComplexClass is in fact play.db.jpa.Model

, and so the field is id

abstracted in the parent class and you cannot put annotation @Expose

on it, then you can create your own ExclusionStrategy that skips fields that are not annotated with @Expose

and named id

. So, something like this (pseudocode):

public final class ComplexClassExclusionStrategy implements ExclusionStrategy {

    public boolean shouldSkipField(FieldAttributes attributes) {
        if (name of field is "id") return false;
        if (field is annotated with @Expose) return false;
        return true;
    }

      

Then the controller changed a bit to look like this:

    GsonBuilder builder = new GsonBuilder();
    ComplexClassExclusionStrategy strategy = new ComplexClassExclusionStrategy();
    builder.setExclusionStrategies(strategy);
    Gson gson = builder.create();
    String json = gson.toJson(complex);
    renderJson(json);

      

+8


source







All Articles