JavaServer Faces Разширяване на JavaServer Faces



Дата27.03.2017
Размер67.33 Kb.
#17890

JavaServer Faces

Разширяване на JavaServer Faces

Построяване и използване на собствени конвертери


Както споменахме миналия път, от гледна точка на конвертния модел в JSF има два изгледа на данните: моделен и презентационен. Единият работи с реалния тип на данните, а другия се грижи за визуализирането им (единият е Java изгледът, другият е HTML изгледът). Когато стандартните конвертери не ни вършат работа JSF предлага лесен начин за построяване на собствени. Изисква се имплементирането на интерфейса Converter, който се състои от две части (методи) getAsObject и getAsString.

Наследявайки метода getAsObject дефинираме как данните се преобразуват от визуалната част до модела. Аналогично getAsString прави обратното.

В следващата демонстрация използваме ICQ номер. В модела искаме да го третираме като цяло число, а при клиента искаме да се визуализира това число като низ с тирета на всеки три символа.

Създаваме собствен клас и дефинираме двата метода по следния начин:



public Object getAsObject(FacesContext context, UIComponent

component, String value) {

String newValue = value.replaceAll("-", "").trim();

return Long.valueOf(newValue);

}
public String getAsString(FacesContext context, UIComponent

component, Object value) {

String icqStr = value.toString();

String ret = icqStr.replaceAll("(\\d{3})", "$1-");

return ret;

}

В метода getAsObject премахваме всички тирета и образуваме цяло число. В другят метод правим обратното – добавяме тирета.

Регистрираме конвертера в конфигурационния файл по следния начин:





ICQConverter

com.dreamix.jsf.ICQConverter



И използваме конвертера в нашата JSP страница:












Построяване и използване на собствени валидатори


Ако искаме да използваме специфична валидация, трябва да построим собствени валидатори. Това може да стане по няколко начина. В следващата демонстрация ще покажем как става това с имплементирането на интерфейса Validator:

public void validate(FacesContext context, UIComponent component,

Object value) throws ValidatorException {

String str = value.toString();

boolean valid = str.matches("^[a-zA-Z][\\w\\.-]*[a-zA-Z0-9]" +

"@[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]"+

"*[a-zA-Z]$");

if (false == valid) {

FacesMessage errMsg = new FacesMessage("Invalid email");

throw new ValidatorException(errMsg);

}

}

Регистрираме валидатора в конфигурационния файл по следния начин:



EmailValidator

com.dreamix.jsf.EmailValidator



И го използваме в нашата JSP страница:







Възможно е да добавяме атрибути на валидатора, да запазваме и възстановяваме състоянието му между заявките.

Построяване и използване на собствени слушатели за събития


В тази част ще дадем примери за използване слушателите за събитията value-change и action. value-change събитието възниква при промяна на стойността на UIInput компонента. Така не се налага всеки път да проверявате за стойност на компонента, а получавате ‘известие’ само когато се смени стойността.

Action събитието възниква при компонентите UICommand. Тук възниква въпросът каква е разликата между посочване на bean метод в атрибута action и регистрирането на actionListener. Разликата е, че action метода се използва за навигация породена от определена логика, докато при actionListener имаме фиксирана навигация.

Използването на собствени слушатели е аналогично на използване на собствени валидатори и конвертери. Демонстрацията остава за читателя.

Построяване и използване на собствени компоненти и рендерери


Преди демонстрацията за построяване на собствени компоненти и рендерери е изключително важно да се разгледа въпросът при какви ситуации да се използват те. Имаме ли реално нужда от собствени компоненти или можем да използваме готовите? Ето няколко ситуации, в които е добре да се използват потребителски компоненти:

- Имаме нужда от добавянето на ново поведение (генериране на нови събития при определени условия)

- Съчетаване на няколко готови компоненти в една нова – компонента за избор на дата, състояща се от три падащи менюта, инпут поле за въвеждане на номер на кредитна карта, състоящо се от 4 стандартни инпут полета.

- Създаване на компонента за готова HTML компонента, която не е включена в стандартната дистрибуция на JSF

- Когато дадена компонента не се рендерира до HTML, а до някакъв друг клиент. Можете да смените само рендерера, можете да изградите собствена компонента, която липсва в HTML (прогрес бар, т.н)

И няколко ситуации, в които се препоръчват стандартните:

- Имате нужда само да боравите с данните на компонентата. Вместо да създаваме собствена компонента, можем да я свържем към пропърти на някой backing bean и да манипулираме данните от там.

- Имате нужда да преобразувате, валидирате данните на компонентата. В такъв случай се използват конвертери и валидатори.

В общия случай, при създаването на потребителски компоненти се налага създаване на три част: компонентен клас (UIComponent) представящ модела на компонента (с този клас може да се bind-ва), рендерер определящ изгледа на компонентата и таг свързващ компонентата с рендерера и.

Естествено е възможно да използваме готова UI компонента, като сменим само рендерера (можем да добавим JavaScript функционалност).

За демонстрация ще създадем компонента, представляваща линк за изпращане на електронна поща (mailto:).

Първата стъпка е създаване на UIComponent клас:



public class UIOutputEMail extends UIComponentBase

HTML компонентата има два атрибута – email и label. Email указва адреса, към който ще сочи линка, label показва текста на линка. За да може модела да отговаря на визуалната част създаваме две пропъртита и съответните им гетери и сетери:

public class UIOutputEMail extends UIComponentBase{

private String email = null;

private String label = null;



За примера няма да използваме отделен рендерер, а ще дефинираме рендерирането на компонентата в UI класа. За тази цел правил следните неща:

public UIOutputEMail(){

super();

setRendererType(null);

}

public String getFamily() {

return null;

}

И имплементираме метода encodeBegin:

public void encodeBegin(FacesContext context) throws IOException {

ResponseWriter writer = context.getResponseWriter();

writer.startElement("a", this);

writer.writeAttribute("href", "mailto:"+getEmail(), "email");

writer.writeText(getLabel(), "label");

writer.endElement("a");

}

Следващата стъпка е създаването на таг класс, който свързва UI класа с евентуалния рендерер и с дефиницията на тага в tld схемата:

public class OutputEMailTag extends UIComponentELTag

Добавяме съответно двата атрибута email и label и техните модификатори. Имплементираме метода setProperties, в който попълваме UI компонентата:

protected void setProperties(UIComponent component) {

super.setProperties(component);

UIOutputEMail emailComponent = (UIOutputEMail) component;

if(null != email){

emailComponent.setEmail(email);

}

if(null != label){

emailComponent.setLabel(label);

}

}

Имплементираме двата метода за връзска с компонентата и с рендерера:

public String getComponentType() {

return UIOutputEMail.COMPONENT_TYPE;

}

public String getRendererType() {

return null;

}

Където UIOutputEMail.COMPONENT_TYPE е със стойност "com.dreamix.jsf.OutputEMail" и има за цел да идентифицира уникално компонентата.

Изготвяме tld схема за тага, който ще използваме в JSP страницата:





1.0

1.2

dreamix


outputEMail

com.dreamix.jsf.custom.OutputEMailTag

empty



Сподели с приятели:




©obuch.info 2024
отнасят до администрацията

    Начална страница