我正在使用Bootstrap tagsinput使用标签注释我的文件:
@helper.form(action=routes.Upload.save(projectId), 'enctype -> "multipart/form-data" )
{
<input type="file" name="corpus">
<input type="text" value="Amsterdam,Washington,Sydney,Beijing,Cairo" name="tags" id="tags" data-role="tagsinput"/>
<input type="submit">
}
在控制器中,我试图将请求绑定到表单:
def save(id:Long) = Action(requestCsvBodyParser){ implicit request =>
uploadForm.bindFromRequest.fold(
hasErrors => {
BadRequest
},
success = { formData =>
// accessing formData.tags
// parsing request.body and store in the database with tags
Ok("Got request")
}
)
}
requestCsvBodyParser是Iteratee [Array [Byte],List [String]]。据我所知,该文件不应该是验证表单的一部分,所以我将表单定义如下:
private val uploadForm = Form(
mapping(
"tags" -> list(text)
)(UploadTags.apply)(UploadTags.unapply)
)
会导致请求成功,但空tags
。如果我使用text
代替list(text)
,那么我总是以BadRequest
结尾。
当我在表单验证中执行此操作时,如果它是解析的反应方式,我也不会感到害羞。
编辑(添加Bodyparser) BodyParser:
/** Enumeratee that transforms a stream of Array[Byte] into a stream of Byte */
val toBytes: Enumeratee[Array[Byte], Byte] = Enumeratee.mapInputFlatten[Array[Byte]] {
case Input.El(arr) => Enumerator[Byte](arr: _*)
case Input.Empty => Enumerator.empty[Byte]
case Input.EOF => Enumerator.eof[Byte]
}
val concatLine: Iteratee[Parsing.MatchInfo[Array[Byte]],String] =
( Enumeratee.breakE[Parsing.MatchInfo[Array[Byte]]](_.isMatch) ><>
Enumeratee.collect{
case Parsing.Unmatched(bytes) => new String(bytes)
} &>>
Iteratee.consume() ).flatMap(r => Iteratee.head.map(_ => r))
val txtToParagraph: Iteratee[Array[Byte], List[String]] =
Parsing.search("\r\n\r\n".getBytes) ><>
Enumeratee.grouped( concatLine ) &>>
Iteratee.head.flatMap( header => Iteratee.getChunks.map(header.toList ++ _) )
val requestCsvBodyParser = BodyParser(rh => txtToParagraph.map(Right(_)))
答案 0 :(得分:1)
如果您希望将表单值解析为列表,则需要在输入名称中添加索引,例如:tags[0]
,tags[1]
,或者只是按照概述附加[]
在2.4.x form docs section on repeated values。
另一方面,如果您希望单个文本字段接受以逗号分隔的值作为列表结束,那么您可以像这样对它们进行转换:
import play.api.data.Form
import play.api.data.Forms._
case class UploadTags(
tags: List[String]
)
object UploadTags {
val form = Form(
mapping(
"tags" -> text.transform[List[String]](
str => str.split(",").map(_.trim).toList,
list => list.mkString(",")
)
)(UploadTags.apply)(UploadTags.unapply)
)
}
即。提供一个函数来将值打包并解压缩到单个表单字段中。
纠正文件上传应该/可以单独验证。