> Docs > Http Server > Form Handling

Form Handling

The data of a form submission can be modeled by FormData. An server app can parse the request to get the FormData then read the field values.

Html Builder

Here are some examples to construct html forms in Html Builder

_form().action("/query").add(
    "Term: ", _input().name("term"), _br(),
    _button("query")
)

_form().method("POST").action("/post").enctype(FormData.ENC_MULTIPART).add(
    CsrfToken._input(),  // hidden input for csrf token
    _input().name("s1"), _br(),
    _input().name("f1").type("file"), _br(),
    _button("upload")
)

GET

If the form submission is a GET request, all form data are in the request URI.

For simple cases, you can use request.uriParam(name).

String term = request.uriParam("term");

To get the full form data, use FormData.parse(uri).

FormData fd = FormData.parse( request.uri() );
String term = fd.param("term");
...

POST

If the form submission is a POST request, the form data are in the request body. Use FormData.parse(request)

if("POST".equals(request.method()))
{
    Async<FormData> afd = FormData.parse(request); // async!
    return afd.then( fd->
    {
        String s1 = fd.param("s1");
        FormDataFile f1 = fd.file("f1");
        //fd.deleteFiles();
        return HttpResponse.text(200, s1, "\n", f1.toString());
    });
}

Note that the URI of a POST request could also be treated as (separate) form data, use parse(uri) for that purpose; parse(request) is for the request body only.

Parser Configuration

The FormData.parse(uri) and FormData.parse(request) methods use the default parser configuration. You can create a FormParser with custom configuration instead

static final FormParser parser = new FormParser()
    .charset(StandardCharsets.US_ASCII)
    .maxFileEntries(3)
    ;

// usage

    FormData fd = parser.parse( request.uri() );

    Async<FormData> afd = parser.parse(request);

CSRF Detection

FormParser detects CSRF by default, using a set of heuristics.

The server app should parse every POST request with parse(request) before honoring the request, for the purpose of CSRF detection, even if there's nothing in the form data that the app needs to read.

If a form contains no CSRF token, CSRF detection still works most of the time because of Referrer/Origin headers. However, to be safe, the server app should add CsrfToken to all POST forms to prevent false detection of CSRF.

_form().method("POST").action("/addArticle").add(
    ...
    CsrfToken._input()
    ...

To ensure that all POST forms contain CSRF tokens, define a convenient builder method:

Html5.FORM _form_post()
{
    return Html5.html5._form()
        .method("POST")
        .enctype(FormData.ENC_MULTIPART)
        .add( CsrfToken._input() );
}

// usage example

    _form_post().action("/logout").add( _button("Log Out") );

// logout handler

    if(!"POST".equals(request.method()))
        return HttpResponse.text(400, "Bad Request");

    return FormData
        .parse(request)
        .then( fd->
        {
            doLogout();
            return HttpResponse.redirect("/afterLogout");
        })
        .catch_(CsrfException.class, e->
        {
            // silently ignore the request
            return HttpResponse.redirect("/");
        });