Using Forms in Induction
This tutorial discusses the HTML form processing module in Induction. In Induction the parsed HTML form data becomes available by simply declaring a parameter of type com.acciente.induction.controller.Form in a controller handler method. An example is shown below:
package demoapp.forms_app;
import com.acciente.induction.controller.Controller;
import com.acciente.induction.controller.Form;
import com.acciente.induction.controller.Response;
/**
* HelloUser
*/
public class HelloUser implements Controller
{
public void handler( Form oForm, Response oResponse ) throws Exception
{
String sUserName = oForm.getString( "userName" );
oResponse.out().println( "Hello " + sUserName + "!" );
}
}
The Form object provides access to all the form data submitted with the HTTP request. If a given request contains form variables submitted via both the GET and POST methods, the Form object transparently combines the form variables from both GET and POST sources. If the request contained the identical form variable names (case matters) in the GET and POST sources, the value of the variable submitted via POST takes precedence.
The Form object also provides transparent access to any POST data submitted encoded using multipart/form-data protocol. Access to any uploaded file objects in the request is available via the getFile method of the Form object.
Data type specifications for form variables
Induction supports specifying data types on the client side (such as in an HTML form, or in a URL containing a query string) for form parameters. The type specifications have automatic defaults and are therefore completely optional. A type is specified as part of the form parameter name as in int:quantity.
The set of types supported are: string (the default type for any non-file data), int, float, boolean and file (the default type for a variable that Induction detects to be an uploaded file).
The Form class has methods to access a form variable based on its type. The most commonly used methods are the getString and getFile methods of the Form class. If a parameter is declared, for example, as int then the getInteger method of the Form class must be used, otherwise an exception will be thrown.
An advantage of using these client-side type specifications is the ability to declare the intended usage of a form variable early, also it prevents having to deal with type conversions in a controller.
Finally, the use of type specifications is completely optional and up to the individual developer.
Array and Map data structure specifications for form variables
A powerful feature of Induction is the support for array and map data structure in HTML forms. To denote that a variable is part of an array the variable name in the HTML form is simply followed by [], as in todo_item[]. With an array structure more than one instance of the variable is not just legal but expected. For example a form may have list of 5 items all named todo_item[]. When such a form is parsed Induction creates a variable name todo_item which contains a java.util.List with an element for each form value.
Induction supports map structure using a similar syntax, to denote a map structure a variable name in the HTML form is followed by [key_name], for example todo_item[week_1].
Lazy evaluation
Merely declaring a Form parameter in a controller does not cause Induction to parse the form data immediately. Induction delays parsing the form data in the request until an attempt is made to read a form variable using the Form object.
This allows a controller with special needs to easily access the underlying raw form data before Induction attempts to parse it. Furthermore, it allows a developer freedom to conditionally decide in a controller handler method if it wants to access the form data via the injected Form object or via direct access to the parameter stream provided by the Servlet API.