简体   繁体   English

Play Framework 2:如何从控制器中的各种来源正确构造对象,然后对其进行验证?

[英]Play Framework 2: How to correctly construct objects from various sources in the controller and then validate them?

For this example, the user wishes to create a blog post for their site. 对于此示例,用户希望为其站点创建博客文章。 Form submission is handled through AJAX. 表单提交是通过AJAX处理的。 The POST request is handled by the createPost method in the controller. POST请求由控制器中的createPost方法处理。 The method extracts the json data and combines it with the users session data to construct the appropriate Post object. 该方法提取json数据,并将其与用户会话数据组合以构造适当的Post对象。 It then validates the data and returns an appropriate response. 然后,它验证数据并返回适当的响应。

The Post model is as follows: Post模型如下:

@Entity
public Post extends model {
  @Id
  public Long id;
  @Required
  public User author;
  @Required
  public String title;
  @Required
  public String body;
}

The controller method is as follows: 控制器方法如下:

@BodyParser.Of(BodyParser.Json.class)
public static Result createPost() {
  JsonNode json = request().body().asJson();
  Post post = new Post();

  post.author = User.findbyId(request().username());
  post.title = json.findPath("title").textValue();
  post.body = json.findPath("body").textValue();

  Form<Post> filledForm = Form.form(Post.class).bind(Json.toJson(post));

  if (filledForm.hasErrors())
    return badRequest(filledForm.errorsAsJson());

  // save post

  return ok();  
}

Now, this method works, however, there must be a better way of doing it rather than taking the json request, extracting it into an object and then converting that object back into json so that it can be bound to the form. 现在,此方法有效,但必须有一种更好的方法,而不是接收json请求,将其提取到对象中,然后将该对象转换回json,以便可以将其绑定到表单。 Any ideas? 有任何想法吗?

The common way to do it is using bindFromRequest in the controller side. 常用的方法是在控制器端使用bindFromRequest

public static Result savePost() {
    Form<Post> postForm= form(Post .class).bindFromRequest();
    if(postForm.hasErrors()) {
        Logger.error("Form has errors: " + postForm.errorsAsJson());
        return badRequest(filledForm.render(postForm));
   }
   Post post=postForm.get();
   post.save()
   ....
}

For a full example you can checkout the forms sample . 有关完整的示例,您可以签出表单样本

And the AJAX post could be something like that: 而AJAX帖子可能是这样的:

function postUrl(form){
    var postData = new FormData($(form)[0])
    var formURL = $(form).attr("action");
    var request=$.ajax({
        url : formURL, type: "POST", data : $(form).serialize(),
    });
    request.done(function(data) {
    //Whatever  
    });
}

It's a commonly discussed issue in Play that form classes shouldn't really be domain classes. 在Play中一个经常讨论的问题是,表单类不应真正是域类。 Only works in simple cases. 仅在简单情况下有效。

One alternative is to create a form-data class and bind that. 一种选择是创建一个表单数据类并将其绑定。 The form-data class can contain data from many different models. 表单数据类可以包含来自许多不同模型的数据。 Then have code that loads your domain object (Post) a copy fields from form-data object. 然后,编写代码以从表单数据对象加载域对象(发布)和复制字段。 I use code-generation for the form-data to domain-object code. 我将代码生成用于表单数据到域对象代码。 YMMV. YMMV。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM