<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Supple software comments on Easy way of handling dates in a Struts form</title>
    <link>http://supplesoftware.com/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Supple software comments</description>
    <item>
      <title>"Easy way of handling dates in a Struts form" by petrovg</title>
      <description>&lt;p&gt;It&amp;#8217;s bit unfashionable to write about Struts now, what with all the JSF, Tapestry, etc frameworks, but most projects I&amp;#8217;ve seen still use Struts, and I often end up having to re-invent how to deal with the dates and other non-standard fields in the forms. So this time I&amp;#8217;ll write it down. Especially as this time it seems relatively neat and simple.&lt;/p&gt;

&lt;p&gt;So here&amp;#8217;s how you do it:&lt;/p&gt;

&lt;h5&gt;The form bean&lt;/h5&gt;

&lt;p&gt;Say we&amp;#8217;ve got the following date fields:
&lt;code&gt;&lt;pre&gt;
  private Date dob;
  private Date memorableDate;&lt;/p&gt;

&lt;p&gt;public Date getDob() {  return dob;  }
  public void setDob(Date dob) {&lt;br/&gt;
this.dob = dob ;  }
  ...
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Struts can&amp;#8217;t populate these fields. One option is to keep your dates as String, but have a go and you&amp;#8217;ll see why that&amp;#8217;s awkward.&lt;/p&gt;

&lt;p&gt;So what we do is &lt;/p&gt;

&lt;p&gt;add these getters and setters for the dates:
&lt;code&gt;&lt;pre&gt;
  public String getDobString() {
    return dateToString(dob);
  }&lt;/p&gt;

&lt;p&gt;public void setDobString(String dobString) {
    this.dob = stringToDate(dobString);
  }
  ...
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The two conversion methods are up to the application&amp;#8217;s requirements, but a simple implementation would be:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;pre&gt;
  private SimpleDateFormat simpleDateFormat = 
      new SimpleDateFormat("dd/MM/yyyy");&lt;/p&gt;

&lt;p&gt;Date stringToDate(String string) throws ParseException {
    return simpleDateFormat.parse(string);
  }&lt;/p&gt;

&lt;p&gt;String dateToString(Date date) {
    return simpleDateFormat.format(date);
  }
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that SimpleDateFormat is a fairly heavy object and not thread-safe. Luckily the form can not be shared anyway, so at least the thread safety is not an issue, unless someone decides to make it static in a feat of efficiency. So, yeah, don&amp;#8217;t make it static.&lt;/p&gt;

&lt;p&gt;Now, let&amp;#8217;s go back to the setter and handle the ParseException. If one occurs, we will keep the name of the field that caused it in a List.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;pre&gt;
  List unparseableFields = new ArrayList(1);&lt;/p&gt;

&lt;p&gt;public void setDobString(String dob) {
    try {
      this.dob = stringToDate(dob);
    } catch (ParseException e) {
      this.unparseableFields.add("dob");
    }
  }
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note - the list must be re-instatiated in the reset() method, because Struts may reuse the forms.&lt;/p&gt;

&lt;p&gt;This means, that after the initial setting of fields by the framework, we&amp;#8217;ll have no flying exceptions, but a list of the unparseable fields. This means we can use that in the validate() method (the next thing to execute) like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;pre&gt;
  public validate(...) {
    ....
    Iterator unparseableFieldsIterator = 
        this.unparseableFields.iterator();
    while (unparseableFieldsIterator.hasNext()) {
      String brokenFieldName = 
         (String) unparseableFieldsIterator.next();
      errors.add(new ActionError(fieldName, "date.parse.error");
    }
    ...
  }
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means that for each field that failed to parse, an error will be created and that error will be attached to the same field.&lt;/p&gt;

&lt;h5&gt;The view&lt;/h5&gt;

&lt;p&gt;In the view (JSP) we use the dobString property, instead of the dob. This, obviously is still stored in the dob Date field, which means it can be accessible as a normal date from the Action others. Here&amp;#8217;s a snippet of the JSP:&lt;/p&gt;

&lt;pre&gt;
  ...
  &amp;lt;errors property="dobString" /&amp;gt;
  &amp;lt;label for="dob"&amp;gt;Date of birth&amp;lt;/label&amp;gt;
  &amp;lt;html:text property="dobString" styleId="dob"/&amp;gt;
  ...
&lt;/pre&gt;

&lt;p&gt;The errors tag achieves the display of the error associated with this field just before it.&lt;/p&gt;

&lt;h5&gt;Further possibilities&lt;/h5&gt;

&lt;p&gt;What I have been doing recently is using one longer field where the user can enter comma-separated values when I need to receive a list. In the form I have the List object and get/setListString methods. In the view I use the listString &amp;#8220;dummy&amp;#8221; property and instruct the user to separate the entries with commas. Then in the form, following the same pattern, I parse the string using the StringTokenizer and throw a ParseException if there&amp;#8217;s an error.&lt;/p&gt;</description>
      <pubDate>Thu,  2 Feb 2006 10:43:00 PST</pubDate>
      <guid>&lt;a href="/articles/2006/02/02/easy-way-to-handle-dates-in-a-struts-form"&gt;Easy way of handling dates in a Struts form&lt;/a&gt;</guid>
      <link>&lt;a href="/articles/2006/02/02/easy-way-to-handle-dates-in-a-struts-form"&gt;Easy way of handling dates in a Struts form&lt;/a&gt;</link>
    </item>
  </channel>
</rss>
