Mag*_*nus 6 scala playframework playframework-2.0
我观察到,当我向Play Framework Form-class添加超过18个参数时,我得到一个很长的(并且对我来说难以理解)编译错误.
这是文件限制吗?我需要在表单帖子中接收多达29个参数.我没有决定参数的设计和数量,因为我正在从开放标准实现协议.
我这样映射:
val registration = Form(mapping(
"client_type" -> nonEmptyText,
"client_id" -> optional(nonEmptyText),
... up to 29 args, all optional(nonEmptyText)
){ (clientType, clientId ...) => RegistrationRequest(clientType, clientId ...) }
{ req => None })
Run Code Online (Sandbox Code Playgroud)
我的策略是以这种方式进行映射,而不是应用/取消应用,并创建一个案例类的层次结构.原因是在Case类中解决了22个参数限制,这是我遇到的第一个看似任意的限制.最多18个args映射工作,之后我得到一个很长的编译错误.
可以在此处找到错误消息(包括太长时间):https://gist.github.com/2928297
我正在寻找关于如何解决这个限制的建议.我知道在Post表单中发送29个参数是不好的设计,但它应该仍然可行.
哈克/变通方法/解决方案
好的,这是我的黑客一起解决方法(写这篇文章比实施花了更长的时间,我在这上面砍了大约30分钟)
我编写了预处理请求参数的函数,并添加了一个组前缀来对某些参数进行分组.然后我使用生成的Map [String,String]并继续使用表单类进行处理,像往常一样进行验证等.这允许我在映射中使用嵌套的case类,并且低于18 params限制.
当心:未来的丑陋代码!我可能不应该像这样显示早期的hacky代码,但我希望它能帮助其他想要解决方法的人.
def preprocessFormParams(prefix:String, replace:String)(implicit request:Request[AnyContent]):Map[String, String] = request.body.asFormUrlEncoded.map( _.filterKeys( _.startsWith(prefix)).map( m => m._1.patch(0, replace, prefix.length) -> m._2.head )).getOrElse(Map.empty)
def unprocessedFormParams(prefixes:Set[String])(implicit request:Request[AnyContent]):Map[String, String] = request.body.asFormUrlEncoded.map( _.filterKeys( !prefixes.contains(_) ).map( m => m._1 -> m._2.head )).getOrElse(Map.empty)
Run Code Online (Sandbox Code Playgroud)
所以这些函数可能应该用于理解或拆分,但是这里有:preprocessedFormParms接受前缀并替换它:
val clientParams = preprocessFormParams("client_", "client.")
("client_id" -> "val1", "client_type" -> "val2") becomes ("client.id" -> "val1", "client.type" -> "val2")
Run Code Online (Sandbox Code Playgroud)
当我有group.key1,group.key2形式的参数时,我可以像这样在表单中嵌套case类
Form(mapping("client" -> mapping("type" -> nonEmptyText
"id" -> optional(nonEmptyText),
"secret" -> optional(nonEmptyText))
(RegisterClient.apply)(RegisterClient.unapply)
... more params ...)
(RegisterRequest.apply)(RegisterRequest.unapply)
Run Code Online (Sandbox Code Playgroud)
在我的行动中,我继续过滤掉我的每个小组
implicit request =>
val clientParams = preprocessFormParams("client_", "client.")
val applicationParams = preprocessFormParams("application_", "application.")
val unprocessedParams = unprocessedFormParams(Set("client_", "application_"))
val processedForm = clientParams ++ applicationParams ++ unprocessedParams
Run Code Online (Sandbox Code Playgroud)
最后,我可以像平常一样应用我的表单,但现在我得到了嵌套结构,减少了参数的数量,并希望使案例类更易于管理.
clientRegistrationForm.bind(processedForm).fold( ... )
Run Code Online (Sandbox Code Playgroud)
使用此方法可以减少参数数量.如果你的参数没有像我的问题那样容易分组的相同前缀,那么你仍然可以使用相同的基本方法,但过滤其他标准.