【问题标题】:redirect from method with http DELETE type to method with GET type从 http DELETE 类型的方法重定向到 GET 类型的方法
【发布时间】:2014-06-23 12:34:23
【问题描述】:

我使用类型为“DELETE”的 jquery ajax 发送我的请求。在服务器端,我有适当的句柄方法,如下所示:

   @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public String delete(@RequestParam("hotel") String hotelCode, @PathVariable Long id, Model model){
        //delete operation
        return "redirect:/HotelTaxesAndCharges?hotel="+hotelCode;
    }

删除后我想将呼叫重定向到的方法如下所示

@RequestMapping(method = RequestMethod.GET)
public String getAll(@RequestParam("hotel") String hotelCode, Model model){
    //logic
    return 'getAll';
}

所以当我在执行期间调用 delete 方法时,我收到错误“您可以仅使用 GET PUT 或 HEAD 方法重定向到 JSP”。我找到了使用 HiddenHttpMethodFilter 的解决方案,但结果代码看起来有点乱,我需要使用 POST 发送请求并添加附加参数 (_method) 以请求自定义请求类型。

所以我的问题是 DELETE/REDIRECT/GET 转换是否有其他解决方案。

抱歉英语不好

更新

所以你也可以使用 delete 来重定向它。如果我将所有内容从删除更改为发布,我会得到:

【问题讨论】:

  • 你从哪里得到错误?错误消息的具体外观如何?
  • @axtavt,我在重定向期间收到错误,错误消息现在看起来像“不支持请求方法'DELETE'”。而且我不知道如何将请求类型从删除转换为重定向。
  • 如果我 POST 类型而不是 DELETE 一切正常
  • 你能监视你的浏览器和你的服务器之间的对话吗(wireshark 很擅长)?我在精简控制器@RequestMapping(value="/delete", method=RequestMethod.DELETE) public String delete(HttpServletRequest req) { return "redirect:/welcome"; } 的以下方法中尝试了重定向,用DELETE 方法调用它,然后......得到了正确的重定向响应。我认为问题不在于 spring-mvc(使用 spring 3.2.4 和 tomcat 7)
  • @SergeBallesta,我添加了两个屏幕截图。首先,您可以在重定向过程中看到错误,因为结果方法请求类型 = GET。在第二个屏幕截图中,您可以看到如果我将删除更改为发布一切顺利,结果方法是 GET

标签: java spring-mvc


【解决方案1】:

发生的事情是正常的,即使它不是你需要的:

  • 您从 ajax 提交 DELETE 请求
  • Spring 控制器接收它并回答“redirect:/.../Hotel...”
  • Spring ViewResolver 发送带有代码 302 和正确 Location 标头的重定向响应
  • 浏览器使用先例方法和新位置(对于 302 来说是正常的)发出 DELETE(当您期望得到时)
  • @RequestMapping 用于 method=GET 时,Spring DispatcherServlet 接收到 DELETE /.../Hotel...
  • Spring DispatcherServlet 正确声明未定义控制器并发出错误

所有这些都由您的 wireshark 痕迹确认

当您发送 POST 请求时,它会起作用,因为为了与 HTTP 1.0 兼容,所有主流浏览器都使用 GET 进行重定向,就像状态为 303 时一样

有一个直接的解决方法:允许重定向 URL 的方法接受除 GET 之外的 DELETE。不是很贵,但不是很好。

您还可以在客户端管理重定向:只需发送一个 200 代码,ajax 将接收该代码,然后让 ajax 进行重定向

最后一个解决方案是使用 303 代码,该代码明确要求浏览器独立于之前的方法发出 GET。您可以通过让控制器请求将 HttpServletResponse 作为参数并返回 null 来对其进行硬编码。然后手动添加 Location 标头和 303 状态代码。

但是您也可以通过将其 redirectHttp10Compatible 属性设置为 false 来配置 InternalResourceViewResolver 以返回 303 代码而不是 302。您只需在 servlet 应用程序上下文中声明一个 bean,Spring 就会使用它。但是您会失去与不支持 HTTP 1.1 和 303 状态代码的旧浏览器的兼容性。

【讨论】:

  • 我更了解您为什么获得 +100k 声望。谢谢。
猜你喜欢
  • 2011-08-11
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
相关资源
最近更新 更多