I'm using Spring for form input and validation. The form controller's command contains the model that's being edited. Some of the model's attributes are a custom type. For example, Person's social security number is a custom SSN type.
public class Person {
public String getName() {...}
public void setName(String name) {...}
public SSN getSocialSecurtyNumber() {...}
public void setSocialSecurtyNumber(SSN ssn) {...}
}
and wrapping Person in a Spring form edit command:
public class EditPersonCommand {
public Person getPerson() {...}
public void setPerson(Person person) {...}
}
Since Spring doesn't know how to convert text to a SSN, I register a customer editor with the form controller's binder:
public class EditPersonController extends SimpleFormController {
protected void initBinder(HttpServletRequest req, ServletRequestDataBinder binder) {
super.initBinder(req, binder);
binder.registerCustomEditor(SSN.class, "person.ssn", new SsnEditor());
}
}
and SsnEditor is just a custom java.beans.PropertyEditor
that can convert text to a SSN object:
public class SsnEditor extends PropertyEditorSupport {
public String getAsText() {...} // converts SSN to text
public void setAsText(String str) {
// converts text to SSN
// throws IllegalArgumentException for invalid text
}
}
If setAsText
encounters text that is invalid and can't be converted to a SSN, then it throws IllegalArgumentException
(per PropertyEditor
setAsText
's specification). The issue I'm having is that the text to object conversion (via PropertyEditor.setAsText()
) takes place before my Spring validator is called. When setAsText
throws IllegalArgumentException
, Spring simply displays the generic error message defined in errors.properties
. What I want is a specific error message that depends on the exact reason why the entered SSN is invalid. PropertyEditor.setAsText()
would determine the reason. I've tried embedded the error reason text in IllegalArgumentException
's text, but Spring just treats it as a generic error.
Is there a solution to this? To repeat, what I want is the specific error message generated by the PropertyEditor
to surface to the error message on the Spring form. The only alternative I can think of is to store the SSN as text in the command and perform validation in the validator. The text to SSN object conversion would take place in the form's onSubmit
. This is less desirable as my form (and model) has many properties and I don't want to have to create and maintain a command that has each and every model attribute as a text field.
The above is just an example, my actual code isn't Person/SSN, so there's no need to reply with "why not store SSN as text..."