Forms and the HST ActionURL
Introduction
Bloomreach Experience Manager's delivery tier supports thePost-Redirect-Get pattern for form submissions. This pattern describes the following three phases:
- The form is submitted to an action URL using thePOST method.
- The form component'sdoAction method is invoked to process form data.
- The server responds to the form's POST request with a redirect to the form's original URL using theGET method.
The following sections explain in more detail how to use the pattern in your form components.
Form Submission
To use the PRG pattern a form must be submitted using thePOST method to a specialaction URL generated by using the hst:actionURL tag.
In a JSP template:
<hst:actionURL var="actionLink" /><form action="${actionLink}" method="post"> <!-- form fields here --></form>In a Freemarker template:
<@hst.actionURL var="actionLink"/><form action="${actionLink}" method="post"> <!-- form fields here --></form>The action URL is unique to the component that renders the form, ensuring that thePOST request will invoke thedoAction method of said component. An action url looks something like:
/news?_hn:type=action&_hn:ref=r34_r1_r1
The above implies anaction request to the pathInfo /news and then on the page that belongs to /news, invoke thedoAction method of the java class belonging to component with reference r34_r1_r1.
Method must be POST
A<form> using a generated action URL should always use thePOST method:
<form action="${actionLink}" method="post">In Bloomreach Experience Manager 14, an (incorrect) GET request for the generated action URL will still trigger thedoAction method, which in general is undesirable. As of Bloomreach Experience Manager 14.1.0, you can prevent this from happining by adding the following to your HST properties:
container.actionValve.method.post.only = true
This will cause anyGET request at an action URL to be rejected with HTTP status 405 "Method Not Allowed", which is the recommended behavior.
As of Bloomreach Experience Manager 15.0, rejectingGET requests at action URLs is the default behavior.
Data Processing
To process submitted form data, the component that renders the form must overrideBaseHstComponent#doAction(HstRequest request, HstResponse response).
Form data is stored in aorg.hippoecm.hst.component.support.forms.FormMap, which can also be used to access the data. Useful static methods are provided byorg.hippoecm.hst.component.support.forms.FormUtils.
To access form data, create a newFormMap object and provide a list of form field names to the constructor:
FormMap map = new FormMap(request, new String[]{"inputFieldName"});AFormMap containsFormField objects which in turn contain the field values. Validation error messages can be added to aFormMap and itsFormField objects.
To persist the form data (including any messages that were added) so they are still available to the component after the redirect, useFormUtils#persistFormMap(HstRequest, HstResponse, FormMap, StoreFormResult):
FormUtils.persistFormMap(request, response, map, null);
Form data should only be persisted indoAction.
OncedoAction is completed the request will be redirected to the original URL of the page containing the form, and the form component'sdoBeforeRender method will be invoked as for any normalGET request.
Rendering
To retrieve persisted form data in a form component's doBeforeRender method, a FormMap object can be populated using the static method FormUtils#populate(HstRequest, FormMap):
FormMap map = new FormMap();FormUtils.populate(request, map);
The form data (including any messages) can then be passed to the templating engine to, for example, render error messages, prepopulate the form, list all submitted values for confirmation, and so on.
Sealing Form Data
Once the form data are no longer needed, they should be 'sealed' so they cannot be read anymore:
map.setSealed(true);
Form Data Storage
Form data is stored in the content repository in the folder/formdata. Different customers have different needs for the retention of this data, so this data is not cleaned up automatically. EachFormData element stores a timestamp, so this data can be cleaned up using the providedForm Data Cleanup Repository Job.