PlayFramework FakeRequest返回400错误 [英] PlayFramework FakeRequest returns 400 error

查看:135
本文介绍了PlayFramework FakeRequest返回400错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在路线上:

POST        /login                  controllers.ApplicationCtrl.login()

在控制器中:

  def login = Action(parse.json) { implicit request => {

    val email = (request.body \ "email").as[String]
    val password = (request.body \ "password").as[String]

     Ok(Json.toJson(
       Map("status" -> "OK",
        "message" -> "%s created".format(email))
      ))
}

正在测试

 "login" in new WithApplication{

      val request = route( FakeRequest(
        Helpers.POST,
        controllers.routes.ApplicationCtrl.login.url,
        FakeHeaders(Seq(CONTENT_TYPE -> Seq("application/json"))),
        """ {"email" : "bob@mail.com", "password" : "secret"} """
      )).get

      status(request) must equalTo(OK)

    }

当我使用命令行进行测试时:

When I test using command line:

curl --header "Content-type: application/json" --request POST --data '{"email" : "bob@mail.com", "password" : "secret"}' http://localhost:9000/login

得到令人满意的响应.

{"status":"OK","message":"bob@mail.com created"} 

但是测试返回 400错误.

怎么了?

(命令行测试以简单和易懂而获胜)

(command line test wins by simplicity and understandability)

推荐答案

此处发生的是Play根据正文的类型设置了请求的内容类型.您使用的是字符串正文,以便您稍后设置的内容类型标头会被text/plain; charset=utf-8覆盖.

What's happening here is that Play sets the content type of the request according to the type of the body. You're using a string body so that the content type header you're setting is later overridden by text/plain; charset=utf-8.

因为您将主体明确地解析为Json,所以如果内容类型不是text/jsonapplication/json,主体解析器将返回错误的请求403.

Because you're explicitly parsing the body as Json the body parser will return a bad request 403 if the content type is not either text/json or application/json.

在您的情况下,最好的方法是使用Json主体,即:

The best thing to do in your case is to use a Json body, i.e:

"login" in new WithApplication {

  val request = route( FakeRequest(
    POST,
    controllers.portal.routes.Portal.test.url,
    FakeHeaders(Seq.empty),
    play.api.libs.json.Json.obj("email" -> "bob@mail.com", "password" -> "secret")
  )).get

  status(request) must equalTo(OK)
}

请注意,您可以通过让备用FakeRequest构造函数从调用中推断出操作的方法和URL来使其更加简洁:

Note that you can make that a bit more succinct by letting an alternate FakeRequest constructor infer the method and URL of your action from the call:

val request = route(FakeRequest(controllers.portal.routes.Portal.test)
    .withBody(Json.obj("email" -> "bob@mail.com", "password" -> "secret"))).get

可用作主体参数的数据类型及其内容类型映射:

Data types you can use as the body parameter and their content type mapping:

  • JsValue-> application/json
  • NodeSeq-> text/xml
  • String-> text/plain
  • Map[String, Seq[String]]-> application/x-www-form-urlencoded
  • Array[Byte]->没什么
  • JsValue -> application/json
  • NodeSeq -> text/xml
  • String -> text/plain
  • Map[String, Seq[String]] -> application/x-www-form-urlencoded
  • Array[Byte] -> nothing

还有一种选择,可以使用tolerantJson作为正文解析器来完全跳过对内容类型的检查.

There's also the option of using the tolerantJson as a body parser to skip checking the content type completely.

这篇关于PlayFramework FakeRequest返回400错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