Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопросы по Spring MVC, жду советов и предложений. 
:(
    Опции темы
garbuz
Дата 28.5.2009, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Мучаю дальше SimpleFormController (если разберусь, то можно и статейку в faq набросать smile )
Сейчас стоит задача забиндить коллекцию в объект. Нашел в инете примерчик
Цитата

This method allows you to register custom editors for certain fields of your command class. For instance, you will be able to transform Date objects into a String pattern and back, in order to allow your JavaBeans to have Date properties and still be able to set and display them in an HTML interface. 


Код

 @Override
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        binder.registerCustomEditor(Set.class, "categories", new CustomCollectionEditor(Set.class){
            protected Object convertElement(Object element){
                if (element != null){
                    Long categoryId = Long.parseLong(element.toString());
                    Category category = daoFacade.getCategoryDAO().getById(categoryId);
                    return category;                   
                }
                return null;
            }
        });
    }

Правда не совсем понятно, как это все работает. 
Итак, как происходит процесс у меня, судя по дебаггеру.
1) Вызывается formBackingObject(). Кстати, что за свойство sessionForm(true/false). Я чего-то так и не понял, за что отвечает? Поставил значение true и после сабмита метод formBackingObject() больше не стал вызываться, то что я и хотел.
2) Вызов initBinder, где сначала происходит только регистрация customEditor, как я понял
3) Список категорий получаю в методе referenceData()
4) Снова initBinder, но в этом методе уже происходит вызов метода converElement, в качестве объекта element приходит id категории, т.е. просто число. Вот тут непонятно? Откуда он взялся? Из тех данных что поулчены в referenceData? Или откуда еще? Причем приходит не один id, а итерируюстя id всей коллекции категории, да. То что нужно. Но если у меня всего 4 категории, то вызов converElement происходит 8 раз, по два раза для id каждой категории. Почему?
5) Отображается форма.
6) Заполняю, сабмичу.
7) Снова вызов initBinder, в качестве element приходит "" (об этом позже)
8) Появляется ексепшн
9) Вызов processFormSubmission()
10) Снова вызов referenceData
11)  Снова вызов initBinder как в пункте 4
12) И так по кругу....

Короче вот такая ерунда. Непонятно зачем метод initBinder вызывается столько раз? Мне кажется, что он должен вызываться один раз после сабмита, получать значение из формы и вытаскивать объект по этому значению. Короче каша в голове. Кто объяснит, буду признателен.

и еще один момент на счет jsp
Код

<form:select path="categories" multiple="multiple">
     <form:options items="${categories}" itemValue="categoryId" itemLabel="categoryName"/>
</form:select>

catefories - это коллекция, которую получаю в referenceData.
HTML на странице выглядит так 
Код

<td>Choose categories</td>

            <td>
                <select id="categories" name="categories" multiple="multiple">
                    
                        <option value="">Ajax</option>
                    
                        <option value="">Java</option>
                    
                        <option value="">Linux</option>
                    
                        <option value="">Новости</option>
                    
                    
                </select><input type="hidden" name="_categories" value="1"/>

            </td>


Значение атрибута value пустые, поэтому и в initBinder после сабмита приходит пустая строка. Почему пустые, пример select и options взял с офф референса. 

Буду рад любой помощи smile
PM MAIL   Вверх
Kangaroo
Дата 29.5.2009, 01:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


AA - Aussie Animal
****


Профиль
Группа: Участник Клуба
Сообщений: 2042
Регистрация: 7.10.2006
Где: US

Репутация: 14
Всего: 104



Ого, сколько проблем  smile  Сегодня не успеваю, завтра утром постараюсь помочь.


--------------------
Lost....
PM MAIL MSN   Вверх
garbuz
Дата 29.5.2009, 02:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(Kangaroo @  29.5.2009,  01:37 Найти цитируемый пост)
го, сколько проблем  smile  Сегодня не успеваю, завтра утром постараюсь помочь. 

Жду! А то мне даже не уснуть smile
PM MAIL   Вверх
Kangaroo
Дата 29.5.2009, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


AA - Aussie Animal
****


Профиль
Группа: Участник Клуба
Сообщений: 2042
Регистрация: 7.10.2006
Где: US

