JavaServer Faces и AJAX

Preview:

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

Въпроси?Въпроси?

Recommended