Question

I am trying to connect a form to another page using POST but I keep getting the error:

Request method 'POST' not supported

My handleNext method in the controller looks like this:

@RequestMapping(value = PAGE_NAME, method = RequestMethod.POST)
public String handleNext(ModelMap map, HttpServletRequest request,
    @ModelAttribute("indexBacking") IndexBacking bo, BindingResult result) {
    return "redirect:/" + GameController.PAGE_NAME;

}

And the GET method on the Game controller looks like this:

@RequestMapping(value = PAGE_NAME, method = RequestMethod.GET)
public String handleBasicGet(ModelMap map, HttpServletRequest request) {


    return MODEL_NAME;
}

My Web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
    <session-timeout>
        30
    </session-timeout>
</session-config>
<welcome-file-list>
    <welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>

Any ideas would be great.

UPDATE The index.jsp has the following reference to the backing object

<form:form action="index.htm" enctype="multipart/form-data"
           method="post" commandName="indexBacking" accept-charset="UTF-8">
      <table id="main">
          ${page_contents}
          <tr>
              <td></td>
              <td>
                  <spring:bind path="name">     
                      <form:input path="name" value="Name" />
                      <form:errors cssClass="vmessage"
                                   element="div" path="name" />
                  </spring:bind>
              </td>
              <td>
                  <input type="submit" value="Submit" />
              </td>
              <td></td>
          </tr>
      </table>
  </form:form>

and the backing object doesn't seem to set the name field here:

public class IndexBacking {
private String name;

/**
 * @return the name
 */
public String getName() {
    return name;
}

/**
 * @param name the name to set
 */
public void setName(String name) {
    this.name = name;
}

}
Was it helpful?

Solution

Request method 'POST' not supported

this error spring throws when following things are wrong:

  • HTML form action has some URL with method as POST and you don't have any controller methods to handle POST request to that URL.
  • missing or invalid @ModelAttribute in POST handler method.

coming to

the backing object doesn't seem to set the name field here:

inside <spring:bind you should use status object like:

  • status.value : to get the actual value of the bean or property.
  • status.expression : the expression that was used to retrieve the bean or property.
  • status.errorMessages : an array of error messages, resulting from validation

And No need to use <spring:bind.. when you use <form:form.. tag, both are almost does the same job, while <spring:bind.. is used to perform some customized operations. So choose either one in <form:sorm.. & <spring:bind..

in your case you can fix you problem using <spring:bind.. like:

<c:url value="/indexBackingUrl" var="pstUrl"/>
<form action="${pstUrl}"  method="post" >
      <table id="main">          
          <tr>
              <td></td>
              <td>Name: 
              <spring:bind path="indexBacking.name">                
                  <input type="text"
                        name="${status.expression}"                                                         
                            value="${status.displayValue}"/>                      
                            <c:if test="${status.error}">
                                Error codes:
                                <c:forEach items="${status.errorMessages}" var="error">
                                    <c:out value="${error}"/>
                                </c:forEach>
                            </c:if>
                </spring:bind>
              </td>
              <td>
                  <input type="submit" value="Submit" />
              </td>
              <td></td>
          </tr>
      </table>
  </form>

NOTE: name attribute is important in input element, cause spring binds bean property value using name of input element.

OR using <form:form.. without <spring:bind.. like:

<form:form action="${pstUrl}" method="post" modelAttribute="indexBacking">  
    <form:label path="name">Name:</form:label>
    <form:input path="name"/>
    <form:errors path="name" element="div"/>
</form:form>

and in Controller's GET handler method add IndexBacking bean instance with key as indexBacking to make work <spring:bind.. in jsp like:

@RequestMapping(value="/indexBackingUrl", method = RequestMethod.GET)
    public String handleNext(Model model) {
        model.addAttribute("indexBacking", new IndexBacking("Jon"));
        return "indexBacking";

    }

and POST handler method in controller will look like:

@RequestMapping(value="/indexBackingUrl", method = RequestMethod.POST)
    public String handleNextPost(ModelMap map, HttpServletRequest request,
            @ModelAttribute("indexBacking") IndexBacking bo, BindingResult result) {

        System.out.println(bo);
        return "redirect:/someOtherUrl";
    }

Edit: when you use enctype="multipart/form-data" in form, then you should register CommonsMultipartResolver bean and commons-io-x.x.jar & commons-fileupload-x.x.x.jar should be available to make work of spring binding or else you will get null value, In your case enctype="multipart/form-data" is not need as you not using any file upload etc.


See Also:

OTHER TIPS

I think you are redirecting to the url from the handleNext controller using post method but the target controller (the one to which the message is redirected) has only a Get method, so change get to post inside Game controller and try again. let me know for any issues.

if you are using return "redirect:/" + GameController.PAGE_NAME; to another controller then specified full url path of that controller. Right now you are redirecting to same controller not in another controller.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top