Upload
morley
View
86
Download
6
Embed Size (px)
DESCRIPTION
JavaServer Faces и AJAX. Цветелин Андреев. Българска асоциация на разработчиците на софтуер. Съдържание. Добавяне на AJAX функционалност към съществуващи JSF приложения Изграждане на потребителски компоненти с AJAX функционалност Съществуващи библиотеки. JavaServer Faces и AJAX . - PowerPoint PPT Presentation
Citation preview
JavaServer Faces и AJAX
Цветелин АндреевБългарска асоциация на разработчиците на софтуер
СъдържаниеСъдържание
• Добавяне на Добавяне на AJAX AJAX функционалност към функционалност към съществуващи съществуващи JSF JSF приложенияприложения
• Изграждане на потребителски компоненти с Изграждане на потребителски компоненти с AJAX AJAX функционалностфункционалност
• Съществуващи библиотекиСъществуващи библиотеки
JavaServer Faces и AJAX JavaServer Faces и AJAX
• JavaServer Faces?JavaServer Faces?• Част от J2EEЧаст от J2EE• Базиран на JSP и Java ServletsБазиран на JSP и Java Servlets• Разделя бизнес логиката от презентационната Разделя бизнес логиката от презентационната
частчаст• Лесен начин за разширяване на готовите Лесен начин за разширяване на готовите
компонентикомпоненти
JSF Hello WorldJSF Hello World
• Включване на таг библиотекитеВключване на таг библиотеките
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %><%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<h:form id="helloForm"> <h:outputText value="#{txt.prompt}"/> <h:inputText size="40" id="nameField" value="#{personBean.name}" required="true"/> <h:commandButton action="greeting" value="#{txt.button_text}" /></h:form>
• Дефиниране на форматаДефиниране на формата
JSF Hello WorldJSF Hello World
• Декларация на Managed Bean в faces-Декларация на Managed Bean в faces-config.xmlconfig.xml
• Изписване на резултата в следващата Изписване на резултата в следващата страницастраница
<h:outputText value="#{personBean.name}" />
<managed-bean> <managed-bean-name>personBean</managed-bean-name> <managed-bean-class>demo.PersonBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope></managed-bean>
faces-config.xml
ДемонстрацияДемонстрация
JSF Hello WorldJSF Hello World
• Клиентска частКлиентска част• JavaScript функции за комуникация със JavaScript функции за комуникация със
сървърната частсървърната част• Прихващане на събития, свързани с полето за Прихващане на събития, свързани с полето за
въвеждане на иметовъвеждане на името• Компонта за ивеждане на резултата от AJAX Компонта за ивеждане на резултата от AJAX
заявкитезаявките• Сървърна частСървърна част
• Сърлвет, обработващ заявкитеСърлвет, обработващ заявките
Добавяне на автоматични Добавяне на автоматични подсказки чрез подсказки чрез AJAX - ServletAJAX - Servlet
Клиентска частКлиентска част
• Връзка към JavaScript файлаВръзка към JavaScript файла
<script type="text/javascript" src="pages/script.js"/>
• Попъп менюПопъп меню
<div id="menu-popup1" ... ></div>
• Обработка на събитията за input полетоОбработка на събитията за input полето<h:inputText ... onkeyup="doCompletion(...);" ... />
Клиентска частКлиентска част
• Изпращане на заявкиИзпращане на заявки
function doCompletion(...) { var url = "AjaxServlet?key=" + escape(target.value); ... req.onreadystatechange = processRequest; req.open("GET", url, true); req.send(null);
• Обработка на резултатаОбработка на резултата
function parseMessages(...) { var items = req.responseXML.getElementsByTagName("items")[0]; for (loop = 0; loop < items.childNodes.length; loop++) { var item = items.childNodes[loop]; appendItem(menu, item.childNodes[0].nodeValue); }
Сървърна частСървърна част
• AjaxServletAjaxServlet
public void doGet(...) { ... String key = (String) request.getParameter("key"); namesBean.getMatches(null, key, result); ...
public class AjaxServlet extends HttpServlet
• Обработка на параметрите на заявката и Обработка на параметрите на заявката и извличане на резулатизвличане на резулат
Сървърна частСървърна част
• Подготвяне и връщане на отговораПодготвяне и връщане на отговораpublic void doGet(...) { ... sb.append("<items>"); Iterator it = items.iterator(); while (it.hasNext()) { sb.append("<item>"); sb.append(it.next().toString()); sb.append("</item>"); } sb.append("</items>"); ... response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); response.getWriter().write(sb.toString()); ...
Сървърна частСървърна част
• Регистриране на сървлетаРегистриране на сървлета
<servlet> <servlet-name>Ajax Faces Servlet</servlet-name> <servlet-class>com.ceco.jsf.AjaxServlet</servlet-class></servlet><servlet-mapping> <servlet-name>Ajax Faces Servlet</servlet-name> <url-pattern>/AjaxServlet</url-pattern></servlet-mapping>
web.xml
ДемонстрацияДемонстрация
Добавяне на автоматични Добавяне на автоматични подсказки чрез подсказки чрез AJAX - ServletAJAX - Servlet
• Жизнен цикъл на JSF приложениетоЖизнен цикъл на JSF приложението• Restore ViewRestore View
• PhaseListenerPhaseListener• Пролседява жизнения цикълПролседява жизнения цикъл• Можем да прихванем всяка заявка в контекста Можем да прихванем всяка заявка в контекста
на приложениетона приложението
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX - PhaseListenerAJAX - PhaseListener
Клиентска частКлиентска част
• Заявката трябва да е в контекста на Заявката трябва да е в контекста на приложениетоприложението
var url = "faces/ajax?&key=" + escape(target.value);
• Дефиниране на контекстаДефиниране на контекста
<servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern></servlet-mapping>
web.xml
Сървърна частСървърна част
• Имплементиране на PhaseListenerИмплементиране на PhaseListener
• Определяне на фазата от жизнения цикълОпределяне на фазата от жизнения цикълpublic class AjaxListener implements PhaseListener {
public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW;}
• Филтриране на AJAX заявкатаФилтриране на AJAX заявкатаpublic void afterPhase(PhaseEvent event) { String rootId = event.getFacesContext().getViewRoot().getViewId(); if (rootId.indexOf("ajax") != -1) { handleAjaxRequest(event); }}
Сървърна частСървърна част
• Прекъсване на жизнения цикълПрекъсване на жизнения цикълevent.getFacesContext().responseComplete();
• Регистриране на потребителски Регистриране на потребителски PhaseListenerPhaseListener
<lifecycle> <phase-listener>demo.AjaxListener</phase-listener> </lifecycle>
faces-config.xml
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX - PhaseListenerAJAX - PhaseListener
ДемонстрацияДемонстрация
Servlet vs. PhaseListenerServlet vs. PhaseListener
• Приблизително еднакви по Приблизително еднакви по производителност и сложностпроизводителност и сложност
• PhaseListener решението е свързано с JSFPhaseListener решението е свързано с JSF• При PhaseListener не се налага да се При PhaseListener не се налага да се
модифицира web.xmlмодифицира web.xml
• Не са преизползваемиНе са преизползваеми• Авторът на страницата трябва да се грижи за Авторът на страницата трябва да се грижи за
JavaScriptJavaScript• Авторът на страницата трябва да е запознат Авторът на страницата трябва да е запознат
със сървърната частсъс сървърната част
НедостатъциНедостатъци
• Възползва се от лесния начин за Възползва се от лесния начин за конструиране на потребителски компонентиконструиране на потребителски компоненти
• Избягват се недостатъците на горните Избягват се недостатъците на горните подходиподходи• Могат да се използват без промяна в повече Могат да се използват без промяна в повече
приложенияприложения• Използват се без познания по Използват се без познания по JavaScriptJavaScript
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX – Custom ComponentAJAX – Custom Component
• Потребителската компонента отговаря за Потребителската компонента отговаря за следните неща:следните неща:• Рендерира HTML презентацията на Рендерира HTML презентацията на
компонентата компонентата • Грижи се за добавянето на връзка към Грижи се за добавянето на връзка към
JavaScript файла в HTML сраницата както и за JavaScript файла в HTML сраницата както и за предоставянето на този файл на клиентапредоставянето на този файл на клиента
• Грижи се за обработката на AJAX заявкитеГрижи се за обработката на AJAX заявките
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX – Custom ComponentAJAX – Custom Component
• Построяване на потребителски компонентиПострояване на потребителски компоненти• Дефинираме собствен таг с атрибутиДефинираме собствен таг с атрибути• Имплементираме HTML рендерерИмплементираме HTML рендерер• Имплементираме PhaseListenerИмплементираме PhaseListener• Имплементираме сървърна компонента Имплементираме сървърна компонента
наследяваща компонентата HtmlInputTextнаследяваща компонентата HtmlInputText
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX – Custom ComponentAJAX – Custom Component
Рендериране на HTML за Рендериране на HTML за компонентатакомпонентата
• Добавяне на попъп меню и прихващане на Добавяне на попъп меню и прихващане на събитията от компонентатасъбитията от компонентата
protected void getEndTextToRender(...) throws IOException { ... writer.startElement("div", component); writer.writeAttribute("id", "menu-popup0", null); ... writer.writeAttribute("class", "popupFrame", null); writer.endElement("div"); ...}
AjaxTextFieldRenderer.java
Рендериране на HTML за Рендериране на HTML за компонентатакомпонентата
• Изключваме подсказките от браузъраИзключваме подсказките от браузъра
protected void getEndTextToRender(...) throws IOException { ... writer.writeAttribute("autocomplete", "off", null); ... writer.writeAttribute("onkeyup", "doCompletion(...)", null); ...}
AjaxTextFieldRenderer.java
• Само един път в страницатаСамо един път в страницата
Рендериране на JavaScript Рендериране на JavaScript файлафайла
protected void getEndTextToRender(...) throws IOException { ... renderScriptOnce(writer, component, context); ...}private void renderScriptOnce { Map requestMap = context.getExternalContext().getRequestMap(); Boolean scriptRendered = (Boolean)requestMap.get(RENDERED_SCRIPT_KEY);
if (scriptRendered == Boolean.TRUE) { return; } requestMap.put(RENDERED_SCRIPT_KEY, Boolean.TRUE); ...
AjaxTextFieldRenderer.java
• Генерираният HTMLГенерираният HTML
<script type="text/javascript" src="faces/ajaxtextfield.js"/>
• Обработка на заявката за JavaScript файлаОбработка на заявката за JavaScript файла
Рендериране на JavaScript Рендериране на JavaScript файлафайла
public void afterPhase(PhaseEvent event) { String rootId = event.getFacesContext().getViewRoot().getViewId();
if (rootId.endsWith("ajaxtextfield.js")) { handleResourceRequest(event, "script.js", "text/javascript"); } ...
AjaxPhaseListener.java
Обработка на AJAX заявкитеОбработка на AJAX заявките
• По аналогичен начин на примера с По аналогичен начин на примера с PhaseListenerPhaseListener
private void handleAjaxRequest(PhaseEvent event) { ... sb.append("<items>"); Iterator it = items.iterator(); while (it.hasNext()) { sb.append("<item>"); sb.append(it.next().toString()); sb.append("</item>"); } sb.append("</items>"); ... response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); response.getWriter().write(sb.toString()); ...
AjaxPhaseListener.java
Модел на работаМодел на работа
11
22
33
Web Page Web Container<script type="text/javascript" src="faces/ajax-textfield.js"/>
XMLHttpRequest
XMLHttpRequest Callback
JavaScript
Name: SonSonya
Custom component
script.js
PhaseListener
NamesBean
Пакетиране на потребителската Пакетиране на потребителската компонентакомпонента
ДемонстрацияДемонстрация
Използване на Използване на потребителската компонентапотребителската компонента
• Лесно, бързо, без JavaScript!Лесно, бързо, без JavaScript!
<%@ taglib uri="http://java.sun.com/ajaxC/txt" prefix="aj" %>...<aj:completionField size="40" id="nameField" completionMethod="#{namesBean.getMatches}" value="#{personBean.name}" required="true" onchoose="function(item) { return chooseName(item); }"/>
inputname.jsp
Използване на потребителската Използване на потребителската компонентакомпонента
ДемонстрацияДемонстрация
JavaServer Faces и AJAXJavaServer Faces и AJAX
• Библиотеки с готови AJAX enabled Библиотеки с готови AJAX enabled компонентикомпоненти• WebStudioWebStudio• AjaxFacesAjaxFaces• AJAX for JavaServer FacesAJAX for JavaServer Faces
• Свободна за свалянеСвободна за сваляне• Добавяне на Добавяне на AJAX AJAX в същесвуващи в същесвуващи JSF JSF
приложения без приложения без JavaScriptJavaScript
Ресурси по тематаРесурси по темата
• JSFJSF• http://java.sun.com/javaee/javaserverfaces/http://java.sun.com/javaee/javaserverfaces/• http://www.jsftutorials.net/http://www.jsftutorials.net/
• JSF JSF и и AJAXAJAX• https://bpcatalog.dev.java.net/ajax/jsf-ajax/https://bpcatalog.dev.java.net/ajax/jsf-ajax/• https://ajax4jsf.dev.java.net/https://ajax4jsf.dev.java.net/
JavaServer Faces и AJAXJavaServer Faces и AJAX
Въпроси?Въпроси?