如何将Play框架模型转换为XML和JSON?

Play Framework是否具有将Play模型转换为XML / JSON的原生推荐方式? 类似于JAXB或Jackson的东西。

有些人推荐使用模板方法,但这非常冗长,并不能保证格式良好的XML / JSON。

XML上的Play文档只显示使用String连接构建的XML响应,如下所示:

return ok("Hello " + name + ""); 

同样,JSON上的Play文档显示一次一行构建一个JSON对象。

 ObjectNode result = Json.newObject(); result.put("status", "OK"); result.put("message", "Hello " + name); 

是否有使用Play将模型序列化为XML / JSON的标准方法?

是否有关于此主题的官方游戏文档

简短回答: jackson为JSON , JAXB为XML

Play本身不提供有关编组模型的任何文档,但它确实附带了可以完成这项工作的第三方库


JSON:

该模型:

 public class User extends Model { public String username; public Long age; @JsonIgnore public String password; // field won't be marshalled } 

使用jackson的ObjectMapper.writeValueAsString()方法将其转换为JSON。

 import org.codehaus.jackson.map.ObjectMapper; // ObjectMapper mapper = new ObjectMapper(); String jsonString = mapper.writeValueAsString(country); 

JSON输出:

 { "username" : "John Smith", "age" : "25" } 

XML:

必须小心,因为Play如何为引擎盖下的模型生成吸气剂和固定剂 。 您不会在代码中看到getter和setter,但它们在运行时存在。

在模型上,将XmlAccessorType注释设置为PROPERTY很重要。 这告诉JAXB从getter / setter序列化而不是从底层字段序列化。

 @XmlAccessorType(XmlAccessType.PROPERTY) 

我们还必须添加一个@XmlRootElement注释,它指定根XML节点的名称:

 @XmlRootElement(name = "UserRoot") 

要省略字段,我们必须将@XmlTransient注释添加到getter。 由于源代码中没有getter,我们必须为每个要省略的字段添加一个getter。

 @XmlAccessorType(XmlAccessType.PROPERTY) public class User extends Model { public String username; public Long age; @JsonIgnore public String password; @XmlTransient // This means ignore this property public String getPassword() { return this.password; } } 

编组由JAXB类Marshaller和JAXBContext执行

 JAXBContext context = JAXBContext.newInstance(User.class); Marshaller marshaller = context.createMarshaller(); // Use linefeeds and indentation in the outputted XML marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(user, System.out); 

输出:

  John Smith 25  

摘要:

关于XML的Play文档和JSON 上的Play文档确实提供了有关使用json / xml的一些信息,但似乎没有任何Play Docs描述如何进行编组 。 为此,我们必须查看第三方库和文档。

对于JSON,我建议使用… org.codehaus.jackson ,因为它可以在Play 2/x @see中作为play.libs.Json使用:Json Doc

对于XML – 模板方法是公平的,因为您可以使用视图呈现正确的XML。

编辑:

Json和Ebean

遗憾的是,必须要说Ebean将其对象序列化为JSON存在问题,因此我总是使用专用的内部类(在目标模型中,它只包含应该在Json中发送的字段),即对于User模型:

 public static class ForJson { public Long id; public String name; public String email; public ForJson(User user) { this.id = user.id; this.name = user.name; this.email=user.email; } } 

路线:

 GET /users/all.json controllers.Application.listUsersJson GET /users/all-details.json controllers.Application.listUsersJsonWithDetails GET /users/:id.json controllers.Application.singleUserJson(id: Long) 

动作:

 public static Result listUsersJson() { List usersToJson = new ArrayList<>(); for (User user : User.find.all()) { usersToJson.add(new User.ForJson(user)); } return ok(Json.toJson(usersToJson)); } public static Result singleUserJson(Long id) { User.ForJson userForJson = new User.ForJson(User.find.byId(id)); return ok(Json.toJson(userForJson)); } public static Result listUsersJsonWithDetails() { Map details = new LinkedHashMap<>(); List usersToJson = new ArrayList<>(); for (User user : User.find.all()) { usersToJson.add(new User.ForJson(user)); } details.put("date", new Date()); details.put("count", usersToJson.size()); details.put("users", usersToJson); return ok(Json.toJson(details)); } 

是的,我知道也许它是简化和编码,但我至少总是有适当的JSON输出,而且我不需要在每个动作中逐行创建JSON。

XML:

HTML字符不会破坏渲染正确的XML,因为默认情况下,Play的模板会将它们转义,因此,它将代替<> ,在XML节点内使用<&gt ; "

 Say "ellou" 

检查模板文档中的转义段落 (页面底部)。

您还可以使用部分模板 - 标签来确保单个项目的格式完全相同: users/1.xmlusers/all.xml

有一种更好的JSON转换方式。

 User user = new User("..."); String jsonString = Ebean.json().toJson(user);