Playframework Scala - 删除路由的问题

3
我正在大学的毕业项目中使用playframework,并且在路由DELETE或PUT方法时遇到了问题。当我请求DELETE或PUT方法时,会出现以下错误信息:

[info] play.api.Play - 应用程序已启动 (Dev) [debug] a.ErrorHandler - onClientError: statusCode = 404, uri = /Rest/deleteCity, message ="

我的JQuery ajax调用如下:
$("#scalaDelete").click(function(){
    $("#result").empty();   
    $.ajax({
        url: "http://localhost:9000/Rest/deleteCity",
        method: "DELETE",
        data: {city: "Alvorada"},
        dataType: "json",
        success: function(result){
            $("#result").append("Result: "+result.Result);
        },
        error: function (request, status, error) {
            alert(status);
        }
    });
});

我的路由播放路径:

DELETE       /Rest/deleteCity       controllers.RestController.deleteCity()

我的控制器方法:

case class UserDelete(city:String)
class RestController @Inject()(db: Database, cc: ControllerComponents) extends AbstractController(cc) {

val userDeleteForm = Form(
   mapping(
     "city" -> text
   )(UserDelete.apply)(UserDelete.unapply)
  )

  def deleteCity = Action{ implicit request=>
    val userPar = userDeleteForm.bindFromRequest.get
    //DatabaseDelete

    Ok(jsonResult)
  }

}

我已经在Chrome中激活了跨域,我使用了一个CORS扩展程序。

谢谢您的帮助

2个回答

1
这似乎与Play框架中的Restful http删除有关,即使用数据进行DELETE可能会有问题。
我建议不要传递数据,而是将其移动到URL中:
DELETE       /Rest/deleteCity/:city   controllers.RestController.deleteCity(city: String)
# or with a query string
DELETE       /Rest/deleteCity   controllers.RestController.deleteCity(city: String)

然后执行

http://localhost:9000/Rest/deleteCity/Alvorada
# or with a query string
http://localhost:9000/Rest/deleteCity?city=Alvorada

个人而言,我更喜欢后者。

{btsdaf} - Daniel Yanagita
{btsdaf} - Andy Hayden
@DanielYanagita 你也移除了 dataType 吗? - Andy Hayden
{btsdaf} - Daniel Yanagita
@daniel 这不是什么傻事,有时候你需要重新启动sbt(路由有时候需要重新启动才能生效) - Andy Hayden
显示剩余3条评论

0

我同意 @AndyHayden 的观点。

Play忽略了DELETE请求的主体,这是我认为正确的行为,但是你可以通过显式传递一个body解析器来解决:

def delete = Action(parse.json) { implicit request =>
  val json = request.body
  val someProp = (json \ "someprop").as[String]
  Ok(s"Prop is: $someProp")
}

(这个例子是Play本身的开发人员之一提供的:https://github.com/playframework/playframework/issues/4606#issuecomment-109192802。)

关于评论中的疑问:

我在这里看到另一篇帖子,一个人说有些浏览器只支持get和post方法。

POSTGET仅适用于form标签的method属性。

您正在使用JavaScript请求,因此可以使用服务器支持的任何方法。即DELETE在这里完全没有问题。

但你需要知道的有趣的事情是,playframework使用akka,这个框架出于安全原因不支持DELETE请求,实际上在帖子中没有很好地解释清楚。因此,如果您想要进行DELETE方法,您需要为完成代码制作一个post方法。

Akka HTTP支持DELETE请求(以及Play Framework):https://doc.akka.io/docs/akka-http/current/scala/http/routing-dsl/directives/method-directives/delete.html

嗨,首先感謝你的幫助;) 所以,如果我理解Akka文檔說的話,我需要編寫路由代碼來創建它,直接在路由文件中是行不通的。 我之前說過不支持DELETE,因為我的服務器給我一個警告說出於安全原因不支持該方法...我會試著通過編寫自定義路由代碼來實現它。 非常感謝! - Daniel Yanagita
嗨@AndriyKuba,很抱歉测试和反馈晚了...然后你们两个都是对的,有两种实现删除的方法。第一种是通过post传递值,并在route.config中创建一个简单的post路由。第二种是通过Get传递值,但为了成功获取,我不得不指定我的Route.config为一个路由方法并编写它的代码。 - Daniel Yanagita

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接