Я использую Spring для ввода и проверки формы. Команда контроллера формы содержит модель, которая редактируется. Некоторые атрибуты модели являются настраиваемым. Например, номер социального страхования человека является настраиваемым типом SSN.
public class Person {
public String getName() {...}
public void setName(String name) {...}
public SSN getSocialSecurtyNumber() {...}
public void setSocialSecurtyNumber(SSN ssn) {...}
}
и перенос лица в команду редактирования формы Spring:
public class EditPersonCommand {
public Person getPerson() {...}
public void setPerson(Person person) {...}
}
Так как Spring не знает, как преобразовать текст в SSN, я регистрирую редактор клиента с помощью связующего устройства формы:
public class EditPersonController extends SimpleFormController {
protected void initBinder(HttpServletRequest req, ServletRequestDataBinder binder) {
super.initBinder(req, binder);
binder.registerCustomEditor(SSN.class, "person.ssn", new SsnEditor());
}
}
и SsnEditor - это обычная java.beans.PropertyEditor
, которая может преобразовывать текст в объект SSN:
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
}
}
Если setAsText
обнаруживает недопустимый текст и не может быть преобразован в SSN, он выдает IllegalArgumentException
(за PropertyEditor
setAsText
спецификацию). Проблема, с которой я сталкиваюсь, заключается в том, что преобразование текста в объект (через PropertyEditor.setAsText()
) имеет место до, вызывающий мой Spring валидатор. Когда setAsText
throws IllegalArgumentException
, Spring просто отображает общее сообщение об ошибке, определенное в errors.properties
. То, что я хочу, является конкретным сообщением об ошибке, которое зависит от точной причины, по которой введенный SSN недействителен. PropertyEditor.setAsText()
будет определять причину. Я попытался встроить текст причины ошибки в текст IllegalArgumentException
, но Spring просто рассматривает его как общую ошибку.
Есть ли решение? Повторяю то, что я хочу, это конкретное сообщение об ошибке, сгенерированное PropertyEditor
для отображения сообщения об ошибке в форме Spring. Единственной альтернативой, о которой я могу думать, является сохранение SSN в виде текста в команде и выполнение проверки в валидаторе. Преобразование текста в объект SSN будет иметь вид onSubmit
. Это менее желательно, так как моя форма (и модель) имеет много свойств, и я не хочу создавать и поддерживать команду, которая имеет атрибут каждой модели как текстовое поле.
Вышеприведенный пример - мой фактический код не является Person/SSN, поэтому нет необходимости отвечать "почему бы не хранить SSN как текст..."