【问题标题】:Spring MVC: Error 400 The request sent by the client was syntactically incorrectSpring MVC: Error 400 客户端发送的请求语法错误
【发布时间】:2013-07-22 16:05:06
【问题描述】:

这似乎是一个常见问题。我已经回答了 SO 中给出的所有答案,但无法使其正常工作。
我正在尝试将 Spring MVC+Freemarker 集成到现有的 Web 应用程序中。它适用于GET 请求,并且 Freemarker 模板可以毫无问题地读取 Controller 提供的 java 对象。
但表单提交无法命中控制器方法。最后我让 log4j 工作了。这是我得到的错误:
错误

    HandlerMethod details: 
    Controller [application.entry.controller.UserController]
    Method [public void application.entry.controller.UserController.handleSave(java.lang.String)]

    org.springframework.web.bind.MissingServletRequestParameterException: 
Required String parameter 'action' is not present


Freemarker:

<form method="POST" action="save.html">
  ------------
  <input type="submit" class="btnnew" name="saveWithoutValidation" value="Save Without Validation"></input>
  <input type="submit" class="btnnew" name="submit" value="Submit"></input>
</form>

context-root 是 PORTAL
spring-servlet.xml

<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
      <property name="cache" value="true"/>
      <property name="prefix" value=""/>
      <property name="suffix" value=".ftl"/>

web.xml

<servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

控制器

@RequestMapping(value="/save", method=RequestMethod.POST)
    public void handleSave(@RequestParam String action){

        if( action.equals("submit") ){
            System.out.println("Damn! You clicked submit");
        }
        else if( action.equals("saveWithoutValidation") ){
           System.out.println("Sweet! You want no string attached.");
        }

    }

