Tuesday, June 9, 2009

User-friendly binding error messages in Spring MVC

In some cases, Spring's binding error messages are not fit to display to the user. How can we get around this? If we override SimpleFormController.onBindAndValidate() in our controller, in the hopes of modifying the BindException parameter accordingly, we'll be hard-pressed to find methods allowing us to do so.

One way to display user-friendly binding error messages is to override SimpleFormController.onBindAndValidate() as follows:

@Override
protected void onBindAndValidate(HttpServletRequest request, Object command,
BindException errors) throws Exception {
if (errors.hasErrors()) {
Map errorsMap = new HashMap();
List errorList = errors.getAllErrors();
for (FieldError error : errorList) {
String msg = "";
try {
msg = this.translate(error.getCode(), error.getArguments());
} catch (Exception e) {}
if (msg.contains("quantity")) {
msg = msg.replace(error.getField(), "quantity");
} else if (msg.contains("unitPrice")) {
msg = msg.replace(error.getField(), "unit price");
}
msg += ".";
errorsMap.put(error.getField(), msg);
}
request.setAttribute("errorsMap", errorsMap);
}
}
This creates a map of user-friendly error messages, keyed by the field names with which the error messages are associated. You can then use it in your JSP, possibly with the tag.

Monday, April 20, 2009

Tip: Velocity

If you are using the #if #else #end construct provided by Velocity, remember to put a space after the #else. If you don't, Velocity will ignore the #else and consider the statement to be a simple #if #end.

Thursday, April 16, 2009

Use BigDecimal for financial calculations

It is common to use the Double object or the double primitive type for financial calculations. Since you have no control over rounding behavior, mistakes may arise in your calculations. You might charge customers more (or less) than they owe. Use BigDecimal to solve this problem. For a clear, thorough explanation, see this document.

Monday, April 6, 2009

Tip: Tomcat startup exception

If, while starting up Tomcat, you get this error - SEVERE: Exception loading sessions from persistent storage - try to delete the SESSIONS.ser from your $CATALINA_HOME/work directory.

Friday, March 20, 2009

Iterating over maps in JSTL

For a simple and clear explanation of how to iterate over maps in JSTL, see this thread and scroll down to hoffmandirt's answer from May 13th, 2008.

Wednesday, February 11, 2009

JSTL's expression language and refactoring

Suppose you've got an object of class Person with a getName() method. JSTL's expression language allows you to access this field in your JSP with the following notation - ${person.name} - assuming you've passed the JSP a person variable pointing to an instance of Person. For example, you might use: .

This is a convenient feature, but it has a downside: Suppose your application grows and you now support first and last names. Person.getName() used to return a first name, but now you wish to change the method name to getFirstName(). This is a simple refactoring to do using a modern IDE - the IDE will find every mention of getName() in your code, and change it to getFirstName(). That's not enough, however. Remember to also search through your JSP's for references to this method and change them too.

Monday, October 27, 2008

Installing JMagick 6.3.9 on Windows XP

Here are the steps:

1. Go to http://downloads.jmagick.org/6.3.9/.
2. Download ImageMagick-6.3.9-0-Q16-windows-dll.exe and install. The PATH environment variable should be updated with the install directory.
3. Download jmagick-win-6.3.9-Q16.zip and unzip. The directory contains jmagick.jar and jmagick.dll. You may move both files subject to #4 and #5.
4. Make sure jmagick.jar is in the Java classpath.
5. Make sure your VM arguments (e.g. in Eclipse or from the command line) contain a pointer to the directory containing jmagick.dll. E.g. -Djava.library.path=C:/dcs/tools/jmagick-win-6.3.9-Q16.