I fell into this trap by taking a template-generated Grails view and trying to modify it for a different use. I had a simple form:
<g:form method="post" controller="partnersUser" action="show">
<input type="text" id="user" name="user"/>
<g:actionSubmit class="save" value="Search" />
As you can see in the g:form tag, this form is supposed to submit to the ‘show’ action in a controller named PartnersUserController.
Oddly, on submit, I was getting sent to a 404 error generated from Tomcat – I wasn’t even seeing a Grails error message, and no exceptions were being logged. And by experimenting, I found that I could get to the ‘show’ action by simply typing in the URL in my browser (GET instead of POST), and that if I appended the ‘user’ parameter, the action worked.
My thanks to Jakub Zygmunt for pointing out that if you use the g:actionSubmit tag (which was already in the template-created form, and I kept), you must specify an action attribute. Even if you’ve already specified an action in the g:form tag, apparently.
<g:actionSubmit class="save" value="Search" action="show" />
The reference documentation for the actionSubmit tag states:
Creates a submit button that maps to a specific action, which allows you to have multiple submit buttons in a single form.
In fact, it’s got a convention. The actionSubmit will supply the value attribute as the name of the action unless it is overridden by explicity assigning an action attribute.
The bottom line is that the actionSubmit tag does a lot more than a simple submit button, and if you use it, you should know what it’s for.
I’ll keep that in mind!