2015-02-10 3 views
0

Я использую Bootstrap tagsinput для аннотирования моего файла с тегами:Filebodyparser с текстовым полем ввода в PLAY2

@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(_))) 

ответ

1

Если вы хотите, значение формы будет разобран в виде списка вам нужно добавить индекс к названию ввода, например: tags[0], tags[1], или просто append [], как описано в 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) 
) 
} 

т.е. предоставить функцию упаковать и распаковать значения в это поле одной формы.

Исправьте, что загрузка файла должна/может быть проверена отдельно.

+0

ваш синтаксический анализ работает нормально, но проблема возникает, когда я добавляю requestCsvBodyParser. Я добавил свой Bodyparser. – boraas

Смежные вопросы