Play!> & JSon : How-to select fields to expose (ExclusionStrategy)
Using JSON as data language to build an API for your Play application, the default behaviour is to render all fields of a class, and this recursively. This means render the fields of a
Here a sample model example that could occurs in a bank application :
A client is specified with this model, that includes the password of the client.
@Entity public class Client extends Model { public String firstname; public String lastname; public String password; public String toString() { return firstname + " " + lastname; } }
This client has accounts in the bank, so a simple model would be :
@Entity public class Account extends Model { @ManyToOne public Client owner; public String number; public Double balance; public String label; public String toString() { return number; } }
One of the first service of the application when a client connects to the application is to show the list of his accounts :
The route is :
GET /api/accounts Operations.listAccounts
And the code of the controller is :
public class Operations extends Controller { public static void listAccounts() { List<Account> accounts = Account.find("order by number").fetch(); renderJSON(accounts); } }
This code will expose the following json datas :
[{"owner":{"firstname":"xxx","lastname":"xxx","password":"yyyy","id":1},"number":"001","balance":999.99,"label":"ACCOUNT X","id":1},...]
Oh, the password is visible.
So what we will do is to extend Play! with a new Controller class that will use add a Strategy to gson :
package ext; import play.mvc.Controller; import play.mvc.Util; import play.mvc.results.RenderJson; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public abstract class NoExposeStrategyController extends Controller { private static final Gson gson; static { gson = new GsonBuilder() .addSerializationExclusionStrategy(new NoExposeExclusionStrategy()) .create(); } @Util public static void renderJSON(Object object) { throw new RenderJson(gson.toJson(object)); } }
Now, we will wrtie this strategy. The goal is to exclude fiels annoted (we will use the tag @NoExpose) in the json output.
package ext; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; public class NoExposeExclusionStrategy implements ExclusionStrategy { @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD }) public @interface NoExpose { // Field tag only annotation } public NoExposeExclusionStrategy() { } public boolean shouldSkipClass(Class<?> clazz) { return (false); } public boolean shouldSkipField(FieldAttributes f) { return f.getAnnotation(NoExpose.class) != null; } }
You can notice that with exclude fields, but that we can also exclude Classes. This can also be very interesting to exclude a model (so all datas of a particular table).
The main code is done. All we have to do now is just two basic actions.
– change the declaration of our controller(s) :
public class Operations extends NoExposeStrategyController {
-annotate the fields we want to exclude :
@NoExpose public String password;
About this entry
You’re currently reading “Play!> & JSon : How-to select fields to expose (ExclusionStrategy),” an entry on Java Thoughts
- Published:
- June 24, 2012 / 9:21 pm
- Tags:
- ExclusionStrategy, json, play framework
2 Comments
Jump to comment form | comment rss [?] | trackback uri [?]