JavaServer Faces и AJAX
description
Transcript of JavaServer Faces и AJAX
![Page 1: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/1.jpg)
JavaServer Faces и AJAX
Цветелин АндреевБългарска асоциация на разработчиците на софтуер
![Page 2: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/2.jpg)
СъдържаниеСъдържание
• Добавяне на Добавяне на AJAX AJAX функционалност към функционалност към съществуващи съществуващи JSF JSF приложенияприложения
• Изграждане на потребителски компоненти с Изграждане на потребителски компоненти с AJAX AJAX функционалностфункционалност
• Съществуващи библиотекиСъществуващи библиотеки
![Page 3: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/3.jpg)
JavaServer Faces и AJAX JavaServer Faces и AJAX
• JavaServer Faces?JavaServer Faces?• Част от J2EEЧаст от J2EE• Базиран на JSP и Java ServletsБазиран на JSP и Java Servlets• Разделя бизнес логиката от презентационната Разделя бизнес логиката от презентационната
частчаст• Лесен начин за разширяване на готовите Лесен начин за разширяване на готовите
компонентикомпоненти
![Page 4: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/4.jpg)
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>
• Дефиниране на форматаДефиниране на формата
![Page 5: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/5.jpg)
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
![Page 6: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/6.jpg)
ДемонстрацияДемонстрация
JSF Hello WorldJSF Hello World
![Page 7: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/7.jpg)
• Клиентска частКлиентска част• JavaScript функции за комуникация със JavaScript функции за комуникация със
сървърната частсървърната част• Прихващане на събития, свързани с полето за Прихващане на събития, свързани с полето за
въвеждане на иметовъвеждане на името• Компонта за ивеждане на резултата от AJAX Компонта за ивеждане на резултата от AJAX
заявкитезаявките• Сървърна частСървърна част
• Сърлвет, обработващ заявкитеСърлвет, обработващ заявките
Добавяне на автоматични Добавяне на автоматични подсказки чрез подсказки чрез AJAX - ServletAJAX - Servlet
![Page 8: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/8.jpg)
Клиентска частКлиентска част
• Връзка към JavaScript файлаВръзка към JavaScript файла
<script type="text/javascript" src="pages/script.js"/>
• Попъп менюПопъп меню
<div id="menu-popup1" ... ></div>
• Обработка на събитията за input полетоОбработка на събитията за input полето<h:inputText ... onkeyup="doCompletion(...);" ... />
![Page 9: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/9.jpg)
Клиентска частКлиентска част
• Изпращане на заявкиИзпращане на заявки
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); }
![Page 10: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/10.jpg)
Сървърна частСървърна част
• AjaxServletAjaxServlet
public void doGet(...) { ... String key = (String) request.getParameter("key"); namesBean.getMatches(null, key, result); ...
public class AjaxServlet extends HttpServlet
• Обработка на параметрите на заявката и Обработка на параметрите на заявката и извличане на резулатизвличане на резулат
![Page 11: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/11.jpg)
Сървърна частСървърна част
• Подготвяне и връщане на отговораПодготвяне и връщане на отговора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()); ...
![Page 12: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/12.jpg)
Сървърна частСървърна част
• Регистриране на сървлетаРегистриране на сървлета
<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
![Page 13: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/13.jpg)
ДемонстрацияДемонстрация
Добавяне на автоматични Добавяне на автоматични подсказки чрез подсказки чрез AJAX - ServletAJAX - Servlet
![Page 14: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/14.jpg)
• Жизнен цикъл на JSF приложениетоЖизнен цикъл на JSF приложението• Restore ViewRestore View
• PhaseListenerPhaseListener• Пролседява жизнения цикълПролседява жизнения цикъл• Можем да прихванем всяка заявка в контекста Можем да прихванем всяка заявка в контекста
на приложениетона приложението
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX - PhaseListenerAJAX - PhaseListener
![Page 15: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/15.jpg)
Клиентска частКлиентска част
• Заявката трябва да е в контекста на Заявката трябва да е в контекста на приложениетоприложението
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
![Page 16: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/16.jpg)
Сървърна частСървърна част
• Имплементиране на 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); }}
![Page 17: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/17.jpg)
Сървърна частСървърна част
• Прекъсване на жизнения цикълПрекъсване на жизнения цикълevent.getFacesContext().responseComplete();
• Регистриране на потребителски Регистриране на потребителски PhaseListenerPhaseListener
<lifecycle> <phase-listener>demo.AjaxListener</phase-listener> </lifecycle>
faces-config.xml
![Page 18: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/18.jpg)
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX - PhaseListenerAJAX - PhaseListener
ДемонстрацияДемонстрация
![Page 19: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/19.jpg)
Servlet vs. PhaseListenerServlet vs. PhaseListener
• Приблизително еднакви по Приблизително еднакви по производителност и сложностпроизводителност и сложност
• PhaseListener решението е свързано с JSFPhaseListener решението е свързано с JSF• При PhaseListener не се налага да се При PhaseListener не се налага да се
модифицира web.xmlмодифицира web.xml
![Page 20: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/20.jpg)
• Не са преизползваемиНе са преизползваеми• Авторът на страницата трябва да се грижи за Авторът на страницата трябва да се грижи за
JavaScriptJavaScript• Авторът на страницата трябва да е запознат Авторът на страницата трябва да е запознат
със сървърната частсъс сървърната част
НедостатъциНедостатъци
![Page 21: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/21.jpg)
• Възползва се от лесния начин за Възползва се от лесния начин за конструиране на потребителски компонентиконструиране на потребителски компоненти
• Избягват се недостатъците на горните Избягват се недостатъците на горните подходиподходи• Могат да се използват без промяна в повече Могат да се използват без промяна в повече
приложенияприложения• Използват се без познания по Използват се без познания по JavaScriptJavaScript
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX – Custom ComponentAJAX – Custom Component
![Page 22: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/22.jpg)
• Потребителската компонента отговаря за Потребителската компонента отговаря за следните неща:следните неща:• Рендерира HTML презентацията на Рендерира HTML презентацията на
компонентата компонентата • Грижи се за добавянето на връзка към Грижи се за добавянето на връзка към
JavaScript файла в HTML сраницата както и за JavaScript файла в HTML сраницата както и за предоставянето на този файл на клиентапредоставянето на този файл на клиента
• Грижи се за обработката на AJAX заявкитеГрижи се за обработката на AJAX заявките
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX – Custom ComponentAJAX – Custom Component
![Page 23: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/23.jpg)
• Построяване на потребителски компонентиПострояване на потребителски компоненти• Дефинираме собствен таг с атрибутиДефинираме собствен таг с атрибути• Имплементираме HTML рендерерИмплементираме HTML рендерер• Имплементираме PhaseListenerИмплементираме PhaseListener• Имплементираме сървърна компонента Имплементираме сървърна компонента
наследяваща компонентата HtmlInputTextнаследяваща компонентата HtmlInputText
Добавяне на автоматични подсказки Добавяне на автоматични подсказки чрез чрез AJAX – Custom ComponentAJAX – Custom Component
![Page 24: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/24.jpg)
Рендериране на 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
![Page 25: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/25.jpg)
Рендериране на HTML за Рендериране на HTML за компонентатакомпонентата
• Изключваме подсказките от браузъраИзключваме подсказките от браузъра
protected void getEndTextToRender(...) throws IOException { ... writer.writeAttribute("autocomplete", "off", null); ... writer.writeAttribute("onkeyup", "doCompletion(...)", null); ...}
AjaxTextFieldRenderer.java
![Page 26: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/26.jpg)
• Само един път в страницатаСамо един път в страницата
Рендериране на 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
![Page 27: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/27.jpg)
• Генерираният 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
![Page 28: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/28.jpg)
Обработка на 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
![Page 29: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/29.jpg)
Модел на работаМодел на работа
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
![Page 30: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/30.jpg)
Пакетиране на потребителската Пакетиране на потребителската компонентакомпонента
ДемонстрацияДемонстрация
![Page 31: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/31.jpg)
Използване на Използване на потребителската компонентапотребителската компонента
• Лесно, бързо, без 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
![Page 32: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/32.jpg)
Използване на потребителската Използване на потребителската компонентакомпонента
ДемонстрацияДемонстрация
![Page 33: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/33.jpg)
JavaServer Faces и AJAXJavaServer Faces и AJAX
• Библиотеки с готови AJAX enabled Библиотеки с готови AJAX enabled компонентикомпоненти• WebStudioWebStudio• AjaxFacesAjaxFaces• AJAX for JavaServer FacesAJAX for JavaServer Faces
• Свободна за свалянеСвободна за сваляне• Добавяне на Добавяне на AJAX AJAX в същесвуващи в същесвуващи JSF JSF
приложения без приложения без JavaScriptJavaScript
![Page 34: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/34.jpg)
Ресурси по тематаРесурси по темата
• 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/
![Page 35: JavaServer Faces и AJAX](https://reader036.fdocuments.net/reader036/viewer/2022062302/56816850550346895dde547c/html5/thumbnails/35.jpg)
JavaServer Faces и AJAXJavaServer Faces и AJAX
Въпроси?Въпроси?