2013-09-22 87 views
2

我要实现它解析BodyParser和验证request.body,它是基于parse.json,目前看起来是这样的:BodyParser基于请求主体返回结果

def parseModel[A](implicit reads: Reads[A]): BodyParser[JsResult[A]] = 
    parse.json.map(_.validate[A]) 

问题是,它的类型是目前BodyParser[JsResult[A]],而我希望它是BodyParser[A]类型。在JsError我想情况下,它基本上与验证错误返回400 Bad Request

Play API docs我不能找到一种方法,让我检查身体以前分析器的结果,并返回结果或继续到控制器。

回答

10

A BodyParser,解析正文后产生一个Either[SimpleResult, A],其中SimpleResult是应该立即返回而不是处理该操作的错误结果。在BodyParser便利方法没有让你这样做,所以取而代之,创建一个新的机构解析器委托给JSON解析器体:

def validateJson[A](implicit reads: Reads[A]) = new BodyParser[A] { 
    def apply(request: RequestHeader) = parse.json(request).map(_.right.flatMap { json => 
    json.validate[A].asEither.left.map(e => BadRequest(JsError.toFlatJson(e))) 
    }) 
} 

这里你可以看到,我们正在映射的解析结果,然后取right值(一次成功的解析,将JsValue),并呼吁它flatMap。我们flatMap方法从validateJsResult转换为Either[JsError, A],所以我们已经完成一半了与A,在那之后我们mapJsErrorSimpleResult,我们是好去。

0

好吧,我已经实现了通过一种方法产生的Action所需的行为:

def validateJson[A](implicit reads: Reads[A]) = 
    parse.json.map(_.validate[A]) 


def ModelAction[A](action: A => Result)(implicit r: Reads[A]) = 
    Action(validateJson[A]) { request => 
    request.body match { 
     case JsSuccess(model, _) => action(model) 
     case JsError(e) => BadRequest(JsError.toFlatJson(e)) 
    } 
    } 

我可以这样使用它:

def create = ModelAction[MyModel] { model => 
    ??? 
} 

我仍然有兴趣,如果有可能做同样与BodyParser,如果我必须这样做或它的更好,因为它是现在?