【问题标题】:How to convert Play Framework Models into XML and JSON?如何将 Play 框架模型转换为 XML 和 JSON?
【发布时间】:2013-01-20 18:55:28
【问题描述】:

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

有些人推荐template approach,但这非常冗长,并不能保证格式正确的 XML/JSON。

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

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

类似地,JSON 上的播放文档显示了一个 JSON 对象一次构建一行。

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

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

有没有关于这个主题的官方播放文档

【问题讨论】:

    标签: java scala playframework playframework-2.0


    【解决方案1】:

    简答:Jackson 代表 JSONJAXB 代表 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:

    必须小心使用 generates getters and setters 的引擎盖下的模型。您不会在代码中看到 getter 和 setter,但它们在运行时存在。

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

    @XmlAccessorType(XmlAccessType.PROPERTY)
    

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

    @XmlRootElement(name = "UserRoot")
    

    要省略字段,我们必须在 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;
        }
    }
    

    编组由 JAXB 类 MarshallerJAXBContext 执行

    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>
    

    总结:

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

    【讨论】:

      【解决方案2】:

      对于 JSON,我建议使用... org.codehaus.jackson,因为它在 Play 2/x @see: Json Doc 中以 play.libs.Json 的形式提供

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

      编辑:

      Json 和 Ebean

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

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

      是的,我知道这可能是冗余编码,但我至少总是有正确的 JSON 输出,而且我不需要在每个操作中逐行创建 JSON。

      XML:

      HTML 字符不会破坏正确的 XML 渲染,因为默认情况下 Play 的模板会对其进行转义,因此将使用 &amp;lt;&amp;gt&amp;quot; 而不是 &lt;&gt;" XML 节点内部:

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

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

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

      【讨论】:

      • 谢谢 biesior。杰克逊文档一次构建 json 一个字段。我正在寻找的是一种在单个语句中自动将模型转换为 json 的方法,使用 java 类名和 java 字段名作为相应的 json 标识符。杰克逊有可能吗?你知道任何描述这个的文档吗? XML 模板方法的问题在于它并不总是返回格式良好的 XML。例如,如果数据包含任何特殊字符,如 或 ",这些将在运行时破坏 xml。保证格式正确的生成器是必不可少的。谢谢
      • 我不知道 XML 的格式化程序,无论如何仍然认为可以使用模板,请检查我的编辑。
      • 你的评论救了我,我觉得 Play 不支持创建 JSON 数组的简单方法太荒谬了!!!为什么它不支持 play.libs.Json.newObject() 的 put(ArrayList()) ???感谢您的回答!
      • yourObjectNode.put("items", Json.toJson(yourArray)) 怎么样?
      【解决方案3】:

      JSON 转换有更好的方法。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-30
        • 2015-01-13
        相关资源
        最近更新 更多