25

在 html 中,一个包含多部分数据的表单:

<form action="@routes.Files.upload" method="post" enctype="multipart/form-data">
    <input type="hidden" name="groupId" value="1" />
    <input type="hidden" name="tagId" value="2" />
    <input type="file" name="file"/>
    <input type="submit" value="upload it"/>
</form>

动作要怎么写Files upload

我知道如何获取上传的文件:

request.body.file("file") map {
    filepart => filepart.ref.moveTo(newFile);
}

以及如何获取提交的输入:

Form(tuple("groupId" -> text, "tagId" -> text)).bindFromRequest.fold(
    errors => ...,
    params => ....
)

但是如何将它们结合在一起呢?

我没有找到合适的类型file可以在 中使用Form(tuple(...)),也没有在 中获取输入值的方法request.body

4

4 回答 4

27

此答案适用于 Java,但您应该能够相当容易地将其适应 Scala。

您需要做的是为表单中文件之外的所有字段定义一个模型。然后像往常一样使用文件上传 API 来检索文件。

例如,这就是我所做的:

表单(在 upload.scala.html 中):

@form(action = routes.UploadResourceController.doUpload(), 'enctype -> "multipart/form-data") {

    @inputText(uploadForm("lang"))
    @inputText(uploadForm("country"))
    @inputFile(uploadForm("resourceFile"))

    <p>
        <input type="submit">
    </p>
}

模型(模型/UploadResource.java):

public class UploadResource {
    @Required
    public String lang;

    @Required
    public String country;

    /* notice a field for the file is missing */
}

控制器(控制器/UploadResourceController.java):

public static Result doUpload() {
    Form<UploadResource> filledForm = uploadForm.bindFromRequest();

    if (filledForm.hasErrors()) {
        return badRequest(views.html.upload.render(filledForm));
    } else {
        UploadResource resource = filledForm.get();
        MultipartFormData body = request().body().asMultipartFormData();
        FilePart resourceFile = body.getFile("resourceFile");

        /* Check resourceFile for null, then extract the File object and process it */
     }
}

我希望这有帮助。

于 2012-03-06T15:48:23.117 回答
13

Scala 中需要表单字段的示例:

模型:

case class Specs (userid: String)

控制器:

object Upload extends Controller {
   val uploadForm = Form(
         mapping(
               "userid" -> nonEmptyText
         )(Specs.apply)(Specs.unapply)
   )
   def upload = Action(parse.multipartFormData) { implicit request =>
      val sp : Option[Specs] = uploadForm.bindFromRequest().fold (
            errFrm => None,
            spec => Some(spec)
      )
      request.body.file("file").map { f =>
         sp.map { spec =>
            val filePath = ... // incorporate userid
            // XXX: file read to memory b4 writing to disk. bad for large files
            f.ref.moveTo(new File(filePath), replace=true)
            Ok("File uploaded")
         }.getOrElse{
            BadRequest("Form binding error.")
         }
      }.getOrElse {
         BadRequest("File not attached.")
      }
   }
}
于 2012-04-25T19:06:37.627 回答
3

如何做到这一点的另一个例子可以是:

模型:

case class Specs(userId: String)

控制器

def upload = Action(parse.multipartFormData) { implicit request => 
   uploadForm.bindFromRequest().fold(
   hasErrors => Ok(ourFormHTML(hasErrors),
   specs => {
      request.body.file("inputFileFieldName") match {
        case Some(file) => {
          import java.io.File
          val filename = file.filename
          val contetType = file.contentType
          file.ref.moveTo(new File(Play.application().path().getAbsolutePath + file.filename))
          Ok("congratz you did it")
        }
        case _ => Ok(ourHTML if we dont send file but want the form anyway)
      }
   }


 )

不要忘记为文件命名,因为您最终可能会想知道出了什么问题。

于 2015-04-20T17:54:54.997 回答
2

我正在使用带有其他表单参数的角度上传文件。我如下创建了我的,它可以工作。

角函数

Upload.upload({
    url: '/api/upload',
    method:'POST',
    data: {
        "file": user.profilePic, //file object
        "username": user.username

    }
}).then(function (resp) {
    //console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);

}, function (resp) {
    console.log('Error status: ' + resp.status);
}, function (evt) {
    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
    //console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
});

玩 2.1 控制器

/**
*
*Upload user profile 
**/
public static Result upload() {
    Logger.info("Uploading images##");
    Http.MultipartFormData body = request().body().asMultipartFormData();
    Http.MultipartFormData.FilePart profile = body.getFile("file");
    if (profile != null) {
        File file = profile.getFile();

        //upload file to a directory
        //todo

        //get the username from form
          Map<String,String[]> dataPart = request().body().asMultipartFormData().asFormUrlEncoded();
          String username = dataPart.get("username")[0];

          //save/update the details with ebean

        return ok("File uploaded");
    } else {

        return status(400, "Missing file");
    }
}
于 2016-02-27T13:00:22.727 回答