Formatting Reference

Stripes' philosophy when it comes to formatting is pretty simple:

  • Formatting should be easy (duh)
  • Formatting should occur on the page, not in the ActionBean or business code
  • Formatting should be localized
  • Formatting should be easy to extend

To that end, formatting is accomplished using a couple of additional attributes on the set of Stripes tags that have the ability to display data (i.e. form input tags such as text, textarea etc.). Stripes does not supply formatting capabilities outside of form fields - JSTL has a bunch of pretty good formatting tags, and there's no reason to duplicate any of the functionality.

Speaking of JSTL, if you are familiar with the JSTL formatting tags, the Stripes formatting system should feel quite familiar. That's done on purpose. Stripes uses the java.text.DateFormat and java.text.NumberFormat to do most of the actual formatting. The main difference is how you specify formatting parameters - JSTL has specific tags to do formatting of numbers and dates, whereas Stripes has the need to add formatting to a set of input tags.

Using Formatting

You might think that an appropriate first question is how do I use formatting? But you'd be wrong! The Stripes input tags engage the formatting system every time they write a value out to the page. They do this as follows:

  1. Determine the type of object being output (String, Date, Number, Other?)
  2. Ask the FormatterFactory for a Formatter instance that can format the relevant type
  3. If there is a Formatter invoke it to format the object, otherwise use String.valueOf()

Other than the object itself, formatting in Stripes is driven by two parameters (supplied as attributes on the Stripes input tags). The parameters are formatType and formatPattern. formatType is used to specify the type of information which should be output from the source object (e.g. for a java.util.Date object, should it be date, time or both). formatPattern can be either one of a set of named styles, or an explicit pattern as understood by the underlying java.text.Format object. This will all make a bit more sense in the context of the two concrete Formatters supplied with Stripes.

When one or both of formatType and formatPattern are not supplied, the Formatter being used must decide what to do. In the case of the NumberFormatter and DateFormatter included with Stripes they simply use the default java.text.NumberFormat and java.text.DateFormat for the Locale being used for the request.

Formatting Dates

Formatting of Date objects (java.util.Date and subclasses) is done using an instance of DateFormatter. It accepts the following values for formatType:

formatType

Description

date

Output only Date information, and no time information, e.g. Sep 3 2005. (Default)

time

Output only Time information, and no date information, e.g. 18:24.

datetime

Output both Date and Time information, e.g. Sep 3 2005, 18:24

The following named styles (in addition to custom patterns) may be supplied as the formatPattern:

formatPattern

Description

short

Output information in as compact a manner as possible form. Maps to DateFormat.SHORT

medium

Output information in a concise, slightly less compact form. Maps to DateFormat.MEDIUM

long

Output information in a fairly verbose form. Maps to DateFormat.LONG

full

Output information in an extremely verbose form. Maps to DateFormat.FULL

A few things to be aware of:

  • The output format using the named styles can vary according to locale
  • You may use any pattern understood by java.text.SimpleDateFormat in addition to the named styles enumerated above
  • If you specify a format pattern that includes date and/or time segments, this override the formatType parameter - your pattern will be used verbatim

Formatting Numbers

Formatting of Number objects (anything extending java.lang.Number or the primitive number types) is done using an instance of NumberFormatter. It accepts the following values for formatType

formatType

Description

number

Output the value as a regular number (Default)

currency

Output the value as a currency amount, using the symbols for the current locale

percentage

Output the value as a percentage (multiply by 100 and attach the % sign)

The following named styles (in addition to custom patterns) may be supplied as the formatPattern:

formatPattern

Description

plain

Output the value in a manner similar to that produced by Number.toString(). Includes no grouping characters, and will include a decimal separator and decimal digits only if they exist in the number supplied. (Default)

integer

Outputs the value with grouping characters appropriate for the current locale, without a decimal separator and any fractional values. Despite the name (or rather the co-option of integer, by programming languages, to mean something more specific) the integer formatPattern can be used with any numeric type. E.g. 123456789.12 in the en_us locale would be output as 123,456,789.

decimal

Outputs the value with grouping characters appropriate for the current locale, with a decimal fraction at least 2 digits long, and at most 6 digits long. E.g. 1234 in the en_us locale would be output as 1,234.00.

A few things to be aware of:

  • The output format using the named styles can vary according to locale
  • You may use any pattern understood by java.text.DecimalFormat in addition to the named styles enumerated above

Using formatting outside of tags

The only place that Stripes integrates formatting is in the tags. But this doesn't mean that it's the only place you can use it! If you find yourself wanting to format objects somewhere in your Java code, all you have to do is call StripesFilter.getConfiguration().getFormatterFactory() and you have full access to the formatting system.

Extending Formatting

To extend or modify the way formatting is performed will require an understanding of the formatting system. Luckily that's not hard to come by. Stripes uses a configured FormatterFactory to locate instances of the Formatter interface. It's probably worth spending a few minutes reading the javadoc for those interfaces.

Stripes supplies a DefaultFormatterFactory which knows how to supply the built in Date and Number formatters based on the inputs provided. In order to integrate a new formatter, or to substitute a different formatter for Date or Number types, you will have to provide your own implementation of FormatterFactory. This is easily done by subclassing DefaultFormatterFactory and overriding getFormatter() to perform any specific lookups and then delegating to super.getFormatter(). You are, of course, free to directly implement FormatterFactory, just bare in mind that if you do this you will need to handle the lookups for Date and Number types too.

Now all that's left is implementing your own Formatter class. This is a relatively simple operation. Remember that as your inputs you will receive an object to be formatted, a Locale, a formatType and a formatPattern. You may choose to use, or ignore as many of these parameters as you see fit. The following is an example of a custom Formatter for formatting social security numbers:

"SsnFormatter.java"
public class SsnFormatter implements Formatter<Ssn> { 
	private String formatType; 

	/** Sets the format type to be used to render Ssns as Strings. */ 
	public void setFormatType(String formatType) { 
		this.formatType = formatType; 
	} 

	public void setFormatPattern(String formatPattern) { 
		// SsnFormatter doesn't use format-pattern 
	} 

	public void setLocale(Locale locale) { 
		// Ssn's are US specific, so no locale support either 
	} 

	/** Sets defaults if a formatType was not supplied. */ 
	public void init() { 
		if (this.formatType == null) { 
			this.formatType = "lastfour"; 
		} 
	} 

	/** Formats the Ssn supplied as a String. */ 
	public String format(Ssn ssn) { 
		if ("lastfour".equals(this.formatType)) { 
			return "###-##-" + ssn.getLastFourDigits(); 
		} 
		else if ("allnine".equals(this.formatType)) { 
			return ssn.getDigits(0,3) + "-" + ssn.getDigits(3,5) + "-" + ssn.getLastFourDigits(); 
		} 
	} 
}