警告:请求方式“GET”不受支持

3

在我的Spring应用程序中,我是这样做的...

我的JSP表单点击超链接后将被发送...

<form:form action="user" modelAttribute="NAME">

   <a href="href_form1" onclick="onClick_Save()" class="save">Save</a>

</fomr:form>
<script>
  function onClick_Save() {
    $("#NAME").attr("action", $('.save').attr("href"));
    $("#NAME").submit();
     });
</script>

在我的控制器类中,我编写了一个方法。
@RequestMapping(value = "href_form1", method = RequestMethod.POST)
public @ResponseBody String href_form1(UserForm userForm,Model model)throws Exception {
    //Database code here.       
    model.addAttribute("NAME", userForm);
    return "User Updated";
}

编辑1:

WARNING: Request method 'GET' not supported

我遇到了错误页面。
HTTP Status 405 - Request method 'GET' not supported

编辑:修改后的代码如下所示

   <script>
  $(function() {
   $('.save').on("click",function(e) {
     e.preventDefault();
     $("#NAME").attr("action", $(this).attr("href")).attr("method","POST");
     $("#NAME").submit();
   });
  });
</script>

但是我的表单无法到达我的控制器方法。 我的代码有什么问题吗?我还尝试在表单标签中使用了method="POST"。
4个回答

1

这里是您出现错误的原因:

当您点击链接时,链接的href调用控制器,因为您没有取消链接的默认操作。

所以代码执行以下操作:

  1. 尝试将表单的操作设置为链接的href
  2. 尝试使用POST提交该表单-这就是我理解您想要实现的内容。
  3. 无论是否成功,浏览器立即遵循链接的href,如果onclick不停止该操作,则会像链接一样进行GET,尝试调用控制器。 即使代码成功地向服务器发送了表单数据,该请求也会被新请求覆盖并以GET方式结束。

在我看来,您有以下几种可能性-其中一些应该比其他更好:

非JavaScript方案

  1. 拥有一个参数来保存你想要保存的内容,并为每个参数建立一个表单。
  2. 更改你的Spring方法为:
    method = { RequestMethod.GET, RequestMethod.POST} 或者
    method = RequestMethod.GET - 使用 GET 可以摆脱表单,只需要更新Spring代码后使用下面的链接即可。
 <a href="href_link?user=user1">Save User1</a>

如果您希望

JavaScript 协助

在表单中有一个参数,保存您想要保存的内容,通过 JavaScript 设置它,并执行必需的 return falsepreventDefault 来取消链接:

<!-- this is an example of the rendered form -->
<form action="href_form1" id="NAME" method="POST">
  <input type="hidden" name="saveItem" id="saveItem" value="" />
</form>  

<a href="#" class="saveLink" data-save="save item 1">Save item 1</a>
<a href="#" class="saveLink" data-save="save item 2">Save item 2</a>
<a href="#" class="saveLink" data-save="save item 3">Save item 3</a>

请注意,我在href中没有链接以避免请求任何内容。
与此过程配合的jQuery:
$(function() {
  // assuming form ID="NAME"
  $(".saveLink").on("click",function(e) { 
     e.preventDefault(); // do not follow link
     $("#saveItem").val($(this).data("save")); // set the hidden field
     $("#NAME").submit();
  });
});

如果你的Spring控制器已经连接好处理请求,这里有一个或许更有趣的方法:

DEMO

  $(function() {
   $('.save').on("click",function(e) { // passing event
     e.preventDefault(); // jQuery will normalise it for all modern browsers
     // post the href of the link to the server and return the result in a 
     // container with ID result
     $.post($(this).attr("href"), function(data) { // or $.get if you want
       $('#result').html(data);
     });
  });

1
@mplungjan,我建议你的答案,我认为你熟悉JavaScript而不是Spring..无论如何,我会投赞成票。 - user2294201
返回false并不能总是阻止事件传播。在IE8中,使用e而不是event是不兼容的。如果e上没有定义preventDefault()(就像许多旧浏览器中一样),那么你将会遇到未知方法错误。在JavaScript中更改表单属性是可怕的做法,完全违反了可读性。你已经使用类属性分配了一个特定的操作,而不是建议使用新的id(你知道类和id之间的区别吗?)。我很难相信你一直以这种方式编程,就像你的个人资料所说的那样。 - AmbrosiaDevelopments
(e)已被jQuery标准化。我不想升级到你试图挑起的个人攻击,只是建议在发表此类评论之前先查看jQuery。在像OP这样简单的HTML中,返回false就可以正常工作。我使用类别是因为显然OP有不止一个链接,而且使用上述代码后,每个链接都会在点击时将其href分配给表单。 是的,我有超过15年的实际JS经验。 - mplungjan
$("saveItem").val($(this).data("save")); // 设置隐藏字段 - AmbrosiaDevelopments
感谢您友善地指出我在iPhone上忽略的遗漏。已经更正。 - mplungjan
显示剩余8条评论

1
您需要在form标签中指定method。是的,您的超链接忽略了表单。因此,请将表单上的action属性设置为href_form1,并将您的超链接更改为提交输入,或者(我不太建议这样做)将您的超链接更改为JavaScript提交。目前,您的链接同时设置了onclickhref。以下是最佳实践。
<form:form action="href_form1" modelAttribute="NAME" method="POST">
    <input type="submit" value="Save" />

此外,您的jQuery选择器$("#NAME")没有找到任何内容,因为您没有在要获取的表单上设置id属性。

我已经再次尝试这个,但是仍然遇到同样的问题。实际上,我点击了超链接而不是提交按钮,所以这会有什么问题吗? - user2294201
修改答案以回应您的评论。同时摆脱您的jQuery。您不需要它,无论如何它都不应该真正出现在JSP中。您应该为不同情况使用不同的表单元素,或者考虑重新设计您的应用程序。 - AmbrosiaDevelopments
听起来像是一个不熟悉 Spring 并认为 JavaScript 可以解决所有问题的人。如果他需要发送特定数据,则应使用不同的表单参数并在控制器中处理它。这正是 MVC 创建的确切原因,即分离此类事物。 - AmbrosiaDevelopments
所以,你有没有抽出时间更新现代技术,撤下你对我的编程技能的贬低和嘲讽性评论呢?特别是因为我当前的建议中没有任何东西不符合你发送不同参数到控制器的建议。 - mplungjan
我承认jQuery确实使用了一个完全跨浏览器的事件对象,具有任意名称。曾经有一段时间它没有这样做,谨慎是很重要的。除此之外,我之前的所有观点仍然有效,你仍然会被踩。难道你没有看到你的jQuery $.post()建议完全忽略了Spring表单吗?在这个问题中,jQuery不是唯一被标记的东西,也不是解决问题的方法。 - AmbrosiaDevelopments
在我的第一个建议中,我通过触发提交事件处理程序来发布表单。这将表现得像单击了提交按钮一样。第二个示例是为了完全摆脱表单,因为在我看来,它是任意地用作占位符执行 POST 的,由于 OP 无法使 Spring 控制器处理 GET 或确实使链接处理 POST。由于仍然不清楚应用程序的最终目标是什么,您或我的任何建议都可以适合该目的。 - mplungjan

1
请尝试类似这样的内容。
<form:form action="href_form1" modelAttribute="NAME" method="POST">
  <input type="submit"/>
</form:form>

@RequestMapping(value = "href_form1", method = RequestMethod.POST)
public @ResponseBody String href_form1(UserForm userForm,Model model)throws Exception {
    //Database code here.       
    model.addAttribute("NAME", userForm);
    return "User Updated";
}

基本上,这是一个非常简单的表单提交。一旦您使其正常工作,就知道您的表单和控制器已经正确设置。之后,如果您想使用锚点标签来提交表单,请回到先前的建议,preventDefault 然后提交表单。
希望这能有所帮助。

0

表单提交的默认 HTTP 方法是 GET。如果您想使用 POST,请指定它,就像这样:method="POST"

此外,我在代码中没有看到正确的 URL 映射。您能否确认它是否正确?


如果我们提到 method="POST",那么它就不起作用了。我的请求映射也正确吗?我看到过一次编辑源代码。 - user2294201
如果使用Firefox,则使用Firebug;或在Chrome中按F12键,然后进入网络部分以查看最终形成的URL。 - Bhushan Bhangale
谢谢您的回复。我正在使用@mplungjan的JavaScript建议,但表单实际上没有发送,我正在使用Eclipse调试视角。 - user2294201
请在您实施我们提出的各种建议后更新最新的代码。 - Bhushan Bhangale
即使添加了 method="POST",也只是因为他设置了一个 href 属性,导致它被跟踪而不是被忽略。此外,由于 JavaScript 没有引用表单,因为它没有 id 属性,所以 action 属性没有被更改。 - AmbrosiaDevelopments

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