Репутация: 14
Всего: 104



Цитата(garbuz @  27.5.2009,  15:22 Найти цитируемый пост)
Зачем еще раз вызов метода formBackingObject(), зачем нам второй объект?

Это связано с параметром sessionForm.
Зачем этот флаг нужен: если он установлен, то комманд обжект хранится в в сессии, а не в реквесте. Это нужно, например, для визард форм, одна форма на несколько страниц.
Вот для этого и в вызывается formBackingObject второй раз (при "ПОСТ") - чтобы или вытянуть из сессии уже существующий комманд обжект, или сделать новый.
Поставь его в false у себя.

Цитата(garbuz @  27.5.2009,  15:22 Найти цитируемый пост)
А где это можно глянуть?

Если у тебя log4j подключен, поставь левел DEBUG для пакета org.springframework

Цитата(garbuz @  28.5.2009,  00:53 Найти цитируемый пост)
Есть на странице множественный select, как выбранные элементы списка превратить в набор и отдать его объекту? 

Посмотри тут, хотя у тебя вроде похоже сделано.


Цитата(garbuz @  28.5.2009,  16:29 Найти цитируемый пост)
Непонятно зачем метод initBinder вызывается столько раз? Мне кажется, что он должен вызываться один раз после сабмита, получать значение из формы и вытаскивать объект по этому значению.

Из-за ошибок бинда получается такой бардак, попробуй их исправить и посмотрим дальше.

По селекту - вроде все правильно. Ты точно айдишники передаешь? Геттеры/сеттеры правильные?


И еще.
1. Почему не возьмешь книгу по Спрингу, например "Spring Live". Там вроде это хорошо объясняется.
2. Почему не смотришь исходники Спринга? Для чего их открытыми держат? smile Там и увидишь всю логику обработки запроса.


--------------------
Lost....
PM MAIL MSN   Вверх
garbuz
Дата 29.5.2009, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Kangaroo, во-первых, спасибо большое за ответы!  smile 

Цитата(Kangaroo @  29.5.2009,  15:29 Найти цитируемый пост)
Это связано с параметром sessionForm.
Зачем этот флаг нужен: если он установлен, то комманд обжект хранится в в сессии, а не в реквесте. Это нужно, например, для визард форм, одна форма на несколько страниц.
Вот для этого и в вызывается formBackingObject второй раз (при "ПОСТ") - чтобы или вытянуть из сессии уже существующий комманд обжект, или сделать новый.
Поставь его в false у себя.

В принципе я все понял из твоего объяснения, но если я ставлю 
Код

setSessionForm(true);

то у меня formBackingObject вызывается один раз до сабмита формы, как я хотел. Т.е. как я понимаю, в этом методе, создаем объект, который будем заполнять данными из формы. Соответственно после сабмита нам надо получить его уже с данными. Если же поставить 
Код

setSessionForm(false);

то метод вызывается еще раз после сабмита, создается новый комманд обджект, а это мне не надо. Или я опять что-то неверно понял?


Цитата(Kangaroo @  29.5.2009,  15:29 Найти цитируемый пост)
Если у тебя log4j подключен, поставь левел DEBUG для пакета org.springframework

Нет, пока без него. Стыдно товарищи, но я им еще вообще не пользовался.

Цитата(Kangaroo @  29.5.2009,  15:29 Найти цитируемый пост)

Из-за ошибок бинда получается такой бардак, попробуй их исправить и посмотрим дальше.
По селекту - вроде все правильно. Ты точно айдишники передаешь? Геттеры/сеттеры правильные?

Исправил. Забил на спринговые теги, оставил только селект.
Код

<form:select path="categories" multiple="multiple">
       <c:forEach items="${cats}" var="cat">
               <option value="${cat.categoryId}"><c:out value="${cat.categoryName}"/></option>
       </c:forEach>
</form:select>

Так id выводится, все работает, биндер соответственно тоже отрабатывает нормально. С этим вроде разобрался smile
Еще вопрос по спринговым тегам. В примерах встречал <spring:bind> это как я понимаю в старых версиях спринга было, сейчас <form:. Верно? Или путаю? smile


