Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Struts, валидация формы, сохранение данных модели


Автор: Alexis 14.12.2006, 12:18
Объясню суть проблемы на небольшом примере.
Пусть у меня есть форма добавления новой категории. Для категории мы должны выбрать родительскую категорию, соответственно в подготовительном Action мы должны получить список категорий и куда-то его засунуть. Я делаю примерно так?
Код

public ActionForward execute(ActionMapping mapping,
            ActionForm form, 
            HttpServletRequest request, 
            HttpServletResponse response) {
        CategoriesManager cm = new CategoriesManager();
        List categories = cm.getDendriformNameCategoriesList();
        request.setAttribute("categories", categories);
        
        return mapping.findForward("success");
}

Соответственно на странице:
Код

Parent category:
<html:select property="parentCategory">
  <html:option value="0">Top level</html:option>
    <logic:iterate name="categories" id="category">
      <html:option value="<%=String.valueOf(((com.eshop.bo.Category)category).getId())%>">
      <bean:write name="category" property="name"/>
    </html:option>
  </logic:iterate>                     
</html:select>

И все было хорошо, пока я не решил сделать валидатор для формы, вдруг имя категории не введут или введут недопустимое. В итоге получается, что при неверном вводе пользователь возвращается на форму создания категории, но request ведь уже другой, а Action второй раз не вызывается, соответственно и никаких categories тоже уже не существует. 
В связи с этим вопрос: куда же все-таки нужно засовывать данные Action'а, чтобы они не "потерялись"? Вроде бы в request им самое место, но ненадежное выходит хранилище  smile 

Решил проконсультироваться с опытными людьми. Мне сказали, что нужно делать кэш, который сам по себе и никак не связан со Struts. А сервер приложений будет при каждом запросе подкачивать в этот кэш данные. Может быть подскажите хотя бы ключевые слова, чтобы погуглить на эту тему.

Автор: tux 14.12.2006, 12:32
А в сессию почему в таком разе не положить? 
Код

request.getSession().setAttribute("categories", categories);

Автор: Alexis 14.12.2006, 12:45
Цитата(tux @  14.12.2006,  12:32 Найти цитируемый пост)
А в сессию почему в таком разе не положить? 

Собственно говоря на данный момент так и сделано. Я просто подумал, что захламлять сессию кучей данных -- не самое хорошое решение, вроде как request для этого придуман.
Хотя если так принято делать, то и я так сделаю. Спасибо за ответ!

Автор: Greg 14.12.2006, 13:36
Цитата(Alexis @ 14.12.2006,  12:45)
Я просто подумал, что захламлять сессию кучей данных -- не самое хорошое решение, вроде как request для этого придуман.

А почему в таком случае Вы считаете,что request можно захламлять ? Вижу у Вас сложились определённые предпочтения smile Позвольте предположить,суть вопроса заключается в рациональном использовании системных ресуросов или же самой модели приложения ?
Насчет первого к сожалению ничего не могу сказать,а вот на счёт второго однозначно - используйте session.

Автор: Alexis 14.12.2006, 19:48
Цитата(Greg @  14.12.2006,  13:36 Найти цитируемый пост)
А почему в таком случае Вы считаете,что request можно захламлять ?

Просто ведь request хранится только между запросами, а не на протяжении всей сессии. Мало ли чего еще я в сессию напихаю.
Цитата(Greg @  14.12.2006,  13:36 Найти цитируемый пост)
Позвольте предположить,суть вопроса заключается в рациональном использовании системных ресуросов или же самой модели приложения ?

Скорее я хотел узнать о более "правильном" с точки зрения верной структуры приложения подходе, т. е. о втором.
Цитата(Greg @  14.12.2006,  13:36 Найти цитируемый пост)
Насчет первого к сожалению ничего не могу сказать,а вот на счёт второго однозначно - используйте session. 

Так и сделаю.

Автор: Alexis 20.1.2007, 17:44
Цитата(Alexis @  14.12.2006,  12:18 Найти цитируемый пост)
В итоге получается, что при неверном вводе пользователь возвращается на форму создания категории, но request ведь уже другой, а Action второй раз не вызывается, соответственно и никаких categories тоже уже не существует. 

Переводил проект на Tiles, и стало мне интересно нужно ли менять свойства Action'а input, которое описывается в struts-config.xml. Наконец-то почитал документацию  smile  , оказалось, что если при валидации формы возвращается ошибка, то пользователю в браузер не каким-то магическим образом выкидывается форма, а ее адрес берется из свойства input, соответственно, если туда подставить адрес экшена, то экшен и вызовется и опять положит в request все что необходимо.
Код

<action path="/admin/prepareAddCategory"
             type="com.eshop.actions.admin.PrepareAddCategory">
    <forward name="success" path=".admin.category.add"/>
</action>
<action path="/admin/processAddCategory"
        type="com.eshop.actions.admin.ProcessAddCategory"
        name="addCategoryForm"
        scope="request"
        input="/admin/prepareAddCategory.do"
        cancellable="true"
        validate="true">
    <forward name="success" path="/admin/categories.do"/>
</action>

Только встала другая проблема. Если экшен, которые подготавливал форму получает какие-то параметры через URL, то при возникновении ошибки при валидации и повторном его вызове ничего ему не передадут. Но я эту проблему решил, может быть и не очень красиво, но работает. При запуске экшен сначала проверяет его наличие в запросе, если находит, то сохраняет еще и в сессию. Если в запросе параметр не найден, то ищем его в сессии, куда его положили при последнем вызове.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)