加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

斯卡拉 – Play Framework Form只有18个参数

发布时间:2020-12-16 09:59:27 所属栏目:安全 来源:网络整理
导读:我观察到,当我向Play Framework Form-class添加超过18个参数时,我得到一个很长的(并且对我来说难以理解)编译错误. 这是文件限制吗?我需要在表单帖子中接收多达29个参数.我没有决定参数的设计和数量,因为我正在从开放标准实现协议. 我这样映射: val registr
我观察到,当我向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 })

我的策略是以这种方式进行映射,而不是应用/取消应用,并创建一个案例类的层次结构.原因是在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)

所以这些功能可能应该用于理解或拆分,但这里有:
preprocessedFormParms获取前缀并替换它:

val clientParams = preprocessFormParams("client_","client.")
("client_id" -> "val1","client_type" -> "val2") becomes ("client.id" -> "val1","client.type" -> "val2")

当我有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)

在我的行动中,我继续过滤掉我的每个小组

implicit request =>
val clientParams = preprocessFormParams("client_","client.")       
val applicationParams = preprocessFormParams("application_","application.")
val unprocessedParams = unprocessedFormParams(Set("client_","application_"))
val processedForm = clientParams ++ applicationParams ++ unprocessedParams

最后,我可以像平常一样应用我的表单,但现在我得到了嵌套结构,减少了参数的数量,并希望使案例类更易于管理.

clientRegistrationForm.bind(processedForm).fold( ... )

使用此方法可以减少参数数量.如果你的参数没有像我的问题那样容易分组的相同前缀,那么你仍然可以使用相同的基本方法,但过滤其他标准.

解决方法

几个星期前我就这个问题 opened a ticket了.

如果您投票支持它,也许它会从Play开发者那里看一下.

怀疑它在他们的优先级列表上是高的(不幸的是,它或多或少只是一个复制粘贴来解决19,20,21和22 Mapping [T])

如果你绝望,你可以分叉玩;否则,想出一个解决方法,例如,利用嵌套表格或拆分> 22场模型分成不同的形式.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读