Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Some wordsmithing and a little more about serialization

...

Storing Data Between Requests

Wiki Markup
{float:right|background=#eee|width=40%}
{since:info:title=New in Tapestry 5.4}
Note: Starting in Tapestry 5.4, the default behavior for server-side validation failures is to re-render the page within the same request (rather than emitting a redirect). This removes the need to use a session-persistent field to store the validation tracker when validation failures occur.
{sinceinfo}
{float}

As with other action requests, the result of a form submission is to send a redirect to the client, which results in a second request (to re-renders render the page). The ValidationTracker must be stored persistently between requests, or all the validation information will be lost ( persisted (generally in the HttpSession) across these two requests in order to prevent the loss of validation information. Fortunately, the default ValidationTracker provided by the Form component is persistent)., so you don't normally have to worry about it.

However, for the same reasonLikewise, the individual fields updated by the components should also be persistentpersisted across requests, and this is something you do need to do yourself – generally with the @Persist annotation.

For example, a Login page, which collects a user name and a password, might look like:

Code Block
java
java
public class Login
{
    @Persist
    private String userName;

    private String password;

    @Inject
    private UserAuthenticator authenticator;

    @Component(id = "password")
    private PasswordField passwordField;

    @Component
    private Form form;

    String onSuccess()
    {
        if (!authenticator.isValid(userName, password))
        {
            form.recordError(passwordField, "Invalid user name or password.");
            return null;
        }

        return "PostLogin";
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        password = password;
    }

    public String getUserName()
    {
        return userName;
    }

    public void setUserName(String userName)
    {
        userName = userName;
    }
}
Wiki Markup
{float:right|width=40%}
{info}
Note that the onSuccess() method is not public; event handler methods can have any visibility, even private. Package private (that is, no modifier) is the typical use, as it allows the component to be tested, from a test case class in the same package.
{info}
{float}

Because a form submission is really two requests: the submission itself (which results in a redirect response), then a second request for the page (which results in a re-rendering Because of the the fact that a form submission is two requests (the submission itself, then a re-render of the page), it is necessary to make the value stored in persist the userName field persist between the two requests, by using the @Persist annotation. This would be necessary for the password field as well, except that the PasswordField component never renders a value.Note that the onSuccess() method is not public; event handler methods can have any visibility, even private. Package private (that is, no modifier) is the typical use, as it allows the component to be tested, from a test case class in the same package

Tip

To avoid data loss, fields whose values are stored in the HttpSession (such as userName, above) must be serializable, particularly if you want to be able to cluster your application or preserve sessions across server restarts.

The Form only emits a "success" event if the there are no prior validation errors. This means it is not necessary to write if (form.getHasErrors()) return; as the first line of the method.

...

Validator

Constraint Type

Description

Example

email

Ensures that the given input is a valid e-mail address

<t:textfield value="email" validate="email" />

max

long

Enforces a maximum integer value

<t:textfield value="age" validate="max=120,min=0" />

maxLength

int

Makes sure that a string value has a maximum length

<t:textfield value="zip" validate="maxlength=7" />

min

long

Enforces a minimum integer value

<t:textfield value="age" validate="max=120,min=0" />

minLength

int

Makes sure that a string value has a minimum length

<t:textfield value="somefield" validate="minlength=1" />

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="c84f272ddaa480a7-4b4b1ebc-47f644dc-827fa1cf-8ee8277344c23c89c1e0c978"><ac:plain-text-body><![CDATA[

regexp

pattern

Makes sure that a string value conforms to a given pattern

<t:textfield value="letterfield" validate="regexp=^[A-Za-z]+$" />

]]></ac:plain-text-body></ac:structured-macro>

required

Makes sure that a string value is not null and not the empty string

<t:textfield value="name" validate="required" />

...