Struts 1 ActionForms - Какое соглашение для дат в форме? - PullRequest
8 голосов
/ 15 июля 2011

Я собираюсь начать с электронного проекта, который использует Struts 1.2. Не планируется переходить на другие рамки.

Я хотел знать, что такое соглашение при обработке даты в форме?

  1. Должен ли я создать переменную Date и создать метод setDate(String date), в котором будет происходить преобразование?

  2. Создать переменную Date, setDate(Date date) и зарегистрировать специальный конвертер где-нибудь в цепочке? (не знаю, возможно ли это)

  3. Создать строковую переменную a setDate(String date) и разрешить преобразование / проверку для метода validate в компоненте ActionForm?

Или другой подход?

Кроме того, если у вас есть какие-либо советы по ускорению работы с этим фреймворком, я был бы очень признателен.

1 Ответ

16 голосов
/ 16 июля 2011

Прежде чем я отвечу на ваш вопрос, позвольте мне сказать следующее: Люди не понимают, что такое 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!

Хорошо, это было вступление! Теперь перейдем к вашему вопросу .

  1. Должен ли я создать переменную 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?

  1. Создать переменную Date, setDate (Date date) и зарегистрировать специальный конвертер где-нибудь в цепочке (не знаю, возможно ли это)

Возможно . Вы можете создать и зарегистрировать пользовательский конвертер, который может принимать строковые представления дат и преобразовывать их в дату. Если вы используете формат ISO 8601 , я думаю, вы будете в безопасности.

Вопрос? Можете ли вы приспособить это к существующему приложению, не нарушая код, который преобразует String в даты по-своему, используя всевозможные форматы или локали?

  1. Создайте переменную 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 - это просто канал связи междуДействие (контроллер) и вид.Относитесь к нему как к такому.

...