2011-10-09 44 views
4

我正在写一个Play应用程序,它将有数十个控制器操作返回JSON。每个JSON结果的格式稍有不同,由几个基元组成。在Play中,渲染JSON时可以使用匿名类型和/或对象初始值设定项吗?

我想避免创建一个Java类,以保持每个动作方法的返回类型,所以目前我使用一个HashMap,像这样:

// 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); 
} 

这将返回JSON看起来像这样,这就是我想:

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

我觉得的语法来构建的HashMap是多余的。我没有一吨的Java的经验,所以我比较C#这让我使用匿名类型对象初始化,以减少的代码如下所示:

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

Java/Play世界里有什么让我更加紧凑地写这种代码的吗?

回答

1

没有完全等效于Java中的C#构造,但是你可以创建一个匿名对象并使用成语图所示初始化:

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); 

    }}); 
} 

(你可以把4页名单的声明外匿名类型初始化,但那么你就需要声明他们最终)

+0

不幸的是,那只是返回一个空字符串。 \t \t renderJSON(new HashMap (){{put(“foo”,“string”); put(“bar”,123); }}); – Portman

+0

有趣。看起来renderJSON中的反射魔术不处理地图的子类。从匿名图创建实际的HashMap确实有效:\t Map map = new HashMap (){{put(“foo”,“string”);放(“酒吧”,123); }}; renderJSON(new HashMap (map)); –

+0

我做了一些另外的测试,并且renderJSON处理了HashMap的普通子类。所以只有匿名的子类会导致问题。 –

0

的Java确实有匿名类型,你应该能够使用就好了。

// 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 
}); 

这会创建匿名内部类,然后JSON数据联编程序应该能够反省它,序列化内容等等。

+0

Play框架没有' t似乎喜欢这些变量是“最终”的事实。我得到以下异常:“Class play.classloading.enhancers.PropertiesEnhancer $ FieldAccessor无法访问类controllers.TestController $ 1修饰符的成员”public“” – Portman

+0

Play有趣的限制,那么 - 不应该有任何根本性的问题因为像杰克逊这样的JSON框架会允许这种用法。 – StaxMan

相关问题