2012-07-07 71 views
6

我正在使用scala 2.0.2 play框架實現web api。我想提取並驗證一些get參數。爲此,我使用了一個可以定義可選字段的play「form」。如何在遊戲框架表單中定義默認值可選字段?

問題: 對於那些可選字段,如果參數未被傳遞,我需要定義一個默認值。 代碼的目的是正確解析這三個用例:?

  • /測試頂= ABC(錯誤,ABC是不是整數)
  • /測試頂部= 123(有效的,頂部是123)
  • /測試(有效的,頂部爲42(默認值))

我已經提出了下面的代碼:

def test = Action { 
    implicit request => 

    case class CData(top:Int) 

    val p = Form(
    mapping(
     "top" -> optional(number) 
    )((top) => CData($top.getOrElse(42))) ((cdata:CData) => Some(Some(cdata.top))) 
).bindFromRequest() 

    Ok("all done.") 
} 

代碼有效,但絕對不是優雅。有很多鍋爐板只是爲缺少的請求參數設置默認值。

任何人都可以提出一個更清潔,更巧妙的解決方案嗎?

回答

8

這是驗證查詢字符串參數的路由器作業。剛剛在routes文件中定義的參數:

GET /test controllers.Application.test(top: Int ?= 42) 

而作爲一個參數添加top到控制器方法:

def test(top: Int) = Action { 
    // Use top here 
    val data = CData(top) 
} 

然後,播放做的所有驗證工作適合你。注意如何使用?=語法指定默認值。

您應該僅對POST請求使用表單。

更新:

如果你想手動檢查參數,則你可以定義helper方法:

def getQueryParam(key: String, default: String)(implicit request: RequestHeader) = 
    request.queryString.get(key).flatMap(_.headOption).getOrElse(default) 

而且使用它你的控制器方法中:

def test = Action { implicit request => 
    val top = getQueryParam("top", "42") 
    ... 

但通過這樣做你會丟失類型檢查。當然,您可以爲每種類型定義助手,例如getIntParamgetStringParam等,但Play已經包含安全路由器實現,旨在解決此類問題。我建議你使用路由機制而不是手動檢查。

+0

這個建議的解決方案效果很好。不幸的是,這個解決方案唯一的缺點是它不能很好地滿足大量的默認參數。當您構建必須支持列表過濾的Web服務/ Web應用程序時,公開路由中的所有默認參數可能會降低代碼的可讀性和健壯性。在所有其他情況下,這確實是首選解決方案 – natbusa 2012-07-09 20:41:21

+1

回答使用幫助方法實現更新,您可能會發現有用。 – lambdas 2012-07-10 05:09:56

+1

我已經提出了對play框架的擴展,以編程更多的關於默認參數的代碼驅動方法。請參閱https://github.com/playframework/Play20/pull/381 – natbusa 2012-07-12 17:10:50

12

在播放2.1

 
val p = Form(
    mapping(
     "top" -> default(number,42) 
    )(CData.apply)(CData.unapply) 
).bindFromRequest() 

會做你想要什麼。