Прежде чем я отвечу на ваш вопрос, позвольте мне сказать следующее: Люди не понимают, что такое ActionForm или что делает ActionForm
ActionForm представляет данные, которые пользователь заполнил в форме HTML. Struts считывает параметры запроса и сопоставляет их по имени с настроенной ActionForm для целевого действия отправки. Это данные, введенные пользователем, простые и понятные.
Данные, поступающие по запросу, всегда имеют тип java.lang.String . Но у людей может быть поле формы с именем age, которое является int в данных модели. Или, может быть, вместо «age» у них есть «birthDate», которое, конечно же, является java.util.Date в их данных модели. Поэтому они считают, что было бы неплохо поместить типы int и Date в ActionForm и позволить Struts преобразовывать строки, поступающие по запросу, в целые числа и даты.
Это очень полезное преобразование, и вы, как разработчик, не должны справляться с этим, Struts делает. Это немного магии фреймворка.
Но это не волнует Гарри Поттера! Преобразование может завершиться неудачно для целых и дат . Почему?
int - это примитивный тип, поэтому он всегда должен иметь значение. Инициализация по умолчанию с нуля. При выполнении привязки (параметры запроса к свойствам объекта ActionForm) Struts видит тип int в ActionForm и пытается преобразовать значение String запроса в int.
Если пользователь вставил строку «5», поле будет установлено в 5. Отлично!
Но что, если пользователь вставил "бла"? Получим ли мы исключение, брошенное нам в лицо? Нету! Мы возвращаем значение ноль, потому что преобразование (молча) не удалось. Ups!
Даты снова являются проблемой. Зачем? Потому что их значение поступает по запросу в виде строки. Их формат может быть таким простым, как «12/01/2011», который совершенно бесполезен в качестве информации. Зачем? Поскольку даты, представленные в виде строк, должны идти рука об руку с Locale , чтобы преобразовать их в правильный экземпляр Date, который он представляет.
"12/01/2011" + Locale.US = 01 December 2011
"12/01/2011" + Locale.FRENCH = 12 January 2011
Ups!
Хорошо, это было вступление! Теперь перейдем к вашему вопросу .
- Должен ли я создать переменную Date и создать метод setDate (String date), в котором будет происходить преобразование.
В какой-то момент вам придется отправить Date обратно в представление, а html-теги Struts обычно должны идти для getDate()
, который возвращает String. «12/01/2011», которое вы получаете при вводе пользователем, может отображаться как «12 января 2011 г. 00:00:00», если получатель возвращает дату (Struts сделает toString()
для значения получателя). Таким образом, вам действительно нужно поле Date, содержащее как метод установки / получения типа Date, так и метод установки / получения типа String. Используйте тип Date в вашем классе Action и используйте String для взаимодействия с тегами представления.
Вопрос? Как получить правильное значение Locale в ActionForm?
- Создать переменную Date, setDate (Date date) и зарегистрировать специальный конвертер где-нибудь в цепочке (не знаю, возможно ли это)
Возможно . Вы можете создать и зарегистрировать пользовательский конвертер, который может принимать строковые представления дат и преобразовывать их в дату. Если вы используете формат ISO 8601 , я думаю, вы будете в безопасности.
Вопрос? Можете ли вы приспособить это к существующему приложению, не нарушая код, который преобразует String в даты по-своему, используя всевозможные форматы или локали?
- Создайте переменную String, setDate (String date) и разрешите преобразование / валидацию для метода validate в компоненте actionForm
Это не сработает.Метод validate
вызывается после привязки параметров к объекту ActionForm.Когда вы достигнете этой точки уже поздно.Struts сделал преобразование.Если у вас есть поле типа int со значением ноль, то нет способа узнать, действительно ли пользователь вставил ноль и преобразование сработало или пользователь вставил «bla», и преобразование не удалось, и вы вернули ноль в качестве значения инициализации по умолчанию.Если ноль является действительным значением для вашего приложения, чем у вас есть еще большие проблемы.
Так что же такое соглашение?
Соглашения нет.Используйте приведенную выше информацию и руководствуйтесь здравым смыслом, учитывая вашу ситуацию.
В идеале все свойства в ActionForm должны быть в виде строк , чтобы не терять информацию во время привязки.Но это включает в себя ручное преобразование свойств в соответствующий тип в классе Action перед их использованием.У вас есть полный контроль (Struts больше не выполняет преобразования, поскольку исходные и конечные значения имеют тип String), но у вас также есть много кода кода, который нужно написать, чтобы сделать это надлежащим образом, что в какой-то момент может стать раздражающим.
PS Прежде чем я закончу это и пойду спать (в моей стране 01:00 утра): Я просто хочу упомянуть одну вещь, которую люди часто не видят. ActionForm не является частью модели , и при этом он не должен напрямую взаимодействовать с моделью.
Если вам необходимо обработать данные из ActionForm в модели, сопоставьте их какотношения один-к-одному с Model DTO (объект передачи данных).Если вы этого не сделаете, то создадите тесную связь между моделью и структурой Struts, потому что ваши объекты ActionForm не являются POJO.Ваш класс должен расширять класс ActionForm из Struts, о котором мы говорили.Люди не делают этого и отправляют ActionForm прямо в модель.Что еще хуже, они также используют метод validate
для выполнения бизнес-валидации вместо базовой валидации, такой как «требуется», «диапазон значений» и т. Д.
ActionForms - это просто канал связи междуДействие (контроллер) и вид.Относитесь к нему как к такому.