In Play, when rendering JSON, can I use anonymous types and / or object initializers?

I am writing a Play application that will have dozens of controller actions that return JSON. The format of each JSON result is slightly different, made up of several primitives.

I would like to avoid creating a Java class to store the return type for each action method, so I am currently using HashMap, for example:

// used to populate the filters for an iphone app public static void filters() { // get four lists from the database List<Chef> chefs= Chef.find("order by name asc").fetch(); List<Cuisine> cuisines = Cuisine.find("order by name asc").fetch(); List<Meal> meals = Meal.find("order by name asc").fetch(); List<Ingredient> ingredients = Ingredient.find("order by name asc").fetch(); // return them as JSON map Map<String,Object> json = new HashMap<String,Object>(); json.put("chefs", chefs); json.put("cuisines", cuisines); json.put("meals", meals); json.put("ingredients", ingredients); renderJSON(json); } 

This returns a JSON that looks like what I want:

 { "chefs": [{},{},...{}], "cuisines": [{},{},...{}], "meals": [{},{},...{}], "ingredients": [{},{},...{}] } 

It seems to me that the syntax for building a HashMap is redundant . I don’t have a ton of Java experience, so I am comparing with C #, which allows me to use an anonymous type with an object initializer to cut such code:

 return Json(new { chefs = chefs, cuisines = cuisines, meals = meals, ingredients = ingredients }); 

Is there anything in the Java / Play world that allows me to write this code more compactly?

+4
source share
2 answers

There is no exact equivalent in Java to the C # construct, however you can create an anonymous object and initialize it using the idiom below:

 public static void filters() { renderJSON(new HashMap<String,Object>(){{ // get four lists from the database List<Chef> chefs= Chef.find("order by name asc").fetch(); List<Cuisine> cuisines = Cuisine.find("order by name asc").fetch(); List<Meal> meals = Meal.find("order by name asc").fetch(); List<Ingredient> ingredients = Ingredient.find("order by name asc").fetch(); // return them as JSON map put("chefs", chefs); put("cuisines", cuisines); put("meals", meals); put("ingredients", ingredients); }}); } 

(You can place ads with four lists outside the initializer of an anonymous type, but then you will need to declare them final.)

+1
source

Java has anonymous types that you should use just fine:

 // these would be accessed from DB or such; must be final so anonymous inner class can access final String _name = "Bob"; final int _iq = 125; renderJSON(new Object() { public String name = nameValue; // or define 'getName()' public int iq = iqValue; // ditto here }); 

this creates an anonymous inner class, and then JSON data binding should be able to understand it, serialize stuff, etc.

0
source

All Articles