对于日志,我尝试将 log4j.logger.org.springframework.web=DEBUG 添加到我现有的 log4j.properties 中,但没有成功。

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    我也有这个问题,我的解决方案不同,所以在这里添加任何有类似问题的人。

    我的控制器有:

    @RequestMapping(value = "/setPassword", method = RequestMethod.POST)
    public String setPassword(Model model, @RequestParameter SetPassword setPassword) {
        ...
    }
    

    问题是对象应该是 @ModelAttribute,而不是 @RequestParameter。此错误消息与您在问题中描述的相同。

    @RequestMapping(value = "/setPassword", method = RequestMethod.POST)
    public String setPassword(Model model, @ModelAttribute SetPassword setPassword) {
        ...
    }
    

    【讨论】:

    • @ModelAttribute 将起作用,因为它还将请求绑定到带注释的目标。 @RequestParam 不过更适合单独绑定请求参数。
    【解决方案2】:

    @RequestParam String action 表明请求中存在一个名为 action 的参数,而您的表单中没有该参数。您必须:

    1. 提交一个名为 value 的参数,例如&lt;input name="action" /&gt;
    2. @RequestParam 中将所需参数设置为false,例如@RequestParam(required=false)

    【讨论】:

      【解决方案3】:

      另一个可能的原因是 RequestMapping 属性的顺序错误。 正如春季文档所说:

      @RequestMapping 处理程序方法可以具有非常灵活的签名。 支持的方法参数和返回值在 下一节。 大多数参数可以以任意顺序使用 BindingResult 参数的唯一例外。这在 下一节。

      如果您向下滚动文档,您会看到 BindingResult 必须紧跟在模型属性之后,因为我们可以在每个请求中拥有多个模型对象,从而实现多个绑定

      Errors 或 BindingResult 参数必须遵循模型对象 立即绑定,因为方法签名可能有 多个模型对象,Spring 将创建一个单独的模型对象 它们每个的 BindingResult 实例,因此以下示例不会 工作:

      这里有两个例子:

      BindingResult 和@ModelAttribute 的排序无效。

      @RequestMapping(method = RequestMethod.POST) 公共字符串 processSubmit(@ModelAttribute("pet") 宠物宠物,模型模型, BindingResult result) { ... } 注意,里面有一个 Model 参数 Pet 和 BindingResult 之间。要使其正常工作,您必须重新订购 参数如下:

      @RequestMapping(method = RequestMethod.POST) 公共字符串 processSubmit(@ModelAttribute("pet") 宠物宠物,BindingResult 结果, 模型模型){ ... }

      【讨论】:

        【解决方案4】:

        我遇到了类似的问题,发现像 Date 这样的几个字段没有得到具体的值,一旦给定了值,事情就很好了。请确保表单上没有日期或任何其他需要具体值的字段。

        【讨论】:

        • 这对我来说是个问题。我只是假设 Spring 会处理日期字段的空值,但我猜不是?
        【解决方案5】:

        根据错误:

        Required String parameter 'action' is not present
        

        Spring 的请求中需要有一个名为 action 的请求参数,以便将请求映射到您的处理程序 handleSave

        您粘贴的 HTML 没有显示此类参数。

        【讨论】:

          【解决方案6】:

          控制器试图在 bean 中查找“action”值,但根据您的示例,您没有设置任何“action”的 bean 名称。 尝试做 name="action"。 @RequestParam 总是在 bean 类中找到。

          【讨论】:

            【解决方案7】:

            我的问题是我的模型属性后缺少BindingResult 参数。

             @RequestMapping(method = RequestMethod.POST, value = "/sign-up", consumes = "application/x-www-form-urlencoded")
                public ModelAndView registerUser(@Valid @ModelAttribute UserRegistrationInfo userRegistrationInfo
                                            HttpServletRequest httpRequest,
                                            HttpSession httpSession) { ... } 
            

            添加BindingResult后,我的控制器变成了

            @RequestMapping(method = RequestMethod.POST, value = "/sign-up", consumes = "application/x-www-form-urlencoded")
                public ModelAndView registerUser(@Valid @ModelAttribute  UserRegistrationInfo userRegistrationInfo, BindingResult bindingResult,
                                            HttpServletRequest httpRequest,
                                            HttpSession httpSession) { ..}
            

            检查答案@sashok_bg @sashko_bg Mersi mnogo

            【讨论】:

              【解决方案8】:

              您的请求映射是/save,但您的POST 是/save.html。将 POST 更改为 /save 应该可以修复它。

              【讨论】:

              • 实际上/save 给了我404。我确实尝试过&lt;form method="POST" action="save"&gt; 但同样的错误。
              【解决方案9】:
              @CookieValue(value="abc",required=true) String m
              

              当我将 required 从 true 更改为 false 时,它​​成功了。

              【讨论】:

                【解决方案10】:

                请保留你的

                <form method="POST" action="XYZ">
                
                @RequestMapping(value="/XYZ", method=RequestMethod.POST)
                    public void handleSave(@RequestParam String action){
                

                您的表单动作属性值必须与@RequestMapping的值匹配,这样Spring MVC才能解决它。

                另外,正如您所说,更改后会出现404,为此,请检查handleSave()方法中是否有控件进入。

                我认为,由于您没有从 handleSave() 方法返回任何内容,因此您必须查看它。

                如果还是不行,请把你的spring日志贴出来。

                另外,请确保您的请求应该像

                /PORTAL/save
                

                如果在PORTAL/jsp/save 之间有任何内容,请在@RequestMapping(value="/jsp/save") 中提及

                【讨论】:

                • 如果您能分享错误原因会很有帮助,这将有助于其他面临类似错误的人。
                • 我在我的问题中添加了例外。但不知道如何解决它。
                • 我认为异常是由于您的参数由 handleSave(@RequestParam String action) 方法引起的。在 html 表单中找不到 handleSave 方法中的参数的映射。尝试通过将 handleSave 方法更改为 handleSave(){ // 你的代码} 来运行应用程序
                • 好的。那么我将如何获取所有表单值以及单击了哪个按钮?
                • 一种方法是 public void handleSave(HttpServletRequest request) {String data1 = request.getParameter("your_html_element_name");}
                【解决方案11】:

                在您的方法中添加 BindingResult 参数。请参考下面的代码。

                save(@ModelAttribute Employee employee,BindingResult bindingResult)

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-01-04
                  • 2012-08-27
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-12-21
                  • 1970-01-01
                  相关资源
                  最近更新 更多