Структура Struts2
1. Зачем использовать рамки?
(1) Структура автоматически выполняет много тривиальных задач
Для Struts2 это помогает нам легко завершить преобразование типа данных, проверку данных, интернационализацию и т. Д.
Общие задачи в веб -разработке. Существуют также режимы шаблона, которые широко используются весной, которые делают наш процесс разработки более автоматизированным и интеллектуальным. Использование структуры-это избежать переосмысления колеса и повторной копии этих кодов шаблонов.
Структура позволяет нам больше сосредоточиться на проблемах более высокого уровня, чем на обычных рабочих процессах и основных задачах.
(2) Использование рамки означает изящно наследуя архитектуру за рамки
Архитектура за рамки обычно определяет серию рабочих процессов. Что нам нужно сделать, так это прикрепить код конкретного приложения к этому процессу, чтобы мы могли пользоваться различными преимуществами, предоставленными структурой. Иногда мы также можем противостоять архитектурным правилам структуры, но структура обычно обеспечивает свою архитектуру таким образом, чтобы его было трудно отвергнуть. Это так просто, что вы можете унаследовать отличную архитектуру изящно, и она бесплатна, так почему бы не сделать это?
(3) Легче найти хорошо обученных людей, использующих рамки
Я почти никогда не использовал каких -либо фреймворков во всем проекте моей компании ранее и искал услуги (аналогично JNDI)
Для регистрации печати (аналогично log4j), а затем в пул подключения к базе данных (аналогично DBCP), все они реализованы самим внутренним персоналом. Во -первых, это связано с тем, что проект относительно старый, и в то время не может быть никакой основы для использования с открытым исходным кодом. Во -вторых, это связано с консервативной стратегией компании, и беспокоит, что использование нестабильной структуры с открытым исходным кодом может привести к риску проекта. Это может быть верно в окружающей среде в то время, и высшее руководство компании, естественно, рассмотрит весь проект с более широкой точки зрения.
Однако, когда проект постепенно становится все больше, и в мире все больше и более превосходных рамках с открытым исходным кодом, если некоторые зрелые рамки с открытым исходным кодом нельзя реформироваться во времени и введены, конечный результат может заключаться в том, что вновь набранные разработчики должны изучать эту сложную систему с нуля (все внутренние системы, и в Интернете нет помощи) и быть осторожными с различными ошибками во внутренней структуре.
Стоимость действительно слишком высока.
(4) Внутренняя структура не может быть в курсе развития отрасли
Ошибка во внутренней структуре, упомянутая ранее. Для фреймворков с открытым исходным кодом может быть команда основателей Framework, большое количество энтузиастов с открытым исходным кодом,
Сообщество с открытым исходным кодом, чтобы поддержать его. Сила людей бесконечна, и можно представить скорость восстановления ошибок. Это из недавнего открытого исходного кода
Процесс исправления ошибок можно увидеть. Многие ошибки, которые были отложены в течение долгого времени, были быстро решены энтузиастами после того, как они становятся открытым исходным кодом, но как насчет внутренней структуры? После того, как люди, которые его разработали, покинули компанию, никто даже не прочитал бы его исходный код без крупных ошибок. Разрыв очевиден!
(5) Конечно, использование структуры не является огромной прибылью.
Как упоминалось ранее, использование незрелой структуры рискованно, и лучше быть консервативным для проекта, который не так радикален.
(Если это не группа свободных и безудержных фанатиков технических технологий, которые могут решить, какую структуру использовать по своему усмотрению, это действительно благословение)
Как и Sequioa, служба высокой доступности Java HA, которую я использовал ранее, эта структура больше не поддерживается компании разработчиков, и риск еще больше.
Кроме того, при использовании некоторых необычных структур, вы также должны обратить внимание на протокол лицензии на исходный код Framework и не ссылаться на его волей в проекте.
Измените исходный код структуры, чтобы избежать ненужных правовых споров.
2. Архитектура, стоящая за Struts2
Поскольку мы анализировали так много преимуществ рамки ранее, мы, естественно, начнем научиться использовать Struts2. Но используя Struts2
Какую элегантную архитектуру он наследует? Фактически, с более высокого уровня абстракции, это все еще модель MVC, с которой мы знакомы.
Согласно предыдущему примеру Helloworld, контроллер C (FilterDispatcher) - это то, что мы объявили в web.xml
CROUS2 CORE CLASS. И модель М - наш класс действий в новостях. И View v - это естественно News.jsp. Концепция модели кажется немного расплывчатой. Что такое модель? Фактически, эта концепция, которая звучит очень существительное, содержит как бизнес-данные, статически переданные с веб-фронта, так и внедрение бизнес-логики.
Некоторые люди могут сказать, что эта архитектура не нова, есть много средств MVC, в чем разница между этим и другими рамками? Давайте рассекаем Struts2 на более низком уровне абстракции и посмотрим, что делает его уникальным.
На первый взгляд, это выглядит очень сложно. Если мы только посмотрим на это с точки зрения пользователя, нам нужно только реализовать желтую часть во время разработки, то есть мы
struts.xml, newsaction и news.jsp в экземпляре Helloworld. Это все, что нам нужно сделать, как упоминалось ранее, нам нужно только делать очень мелочи, и мы становимся частью этой превосходной архитектуры.
Теперь посмотрите на другие части. FilterDispatcher - это файл сервлета, который мы настраиваем в web.xml, который является Struts2
Все веб -приложения Struts2 должны быть настроены таким образом. Затем синие и зеленые части являются ядром Struts2. Можно сказать, что эти классы тщательно разработаны разработчиками Struts2.
(1) Клиент отправляет запрос, а контейнер J2EE анализирует HTTP -пакет и инкапсулирует его в HttpservletRequest.
(2) FilterDispatcher перехватывает этот запрос и выполняет поиск MAPPER на основе пути запроса, чтобы определить, какое действие вызывает.
(3) Согласно результату возврата ActionMapper, FilterDispatcher доверяет ActionProxy, чтобы найти это действие на struts.xml.
(4) ActionProxy создает действие и начинает рекурсивные призывы к перехватчику и действию.
(5) Каждый перехватчик выполняет свои собственные задачи
(6) Реальный призыв к действию возвращает путь результата
(7) Объект результата выведет данные возврата в поток
(8) Верните httpservletresponse в контейнер J2EE, а контейнер отправляет клиенту HTTP -пакеты.
Это процесс выполнения Struts2. Основными объектами являются ActionInvocation и Interceptor, а также ActionContext, который еще не был введен.
ActionInvocation - это общее планирование всего процесса, которое очень похоже на объект вызова в Spring AOP. Многие перехватчики встроены в Struts2. Самое главное - сохранить параметры запроса и передать данные переднего плана с переменными элемента действия.
ActionContext - это глобальный контекстный объект, который сохраняет эти данные, и наиболее важным является ValueStack, используемый для сохранения экземпляра действия.
Так называемый глобальный означает, что ActionContext можно получить в действии и результате, но на самом деле это Threadlocal. Каждый поток запроса будет иметь свой собственный экземпляр действия и ActionContext.
Можно сказать, что обучение Struts2 в основном касается обучения:
(1) Пусть перехватчик и действие сотрудничают, чтобы выполнить задачу.
(2) Сохраните данные переднего плана в действие.
(3) Результат получает данные о возврате от действия через ValueStack.
3. Различия между Struts2 и Struts1
Из приведенного выше процесса выполнения мы уже можем увидеть огромную разницу между Struts1 и 2.
(1) Куда прошел Actionform? Действие остается тем же действием?
Самое очевидное, что мы не можем видеть объект Actionform во всем процессе, и хотя действие все еще называется этим именем, оно, похоже, полностью отличается от действия в Struts1.
Прежде всего, Actionform была заброшена, и данные, отправленные с стойки регистрации, можно было сохранить на любой POJO. Сначала день сохранения в ActionForm, а затем копирование в объект DTO закончился. Во -вторых, этот POJO на самом деле является переменной -членом в объекте действия. Это в struts1
В этом случае невозможно поделиться экземпляром действия для всех запросов. Теперь Struts2 создаст экземпляр действия для каждого запроса, так что это работает. В -третьих, хотя это возможно, кажется, что действие как модель М в MVC сохраняет данные и содержит бизнес -логику. Это плохой дизайн? На самом деле, если вы внимательно думаете об этом, этот дизайн очень удобен, мы уже получили данные.
Вы можете напрямую эксплуатировать уровень обслуживания. Действие, кажется, имеет слишком много обязанностей, но не так много.
(2) Как север фронтального телевода стал фильтром?
Мы знаем, что Struts1 и Spring MVC оба используются в качестве входов через северные сервлеты. Почему Struts2 используют сербовиляционные фильтры?
Поскольку Struts2 основан на ядре веб -работы, он полностью отличается от Struts1. Можно сказать, что веб -работа уменьшает приложения и J2EE
Связание API, такое как изменение ActionServlet на фильтр Сервлета и прямой доступ к httpservletrequest/response.
Например, любой POJO может служить формой действия, любой класс может использоваться в качестве действия без реализации интерфейса действия и т. Д.
Поэтому Struts2 также наследует этот превосходный неинвазивный дизайн.
Это несколько похоже на идеи дизайна Spring. Например, эти интерфейсы посуды вообще не необходимы вообще, чтобы минимизировать связь между кодом приложения и структурой. Инвазивность действительно является важным фактором, который следует учитывать при разработке структуры.
(3) ognl между фильтром, действием и результатом
Следующий рисунок может четко показать, как Ognl интегрирован в структуру Struts2.
Настолько удобно получить доступ к данным в действии, используя тег Struts2 в входной странице inputform.html и вернуться на страницу ResultPage.jsp.
Ognl предоставляет доступ к свойствам действий, сохраненных в ValueStack, так же удобно, как доступ к собственным свойствам ValueStack.
Обширное использование ognl является основной особенностью Struts2. Включая значения тега переднего плана, результат, получение значений от действия и т. Д., Будет использовать Ognl в больших количествах. Тем не менее, отражение много используется в ognl. Я думаю, что это одна из причин, по которой Struts2 не так хороша, как Struts1. В конце концов, требуется определенная цена, чтобы получить гибкую и низкоосвященную архитектуру.
(4) Сила перехвата неизвестна
Еще одна мощная особенность в Struts2 - перехватчик перехватчика. У Struts2 встроено большое количество перехватчиков, которые позволяют повторно использовать большое количество кода, автоматизируя то, что мы ранее называли тривиальными задачами, что позволяет Struts2 достигать высокого уровня разделения внимания. Это действительно модель для применения идей AOP в рамках!
Struts2 Три метода передачи данных
Struts2 предоставляет три способа сохранения параметров в http -запросах: атрибуты Javabean, Javabean -объекты и модель -образные объекты. Давайте посмотрим на эти три метода передачи данных с помощью наиболее распространенного примера входа в систему. Код страницы очень прост. Форма отправки содержит имя пользователя и пароль. Вы можете получить эти два параметра в действии, чтобы проверить, успешно входит ли пользователь.
1. Javabean Properties
< %@ page contentType = "text/html; charset = utf-8" %> <html> <Head> </head> <body> <h1> страница входа </h1> <form action = "/cdai/login" method = "post"> <div> <label для = "username"> name: </label> <input id = "US name" = "us name" = "us name" = "us =" us name "=" us name "=" us name "=" us = "us name" = "us name" = "us name" = "us name" = "us =" = "use name" = </div> <div> <label for="password">Password:</label> <input id="password" name="password" type="password"/> </div> <div> <label for="rememberMe"> <input id="rememberMe" name="rememberMe" type="checkbox"/> Remember me</label> <input type="submit" value="Login"></input> </div> </form> </body> </html>
пакет com.cdai.web.ssh.action; Импорт com.cdai.web.ssh.request.loginrequest; Импорт com.cdai.web.ssh.service.userservice; импорт com.opensymphony.xwork2.action; импорт com.opensymphony.xwork2.modeldriven; Общедоступный вход в систему реализует действие {Private String username; Private String Password; Private Userservice Userservice; @Override public String execute () {system.out.println ("action action -" + request); вернуть успех; } public String getUsername () {return Request; } public void setUsername (string username) {this.username = username; } public String getPassword () {return Request; } public void setPassword (String password) {this.password = password; }}Этот метод относительно прост, напрямую сохранять параметры в форме для свойств в действии. При проверке, действие также может потребоваться инкапсулировать имя пользователя и пароль в DTO, чтобы передать его на уровень службы для проверки. Так почему бы не пойти еще дальше и сохранить имя пользователя и пароль непосредственно в DTO.
2. Javabean Objects
< %@ page contentType = "text/html; charset = utf-8" %> <html> <Head> </head> <body> <h1> страница входа </h1> <form action = "/cdai/login" method = "post"> <div> <label для = "username"> name: </label> <input id = "use name". type = "textfield"/> </div> <div> <label для = "пароль"> пароль: </label> <input id = "password" name = "request.password" type = "пароль"/> </div> <div> <label для = "homameme"> <input id = "homame" name = "homame me" type = "checkbox"/> inmove me </label> <into "name =" homame me "type ="/> homp inmove me </label> <into "name =" homame me empo "/> </> homp homp. value = "login"> </input> </div> </form> </body> </html>
пакет com.cdai.web.ssh.action; Импорт com.cdai.web.ssh.request.loginrequest; Импорт com.cdai.web.ssh.service.userservice; импорт com.opensymphony.xwork2.action; импорт com.opensymphony.xwork2.modeldriven; Общедоступное вход в систему реализует Action {Private LoginRequest запрос; Private Userservice Userservice; @Override public String execute () {system.out.println ("action action -" + request); вернуть успех; } public LoginRequest getRequest () {return Request; } public void setRequest (запрос loginRequest) {this.Request = request; }} Это позволяет легко позвонить в сервисный слой напрямую. Но есть небольшой недостаток, что это углубляет глубину имени параметра страницы, только добавление запроса к имени параметра
Префикс (имя атрибута в действии) позволяет Struts2 правильно сохранить параметры в форме в объекте запроса через ognl.
3. Модельный объект
< %@ page contentType = "text/html; charset = utf-8" %> <html> <Head> </head> <body> <h1> страница входа </h1> <form action = "/cdai/login" method = "post"> <div> <label для = "username"> name: </label> <input id = "US name" = "us name" = "us name" = "us =" us name "=" us name "=" us name "=" us = "us name" = "us name" = "us name" = "us name" = "us =" = "use name" = </div> <div> <label for="password">Password:</label> <input id="password" name="password" type="password"/> </div> <div> <label for="rememberMe"> <input id="rememberMe" name="rememberMe" type="checkbox"/> Remember me</label> <input type="submit" value="Login"></input> </div> </form> </body> </html>
пакет com.cdai.web.ssh.action; Импорт com.cdai.web.ssh.request.loginrequest; Импорт com.cdai.web.ssh.service.userservice; импорт com.opensymphony.xwork2.action; импорт com.opensymphony.xwork2.modeldriven; Общедоступное вход в систему реализует действие, ModelDriven <goginRequest> {private loginRequest request = new LoginRequest (); Private Userservice Userservice; @Override public String execute () {system.out.println ("action action -" + request); вернуть успех; } @Override public LoginRequest getModel () {return request; }} Таким образом, требуется еще один интерфейс модели, и объекты, предоставленные моделью, сохраняются в ValueStac
Имена атрибутов имени пользователя и пароля определяют имя параметра формы.
Какой из трех методов не должен быть обобщен? Это зависит от конкретных потребностей проекта, а затем решите его самостоятельно!