Цитата(Kangaroo @  29.5.2009,  15:29 Найти цитируемый пост)

И еще.
1. Почему не возьмешь книгу по Спрингу, например "Spring Live". Там вроде это хорошо объясняется.
2. Почему не смотришь исходники Спринга? Для чего их открытыми держат? smile Там и увидишь всю логику обработки запроса. 

Книгу нашел, буду глядеть если что. В исходникики тоже постараюсь заглянуть smile 

Следующие вопросы )
1)Хочу сделать отдельное поле для ввода тегов через запятую, набор тегов тоже представляет собой коллекцию, но в итоге это будет выглядеть не как массив, как в случае с множественным селектом, а как простая строка. Какой биндер выбрать, чтобы на основе этой строки выбралась/создалась коллекция тегов. 
2)Так же туда же хочу запихать чекбокс, там пользователь отмечает черновик это или же нет. Ну понятно что я имею ввиду. Тоже вопрос какой биндер выбрать, чтобы вытащить объетк типа Status и назначить его новому посту.

Спасибо!

PM MAIL   Вверх
Kangaroo
Дата 29.5.2009, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


AA - Aussie Animal
****


Профиль
Группа: Участник Клуба
Сообщений: 2042
Регистрация: 7.10.2006
Где: US

Репутация: 14
Всего: 104



Цитата(garbuz @  29.5.2009,  18:02 Найти цитируемый пост)
то метод вызывается еще раз после сабмита, создается новый комманд обджект, а это мне не надо. Или я опять что-то неверно понял?

Он берется пустой и заполняется (биндится) значениями с формы. Если бы у тебя сессонФорм = тру, то брался бы не пустой, а полученный из сессии (может в нем уже есть данные с предыдущих форм-страниц).


Цитата(garbuz @  29.5.2009,  18:02 Найти цитируемый пост)
В примерах встречал <spring:bind> это как я понимаю в старых версиях спринга было, сейчас <form:. Верно? Или путаю? 

Я с этим не работал, но думаю что в <form: используется <spring:bind>. Он просто более нижнего уровня.

По вопросам:
1. Не знаю такого, напиши сам.

2. Зачем Status, если можно boolean и и стандартный биндер checkbox-boolean.


--------------------
Lost....
PM MAIL MSN   Вверх
garbuz
Дата 31.5.2009, 03:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(Kangaroo @  29.5.2009,  23:46 Найти цитируемый пост)

Он берется пустой и заполняется (биндится) значениями с формы. Если бы у тебя сессонФорм = тру, то брался бы не пустой, а полученный из сессии (может в нем уже есть данные с предыдущих форм-страниц).

Кажется начинаю понимать. Сам объект, который мне собственно и нужен, формируется два раза - до и после сабмита. Если я ставлю значение false, то мой объект будет тот, который уже создается после сабмита, и в который потом заносятся значения. А тот что был получен до сабмита, его схавает сборщик мусора.


Цитата(Kangaroo @  29.5.2009,  23:46 Найти цитируемый пост)
1. Не знаю такого, напиши сам.

вот. В принципе то, что я хотел (для реализации пришлось лезть в исходники спринга  smile )
Код

binder.registerCustomEditor(Set.class, "tags", new CustomCollectionEditor(Set.class) {
            public void setValue(Object value) {
                if (value != null) {
                    String str = value.toString();
                    String[] tags = str.trim().split(",");
                    Collection collection = Arrays.asList(tags);
                    super.setValue(collection);
                }
            }

            protected Object convertElement(Object element) {
                if (element != null) {
                    String tagName = element.toString();
                    Tag tag;
                    try {
                        tag = daoFacade.getTagDAO().getByName(tagName);
                        return tag;
                    } catch (IndexOutOfBoundsException e) {
                        tag = new Tag();
                        tag.setTagName(tagName);
                        tag.setPosts(new HashSet());
                        daoFacade.getTagDAO().create(tag);
                        return tag;
                    }
                }
                return null;
            }

        });


Вроде даже как работает smile



Цитата(Kangaroo @  29.5.2009,  23:46 Найти цитируемый пост)
2. Зачем Status, если можно boolean и и стандартный биндер checkbox-boolean. 

