scala 如何将 Play 框架模型转换为 XML 和 JSON?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14714455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert Play Framework Models into XML and JSON?
提问by KevSheedy
Does the Play Framework have a Nativeor Recommendedway of converting Play models into XML/JSON? Something similar to JAXB or Hymanson.
Play 框架是否具有将 Play 模型转换为 XML/JSON的本机或推荐方式?类似于 JAXB 或 Hymanson 的东西。
Some people recommend the template approachbut this is very verbose and doesn't guarantee well-formed XML/JSON.
有些人推荐模板方法,但这非常冗长,并且不能保证格式良好的 XML/JSON。
The Play Documentation on XMLjust shows an XML response being built using String concatenation like so:
XML 上的播放文档仅显示使用字符串连接构建的 XML 响应,如下所示:
return ok("<message \"status\"=\"OK\">Hello " + name + "</message>");
Similarly, the Play Documentation on JSON shows a JSON object being built up one line at a time.
类似地,JSON 上的 Play 文档显示了一次构建一行的 JSON 对象。
ObjectNode result = Json.newObject();
result.put("status", "OK");
result.put("message", "Hello " + name);
Is there a Standardway of serializing Models into XML/JSON using Play?
是否有使用 Play 将模型序列化为 XML/JSON的标准方法?
Is there any Official Play Documentationon this subject?
是否有关于此主题的官方 Play 文档?
回答by KevSheedy
Short answer: Hymansonfor JSONand JAXBfor XML
简短回答:Hymansonfor JSON和JAXBfor XML
Playitself doesn't provide any documentation on marshallingmodels but it does ship with 3rd party librariesthat can do the job.
Play本身不提供任何关于编组模型的文档,但它确实附带了可以完成这项工作的3rd 方库。
JSON:
JSON:
The model:
该模型:
public class User extends Model {
public String username;
public Long age;
@JsonIgnore
public String password; // field won't be marshalled
}
Marshall it to JSON using Hymanson's ObjectMapper.writeValueAsString()method.
使用 Hymanson 的ObjectMapper.writeValueAsString()方法将其编组为 JSON 。
import org.codehaus.Hymanson.map.ObjectMapper;
//
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(country);
JSON Output:
JSON 输出:
{
"username" : "John Smith",
"age" : "25"
}
XML:
XML:
Care must be taken because of how Play generates getters and settersfor it's models under the hood. You won't see the getter and setters in the code but they exist at runtime.
必须小心,因为 Play 如何为其引擎盖下的模型生成 getter 和 setter。您不会在代码中看到 getter 和 setter,但它们在运行时存在。
On the model, it's important to set the XmlAccessorTypeannotation to PROPERTY. This tells JAXB to serialize from the getter/settersand not from the underlying fields.
在模型上,将XmlAccessorType注释设置为PROPERTY很重要。这告诉 JAXB 从getter/setter而不是从底层 fields序列化。
@XmlAccessorType(XmlAccessType.PROPERTY)
We also have to add an @XmlRootElementannotation which specifies the name of the root XML node:
我们还必须添加一个@XmlRootElement注释,用于指定根 XML 节点的名称:
@XmlRootElement(name = "UserRoot")
To omit a field, we must add the @XmlTransientannotation to the getter. Since there is no getter in the source code, we must add one for every field we want to omit.
要省略字段,我们必须向 getter添加@XmlTransient注释。由于源代码中没有 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;
}
}
The marshalling is performed by the JAXB classes Marshallerand JAXBContext
编组由 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);
Output:
输出:
<UserRoot>
<name>John Smith</name>
<age>25</age>
</UserRoot>
Summary:
概括:
The Play docs on XMLand the Play docs on JSONdo provide some information on working with json/xml but there doesn't seem to be any Play Docs describing how to do Marshalling. For that we have to look at 3rd Party librariesand documentation.
在对XML文档播放和JSON的播放文档不提供使用JSON / XML的一些信息,但似乎没有要说明如何做任何播放文件编组。为此,我们必须查看3rd Party 库和文档。
回答by biesior
For JSON I'd suggest using... org.codehaus.Hymanson, as it available as play.libs.Jsonin Play 2/x@see: Json Doc
对于 JSON,我建议使用... org.codehaus.Hymanson,因为它play.libs.Json在@see 中可用Play 2/x:Json Doc
For XML- template approach is fair enough, as you can render proper XML with the view.
For XML- 模板方法足够公平,因为您可以使用视图呈现正确的 XML。
Edit:
编辑:
Json and Ebean
Json 和 Ebean
Sadly must to say that Ebean has a problems with serializing its objects to JSON, therefore I'm always using dedicated inner class (in the target model, which contains only fields, that should be send in Json) ie, for Usermodel:
遗憾的是,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;
}
}
routes:
路线:
GET /users/all.json controllers.Application.listUsersJson
GET /users/all-details.json controllers.Application.listUsersJsonWithDetails
GET /users/:id.json controllers.Application.singleUserJson(id: Long)
actions:
行动:
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));
}
Yes, I know maybe it's reduntand coding, but I have at least always proper JSON output, and I don't need to create JSON line by line in each action..
是的,我知道这可能是冗余编码,但我至少总是有正确的 JSON 输出,而且我不需要在每个操作中逐行创建 JSON。.
XML:
XML:
HTML chars won't break the rendering the proper XML as by default Play's templates escapes them, so instead of <, >, "it will use <, >, "inside the XML node:
HTML字符不会打破渲染正确的XML作为默认播放的模板逃脱他们,所以不是<,>,"它将使用<,>,"XML节点内:
<sample>Say "ellou"<sample>
Check Escaping paragraph in templates's doc(bottom of the page).
检查模板文档中的转义段落(页面底部)。
What's more you can use partial templates - tagsto make sure, that single item will be formatted exactly the same in both: users/1.xmland users/all.xml
更重要的是,您可以使用部分模板 -标签来确保单个项目的格式完全相同:users/1.xml和users/all.xml
回答by Ouyang Chao
There is a better way for JSON conversion.
有更好的 JSON 转换方法。
User user = new User("...");
String jsonString = Ebean.json().toJson(user);

