MVC

Шаблон проектирования - повторяющееся решение повторяющейся проблемы.

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

Все шаблоны делят на три группы:

Presentation - описывают презентационную логину (например View Helper)

Business - описывают решения для компонентов, отвечающих за бизнес слой приложения. (Session Facade)

Integration - отвечает за интеграцию разных компонентов (например источников данных и и бизнес-логикой), Пример DataAccessObject

Один из самых распространненных шаблонов является MVC. Есть два вида шаблона: mvc1 и mvc2

Контроллер может быть и сервлетом и фильтром.

В mvc1 контроллер у каждого представления свой, в mvc2 существует единый контроллер для всего приложения и все запросы к любой странице проходит через него. Контроллер отвечает за действия общие для всех страниц: навигация, журнализация, аутентификация, .......

mvc2 имеет два подвида:

Service to Worker

Dispatecher View

При использовании mvc2 возникает проблема как передать информацию контроллерку куда следует передать запрос. Это можно сделать тремя путями:

1) Использовать hidden-поля при post-запросах. Контроллер может извлечь из запроса и перевести управление на нужный вид

2) В качестве параметров url - http://host/?op=createUser

3) Передача параметров через сам url (без параметров). Чаще всего так и используется.

В 3) случае информацию можно передать в качестве суффиска (до точки) - тогда префикс указывает на контроллер. Если используется префикс, то наоборот.

Чаще используется вариант, когда на контроллер указывает суффикс

 controller *.do 

При перенаправлении используется специальный объект javax.servlet.RequestDispatcher.

У RequestDispatcher есть метод forward, котороый осуществляет внутренний роутинг на нужный объект или jsp-страницу.

Еще у RequestDispatcher есть include, который вызовет jsp и вернется обратно

Есть 4 способа получить RequestDispatcher,

Черзе контекст

Через request.getRequestDispatcher - здесь можно относительный путь

Через метод getNamedDispatcher(name) у контекста, отличие в том, что name - имя объекта.

Важно, что нельзя передавать управление на объекты вне текущего контекста. Чтобы все-таки передать, надо получить контекст нужного объекта через getContext.....

Недостаток mvc1 был в том, что все пути в контроллеры статически-прописаны. Хороший тон рекомендует управление данными: сделать универсальный контроллер, который будет считывать файл с настройками (правила навигации) и этот универсальный конторллер можно исапользовать в разных приложения только заменяя файл настроек.

Для того, чтобы в случае с универсальным контроллером можно было еще записывать действия, реализуется шаблон команд - реализуется класс, и с помощью рефлексии класс загружается в зависимости от того что в файле настроек содержится.

Рассмотрим один из пример:   Дествия указываются именем класса, а у класса должен быть метод execute  

jaxb - позволяет распарсить xml создать объект и

jxc - компилятор, позволяет из описания xml получить классы

schemaget - из описания классов получает схему xml

в netbeans это все встроено и руками запускать не придется.

bcontrol-config.xsd пусть в нашем примере схема объекта   <xsd...

max-Uccurs="1" - сколько раз может встречаться

type="xsd:stirng" - тип элемента строка

user="reque" - обязательный элемент

xjc использовать не надо, достаточно кликнуть по файлу и выбрать JAXB ... и netbeans сгенерирует класс, соответствующий схеме.

При загрузке таких классов, класс инициализируется один раз при загрузке приложение. Инициализация производится при помощи listener.

Метод execute должен возвращаь null если все выполнилось хорошо, иначе ошибка.

ДЗ сделать все это руками.

Содержимое схемы xsd:





  <xsd:element name="global-forwards" minOccurs="0" maxOccurs="1"> <xsd:complexType> <xsd:sequence> <xsd:element name="forward" minOccurs="1" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="pathName" type="xsd:string" use="required"/> <xsd:attribute name="path" type="xsd:string" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="requests" minOccurs="1" maxOccurs="1"> <xsd:complexType> <xsd:sequence> <xsd:element name="request" type="ReqInfo" minOccurs="1" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="message-resources" minOccurs="0" maxOccurs="1"> <xsd:complexType> <xsd:attribute name="parameter" type="xsd:string" use="required"/> <xsd:attribute name="null"     type="xsd:boolean"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> <xsd:complexType name="ReqInfo"> <xsd:sequence> <xsd:element name="action" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="className" type="xsd:string" use="required"/> </xsd:complexType> </xsd:element> <xsd:element name="forward" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="pathName" type="xsd:string" use="required"/> <xsd:attribute name="path" type="xsd:string" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="pathName" type="xsd:string" use="required"/> <xsd:attribute name="path" type="xsd:string" use="required"/> </xsd:complexType> </xsd:schema>

Из этого класса можно сгенерировать классы, которые выполнять роль роутера. Надо создать файл xml и в нем записать все маршруты, если по одному адресу придет запрос, то создать класс, вызвать в классе execute,

Пример xml:

<?xml version="1.0" encoding="UTF-8" ?> <bcontrol-config> <global-forwards> <forward pathName="index" path="/index.jsp"/> </global-forwards> <request pathName="countries" path="/WEB-INF/jsp/Country10.jsp"/> <request pathName="authors" path="/WEB-INF/jsp/Author10.jsp"> <action className="org.bookstore.action.SelectAuthorsAction"/> <forward pathName="error" path="/WEB-INF/jsp/Country10.jsp"/> <request pathName="currauthors" path="/WEB-INF/jsp/Author10.jsp"> <action className="org.bookstore.action.CheckExistAuthorsAction"/> <forward pathName="error" path="/WEB-INF/jsp/Country10.jsp"/> <request pathName="admin" path="/WEB-INF/jsp/Admin10.jsp"> <action pathName="org.bookstore.action.AdminAction"/> <message-resources parameter="org.bookstore.util.AppResources" null="false"/> </bcontrol-config>

Чтобы извлечь экземляры класса из примера этого файла, надо выполнить JABX.Parser unmarshal