У поста планируется не два статуса, а больше. Так что обычный булеан тут не прокатит. Буду тоже извращаться и писать что-нибудь подходящее. 

Еще раз спасибо! smile

PM MAIL   Вверх
garbuz
Дата 1.6.2009, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Вот биндер для статуса, решил использовать радиобаттоны
Код

<td>Draft     : <form:radiobutton path="status" value="inactive"/> </td>
<td>Publish : <form:radiobutton path="status" value="active"/></td>

Сам кастом едитор
Код

binder.registerCustomEditor(Status.class, "status", new PropertyEditorSupport(){
            public void setAsText(String text){
                if (text instanceof String){
                    if (text.equals("inactive")){
                        Status status = daoFacade.getStatusDAO().getByName("inactive");
                        setValue(status);
                    } else if (text.equals("active")){
                        Status status = daoFacade.getStatusDAO().getByName("active");
                        setValue(status);
                    }

                }
            }

        });

Вопрос вот в чем. Когда Происход регистрация биндера, до показа формы, то сразу вызывается метод setTextAs, причем вызывается два раза с двумя значениями радиобаттнов, т.е. по идее из базы дергаются два объекта. После сабмита этот метод вызывается снова, но уже один раз с тем значением, которое мы выбрали на странице. Вытаскивается нужный объект типа Status. Почему спринг перед сабмитом дергает этод метод и вытаскивает "лишние объекты"?

PM MAIL   Вверх
garbuz
Дата 2.6.2009, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Начал прикручивать валидацию!  smile 
С текстовыми полями все ясно вроде бы, переопределяем метод getText:
Код

 public String getAsText() {
                Object value = getValue();
                if (value != null) {
                    Set<Tag> tags = (Set<Tag>) getValue();
                    StringBuilder builder = new StringBuilder();
                    for (Tag c : tags) {
                        if (c instanceof Tag) {
                            String tagName = c.getTagName();
                            System.out.println("tag name = " + tagName);
                            builder.append(tagName + ", ");
                        }
                    }
                    return builder.toString();
                }
                return null;
            }

Этот метод, возвращает строку из имени объектов коллекции тегов. 
А что делать с радиобаттонами и селектом? Как у них на странице засетить выбранные ранее значения?

PS. Вопрос по методу выше, почему метод вызывается еще несколько раз(а именно 4) до показы формы, потом после сабмита и после валидации. Неужели так и должно быть?
PM MAIL   Вверх
Старовъръ
Дата 2.6.2009, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 1
Всего: 10



1. Ммм.. а как валидация происходит? Не вижу тега <form:errors...>
2. <spring:bind> - это устаревшая вещь.
3. Почему бы не разбивать вопросы по разным темам? Название темы должно отражать ее суть и в одной теме желательно должен звучать один вопрос. Другим будет легче искать уже отвеченные темы, если их разбивать по отдельным вопросам.

Это сообщение отредактировал(а) Старовъръ - 2.6.2009, 12:03
PM MAIL WWW   Вверх
garbuz
Дата 2.6.2009, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(Старовъръ @  2.6.2009,  12:01 Найти цитируемый пост)
1. Ммм.. а как валидация происходит? Не вижу тега <form:errors...>
2. <spring:bind> - это устаревшая вещь

