如何在Play(Scala)中中断响应



我是使用Scala的Play Framework的新手。我想评估一个条件,在该条件评估为true时,我想发送一个响应并在该点退出。然而,我正在尝试的下面的代码一直持续到最后。

我尝试用return语句中断-但是,我得到了一个类型不匹配。有人能帮我吗?

def hello = Action { request =>
    if (true) {
      Ok("in If")
      // Return at this point
    }
    print("This line should not be printed")
    Ok("final") 
}

编辑

假设使用4个参数进行GET调用——nameagemarriedspouse。我想确保所有3个参数(nameagemarried)都通过了,如果married为真,请检查spouse是否通过了。如果此验证失败,我想回复说Bad Request。否则,继续逻辑。我该怎么写?

这里有一种替代方法:

case class QueryInput(name: String, age: Int, married: Boolean, spouse: Option[String]) {
  def validated = if(married && spouse.isEmpty) None else Some(this)
}
def validateInput(request: RequestHeader) = {
  val input = for {
    name <- request.queryString.get("name").flatMap(_.headOption)
    age  <- request.queryString.get("age").flatMap(_.headOption.flatMap(a=>Try(a.toInt).toOption))
    married <- request.queryString.get("married").flatMap(_.headOption.map(_=="true"))
  } yield {
    QueryInput(name, age, married, request.queryString.get("spouse").flatMap(_.headOption))
  }
  input.flatMap(_.validated)
}
def hello() = Action { request =>
  validateInput(request) match {
    case Some(input) => Ok(input.toString())
    case None => BadRequest
  }
}

事实上,有很多选择。您还可以使用"任一"类进行验证:左值用于累积错误并返回错误请求,右值用于构造已验证的输入。

我的建议是使用一种方法来验证参数。然后执行一个简单的if/else检查参数是否有效,并返回成功或一般错误。

如果您真的想要一个特定的

第一件事:

当块进行计算时,它的所有表达式和声明都会按顺序进行处理,然后块将最后一个表达式的值作为自己的值返回。

第二:不要使用return。

第三个是解决问题的Play Framework方法:动作合成。尽管我不会说这是微不足道的。

您可以通过在中返回Ok来实现这一点,但实际上,这不是scala方法。你想做的是改变你的心态,把一切想象成一种功能。如果你不知道,If-then-else总是返回一个值。例如,您实际上可以这样写:

def hello = Action { request =>
  val result = if (true) {
    Ok("foo")
  } else {
    Ok("bar")
  }
  result
}

当然,一种更为标量化的方法是使用匹配器

def hello = Action { request =>
  val result = true match {
    case true => Ok("foo")
    case _ => Ok("bar")
  }
  result
}

更进一步,您甚至根本不需要指定结果对象,因为scala根据返回/创建的最后一个对象来计算返回的对象。

def hello = Action { request =>
  true match {
    case true => Ok("foo")
    case _ => Ok("bar")
  }
}

编辑:要回答OP的编辑,您仍然需要使用匹配器。假设你的vals是可选的,下面是你要做的:

def hello(nameOpt:Option[String], ageOpt:Option[String], marriedOpt:Option[String]) = Action { request =>
  (nameOpt, ageOpt, marriedOpt) match {
    case (Some(name), Some(age), Some(married)) => Ok("all 3 are given")
    case (Some(name), Some(age), _) => Ok("all 2 are given")
    // functionally same as above
    // case (Some(name), Some(age), None) => Ok("all 2 are given") 
    // some combination of the above
    case (None, None, Some(married)) => Ok("married but no name or age")
    // default case
    case _ => Ok("bar")
  }
}

最新更新