【问题标题】:Play/Scala/Anorm saving answer to variable number of questionsPlay/Scala/Anorm 保存可变数量问题的答案
【发布时间】:2015-08-15 04:30:39
【问题描述】:

我正在使用带有 anorm/pgsql 的 play 框架来创建一个调查应用程序。由于某些响应具有嵌套响应类型,因此对问题的响应以 JSONB 格式保存。我可以通过 POST'ing 到我的 routes.conf 文件中定义的路由来保存对单个问题的响应,但是我无法思考如何创建逻辑以一次接受多个问题的逻辑。基本上,当单击调查上的“下一步”按钮时,将发布 2-n 个问题的答案。我有如下代码,但目前不确定如何使用 POST 对其进行测试:

  def jsonSaveMany(userResponses:List[Response],email:String,id:Long) = {
    DB.withConnection{
      implicit c =>
       for (response <- userResponses) jsonSave(response,response.useremail,response.id)

    }
  }
  def jsonSave(usersResponse:Response,email:String,id:Long) = {
    DB.withConnection{
      implicit c =>
        val userResponse=usersResponse.response
        val userJson:String = s"""{"response":"$userResponse"}"""
        val pgObject = new PGobject();
        pgObject.setType("jsonb")
        pgObject.setValue(userJson)
        SQL(s"INSERT INTO responses(response,useremail,questionid) values ({userResp},{eMail},{quesId})")
          .on('userResp -> anorm.Object(pgObject), 'eMail -> s"$email",'quesId -> id)
          .executeInsert(SqlParser.scalar[String].singleOpt)
    }
  }

我一直在使用 Twirl 模板引擎测试的视图文件采用 @(responseForm: Form[Response]) 参数,但基本上我需要能够为其提供一个 Form[Response] 类型的列表,其中列表的范围可以是 2-n 个问题.我似乎找不到更好的方法来制定这个,甚至无法测试这个逻辑是否有效。我不确定如何在我用来测试的 scala.html 文件中创建一个 Form[Response] 列表。

我最近尝试的另一种方法是在响应案例类的伴随对象中使用 JSON inception,如下所示:implicit val responseReads = Json.reads[Response] 但我无法通过 CURL 测试发布到此,因为当我没有任何响应时POST 到我为此函数定义的路由。

我的问题基本上是,我如何利用地图类型的功能来获取每个问题并将响应保存到数据库并通过简单的前端 GUI 或终端的基本 CURL 进行测试?

【问题讨论】:

  • 你试过哪个代码?
  • 我已经实现了隐式 Json.reads 以及 jsonSaveMany() 函数。我的问题基本上是如何检查它是否工作......当我从终端卷曲时,即使对于我已经工作的路线,我也看不到与使用浏览器时相同的输出。如果我可以有一个简单的前端文本输入,在“提交”上提交 JSON,这将帮助我知道我的隐式阅读器是否工作
  • 我在使用 jsonSaveMany() 函数时遇到的问题是我不确定如何在 scala.html 文件中包含可变长度的响应类型列表,我可以使用这些文件将数据发回服务器。我在使用 jsonSave 函数的 scala.html 文件中实现了单个响应 GUI,这适用于单个问题响应。
  • 我尝试添加一个文本字段并将 JSON 对象直接放入其中并像 {"useremail":"my@email.com","re​​sponse":"myAnswer"} 那样发布它我得到了POST noSuchElementException None.get 的内部服务器错误

标签: json playframework anorm


【解决方案1】:

最终我放弃了 jsonSaveMany() 函数并在 ResponseController 文件而不是我的 DBController 文件中进行了理解。

为了有效地测试这一点,我使用了 ws.URL Future 调用,它直接调用了我自己的 API 端点。这样,我可以简单地通过 scala.html 页面中的简单链接进行身份验证和测试,该页面发布了 JSON 对象的虚拟序列,以测试它们是否成功发布。我的单元测试如下所示:

def postJSONTest = SecuredAction {
    request =>
      val datum1 = Json.obj(
        "questionid" -> 14,
        "id" -> 14,
        "response" -> "godzilla"
      )

      val datum2 = Json.obj(
        "questionid" -> 15,
        "id" -> 15,
        "response" -> "van halen"
      )

      val data = JsArray(Seq(datum1,datum2))
      val email = request.identity.email.get
      val url = s"http://localhost:9000/response/save/$email"
      val futureResponse: Future[WSResponse] = ws.url(url).post(data)
      Redirect(routes.ResponseController.responses).flashing("success" -> "JSON posted!")
  }

我正在使用剪影进行身份验证/授权,request.identity.email.get 检索当前登录用户的电子邮件。

当我将数据附加到数据时,它会呈现为 json 数组,如下所示:

[{"questionid":14,"id":14,"response":"godzilla"},{"questionid":15,"id":15,"response":"van halen"}]

我的响应案例类包含一个隐式 json 读取器,如下所示:

case class Response (questionid:Long,
                     id:Long,
                     response:String)


object Response {
  /**
   * the implicit reader responseReads converts incoming JSON with
   * keys equal to the property names of the Response case class
   * into a format that is easily saved to pgSQL
   */
  implicit val responseReads=Json.reads[Response]

我的 ResponseController.scala 文件中的函数包含一个 for-comprehension,它使用隐式 JSON 读取方法将 JSON 对象数组中的每个元素转换为 Response 对象。这使它成为一种易于保存到 pgSQL 中的格式。

  def postResponse(email:String) = Action {
    implicit request =>
        val json = request.body.asJson.get
        val jsonList = json.as[List[JsObject]]
        for (item <- jsonList) {
            val oneItem = item.as[Response]
            Response.jsonSave(oneItem,email)
            }
        Ok("success")
  }

这是我的一般方法,真正帮助我的部分是使用Future[WSResponse] = ws.url(url).post(data) 将 JSON 数据直接发布到我的应用程序中。我尝试使用 CURL 和 chrome 扩展 POSTMAN,但在使用这些方法时遇到了问题。希望这个答案可以帮助其他使用 play/scala 的人。

【讨论】:

    猜你喜欢
    • 2018-07-22
    • 1970-01-01
    • 2021-04-13
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多