<form:errors...> на странице
Код

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ include file="include.jsp" %>
<html>
<head><title>New Post</title></head>
<body>
<form:form method="POST" commandName="newPost" action="createPost.htm">
    <table style="width:800px">
        <tr>
            <td>Choose categories</td>
            <td>
                <form:select path="categories" multiple="multiple">
                    <c:forEach items="${cats}" var="cat">
                        <option value="${cat.categoryId}"><c:out value="${cat.categoryName}"/></option>
                    </c:forEach>
                </form:select>
            </td>
            <td><form:errors path="categories" cssStyle="color:red;"/></td>
        </tr>
        <tr>
            <td>Post Name</td>
            <td>
                <form:input path="postName" />
            </td>
            <td><form:errors path="postName" cssStyle="color:red"/></td>
        </tr>
        <tr>
            <td>Preview</td>
            <td>
                <form:textarea path="preview" rows="10" cols="40"></form:textarea>
            </td>
            <td><form:errors path="preview" cssStyle="color:red;"/></td>
        </tr>
        <tr>
            <td>Post Body</td>
            <td>
                <form:textarea path="postBody" rows="10" cols="40"></form:textarea>
            </td>
            <td><form:errors path="postBody" cssStyle="color:red;"/></td>
        </tr>
          <tr>
            <td>Tags</td>
            <td>
                <form:input path="tags"/>
            </td>
            <td><form:errors path="tags" cssStyle="color:red;"/></td>
        </tr>
         <tr>
             <td>Status</td>
             <td>Draft   : <form:radiobutton path="status" value="inactive"/><br>
                 Publish : <form:radiobutton path="status" value="active"/></td>
             <td><form:errors path="status" cssStyle="color:red;"/></td>
         </tr>
          <tr>
             <td></td>
             <td></td>
             <td><input type="submit" value="submit"></td>
         </tr>
    </table>

</form:form>
</body>
</html>


А про <spring:bind я так и думал, что это устаревшая версия. Вопросы остаются открытыми:
Цитата

А что делать с радиобаттонами и селектом? Как у них на странице засетить выбранные ранее значения?

PS. Вопрос по методу выше, почему метод вызывается еще несколько раз(а именно 4) до показы формы, потом после сабмита и после валидации. Неужели так и должно быть?

PM MAIL   Вверх
garbuz
Дата 2.6.2009, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Еще вопрос.
Есть контроллер, который просто отображает какой-либо пост. На странице внизу есть форма для комментарев. Т.е. сама форма отображается все тем же контроллером. Какого типа должен быть контроллер, который обрабатывает комментарии? 
1)Если он будет предком SimpeFormController, тогда получается, что сама форма отображается другим контроллером. Или это не важно? Можно обойтись только POST запросом и все. Но с другой стороны если прикручивать валидацию и будет ошибка, то надо как-то снова отобразить эту страницу с формой, но этим же занимается другой контроллер.
2) Сделать предком AbstractController и просто вытаскивать данные из запроса. Но тогда мы теряем валидацию и прочие прелести SimpleFormController'a. 

Как в этом случае лучше поступить?
PM MAIL   Вверх
garbuz
Дата 2.6.2009, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Найдено рещение для радиобаттонов. Надо тоже было переопределить метод getAsText, который должен возвращать строку, подобно той, которая прописана у радиобаттонв на странице в атрибуте value, тогда после сабмита и возврата на форму, этот радиобаттно становится выделенным smile 

Остался множественный селект :(
PM MAIL   Вверх
garbuz
Дата 3.6.2009, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Решил пока оставить select в покое.
Перефразирую свой вопрос выше более понятно.

Есть PostController, который в качестве параметра принимает id поста, выбирает пост с комментариями из базы и вызывает вьюху, где все эти данные отображаются. Внизу страницы есть текстовое поле для комментариев. Так вот, какого типа должен быть контроллер, который будет добавлять эти комментарии?
Я вижу два варианта.
1) Это будет класс, расширяющий SipmleFormController
2) Это будет класс, расширяющий AbstractController

Если это первый вариант, то как мне в форме, которая будет отображаться другой вьюхой (та что упоминалась выше) указать поля для биндинга данных, что будет в случае если не пройдет валидация и снова потребуется отобразить форму - соответственно нужен GET запрос и нужно снова отобразить эту страницу с формой? Этим же занмиается Postcontroller. короче вот такая ситуация.

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

Кто что посоветует? Может есть более красивые и правильные решения? Надеюсь, что понятно обрисовал всю ситуацию smile
PM MAIL   Вверх
Старовъръ
Дата 4.6.2009, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 1
Всего: 10



Нет, не понятно) Если на странице есть инпуты, используется SimpleFormController. Он же расширяет AbstractController, посему ты и так, и так будешь использовать AbstractController smile

Это сообщение отредактировал(а) Старовъръ - 4.6.2009, 14:09
PM MAIL WWW   Вверх
Страницы: (4) Все 1 2 [3] 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.1004 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.