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

时间:2013-02-05 18:35:33

标签: java scala playframework playframework-2.0

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

有些人推荐template approach,但这非常详细,并不能保证格式良好的XML / JSON。

Play Documentation on XML只显示使用字符串连接构建的XML响应,如下所示:

return ok("<message \"status\"=\"OK\">Hello " + name + "</message>");

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

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

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

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

3 个答案:

答案 0 :(得分:11)

简短回答: JSON Jackson XML 的<{3}}

JAXB本身并未提供有关编组模型的任何文档,但它附带第三方库可以执行此任务。


<强> JSON:

模特:

public class User extends Model {
    public String username;
    public Long   age; 

    @JsonIgnore
    public String password; // field won't be marshalled
}

使用jackson的Play方法将其转换为JSON。

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

JSON输出:

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

<强> XML:

必须小心,因为Play ObjectMapper.writeValueAsString()对于它的模型是如何引人注目的。您不会在代码中看到getter和setter,但它们在运行时存在。

在模型上,将generates getters and setters注释设置为XmlAccessorType非常重要。这告诉JAXB从 getter / setters 序列化,而不是从基础字段序列化。

@XmlAccessorType(XmlAccessType.PROPERTY)

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

@XmlRootElement(name = "UserRoot")

要省略字段,我们必须将@XmlRootElement注释添加到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类@XmlTransientMarshaller执行

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

<强>输出:

<UserRoot>
    <name>John Smith</name>
    <age>25</age>
</UserRoot>

<强>要点:

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

答案 1 :(得分:2)

对于JSON,我建议使用org.codehaus.jacksonplay.libs.Json @see: Json Doc

中的Play 2/x

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

修改

Json和Ebean

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

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)

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

<强> XML:

HTML chars不会破坏渲染正确的XML,因为默认情况下,Play的模板会将其转义,因此public static Result listUsersJson() { List<User.ForJson> 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<String, Object> details = new LinkedHashMap<>(); List<User.ForJson> 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)); } <>将使用"而不是&lt;。 ,XML节点内的&gt&quot;

<sample>Say &quot;ellou&quot;<sample>

检查Escaping paragraph in templates's doc(页面底部)。

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

答案 2 :(得分:1)

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

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