morosystems na ostravském czjugu o apache wicket

33
Apache Wicket MoroSystems, s.r.o. Pavel Klobása Senior Java Developer [email protected]

Upload: tomas-paral

Post on 08-Jul-2015

2.238 views

Category:

Education


3 download

DESCRIPTION

Pavel Klobása si pro posluchače ostravského CZJUGu připravil přednášku o Apache Wicket.

TRANSCRIPT

Page 1: MoroSystems na ostravském CZJUGu o Apache Wicket

Apache Wicket

MoroSystems, s.r.o.Pavel KlobásaSenior Java [email protected]

Page 2: MoroSystems na ostravském CZJUGu o Apache Wicket

MoroSystems, s.r.o.• Pobočky Brno a Hradec Králové• Firma s českými vlastníky• 26 zaměstnanců a externistů• Na trhu od roku 2005

Page 3: MoroSystems na ostravském CZJUGu o Apache Wicket

MoroSystems, s.r.o.• Odborný weblog VsadNaJavu.cz• Zakázkový vývoj webových aplikací,

informačních systémů a portálových řešení• Outsourcing vývoje SW nad Java/J2EE• Implementace a customizace Atlassian JIRA• Internetový startup Hráči.info

Page 4: MoroSystems na ostravském CZJUGu o Apache Wicket

Obsah

Porovnání s jinými frameworky

Komponenty

Modely

Podpora JavaScriptu a Ajaxu

Jak vytvořit RIA

Page 5: MoroSystems na ostravském CZJUGu o Apache Wicket

Část první: porovnání s jinými frameworky

Page 6: MoroSystems na ostravském CZJUGu o Apache Wicket

Principy webových frameworků

MVC Klientský fw Komponentový fwStruts, Spring MVC... Flex, GWT JSF, Tapestry, WicketServer: celá aplikaceKlient: statické HTML

Server: REST APIKlient: celá aplikace

Server: celá aplikaceKlient: statické HTML

Stav v URL Stav na klientu Stav v komponentáchInternet Intranet IntranetVelká zatěž Velká zatěž Střední zatěž

Page 7: MoroSystems na ostravském CZJUGu o Apache Wicket

Principy frameworků vs. AJAXMVCImplementace AJAXu jde proti principu MVC. Musíme implementovat vykreslení celé stránky a vykreslení fragmentu stránky zvlášť. Vzniká duplicita kódů...

Klientský fwKlient stáhne data přes REST API = základní vlastnost frameworku.

Komponentový fwKomponenty „žijí“ na serveru – můžeme je požádat o vykreslení do AJAXové odpovědi – dojde k aktualizaci fragmentu HTML stránky. Pokud fw podporuje AJAX, je jeho použití snadné.

Page 8: MoroSystems na ostravském CZJUGu o Apache Wicket

Umí tohle váš framework?● pracuje s POJO daty● lze využít generické datové typy● šablony editovatelné v běžném HTML editoru● oddělení kódu a šablon● snadné použití JavaScriptu/AJAXu● „hezké“ URL, tlačítko Zpět● podpora pro clustering● testovatelnost pomocí jednotkových testů

Page 9: MoroSystems na ostravském CZJUGu o Apache Wicket

...tak trochu jako Swing...

● Anonymní třídy● Model oddělený od komponenty● Dědičnost● Kompozice komponent● (Generické datové typy)

Page 10: MoroSystems na ostravském CZJUGu o Apache Wicket

Část druhá: O komponentách

Page 11: MoroSystems na ostravském CZJUGu o Apache Wicket

Hierarchie komponent

Component

WebComponent

WebMarkupContainer

FormBorder

Link

Panel

TreeGrid

DataGrid

TabbedPanel

FormComponent

Button

FileUpload

CheckBox

TextField

Label Image

Další komponenty viz téžhttp://wicket.sourceforge.net/wicket-extensions/

Page 12: MoroSystems na ostravském CZJUGu o Apache Wicket

Grid

Page 13: MoroSystems na ostravském CZJUGu o Apache Wicket

AddressPanel.html<html xmlns:wicket="http://wicket.apache.org/"><body><table class="edit-form"><wicket:panel><tr><th>Adresát:</th><td><input wicket:id="name" type="text" class="adr"/></td>

</tr><tr><th>Ulice:</th><td><input wicket:id="street" type="text"/></td>

</tr><tr><th>Město:</th><td><input wicket:id="city" type="text"/></td>

</tr><tr><th>Země:</th><td><select wicket:id="country"></select></td>

</tr></wicket:panel>

</table></body></html>

Ukázka šablonyID komponenty

Page 14: MoroSystems na ostravském CZJUGu o Apache Wicket

Ukázka kódupublic class AddressPanel extends Panel { private static final long serialVersionUID = 1L;

public AddressFragmentPanel(String id, IModel<Address> model) { super(id, new CompoundPropertyModel<Address>(model)); add(new TextField<String>("name").setRequired(true)); add(new TextField<String>("street")); add(new TextField<String>("city").add(new IValidator(){

public void validate(IValidatable<T> validatable){String city = (String)getDefaultModelObject();if (city == null || city.length()<2) {

ValidationError error = new ValidationError();error.setMessage("Bad city name");validatable.error(error);

}}

}); add(new CountryDropDown("country")); }}

Je to znovupoužitelná komponta,vzniklá jako kompozice komponent

Název komponenty odpovídá názvu atributu modelu

Anonymní třída není problém

Page 15: MoroSystems na ostravském CZJUGu o Apache Wicket

public interface IBehavior { void beforeRender(Component component); void afterRender(Component component); void onComponentTag(Component comp,ComponentTag tag); boolean isEnabled(Component component); …a několik dalších metod...}

IBehavior – modifikace komponenty

Dědičnost komponent umožňuje totéž, ale IBehavior je často elegantnější...

Page 16: MoroSystems na ostravském CZJUGu o Apache Wicket

public class Highlighter extends AbstractBehavior {@Overridepublic void onComponentTag(Component comp,ComponentTag tag) {

if (isHighlighted(component)) {tag.getAttributes().put("class","hglt");

}}private boolean isHighlighted(component){

// TODO: implement it}

}

IBehavior – ukázka

Page 17: MoroSystems na ostravském CZJUGu o Apache Wicket

public class HighlighterUtils {public static void prepareForms(MarkupContainer parent) {

parent.visitChildren(FormComponent.class, new IVisitor<FormComponent>(){

public Object component(FormComponent comp){comp.add(new Highlighter());return IVisitor.CONTINUE_TRAVERSAL;

}});

}}

IVisitor

- IBehavior lze opakovaně využít- jedna komponenta může mít více IBehavior

Page 18: MoroSystems na ostravském CZJUGu o Apache Wicket

public class MyComponent extends Component{@SpringBeanProductDAO productDAO;...

}public class MyApplication extends WebApplication {

public void init() {super.init();addComponentInstantiationListener(

new SpringComponentInjector(this));}

}

Spring Dependency Injection

<dependency><groupId>org.apache.wicket</groupId><artifactId>wicket-spring</artifactId><version>${wicket.version}</version>

</dependency>

Page 19: MoroSystems na ostravském CZJUGu o Apache Wicket

Část druhá: O modelech

Page 20: MoroSystems na ostravském CZJUGu o Apache Wicket

public interface IModel<T> extends IDetachable{T getObject();void setObject(final T object);

}

Model

Pro srovnání:Model v MVC = mapa objektůModel ve Swingu = ad hoc interface dle komponenty

Page 21: MoroSystems na ostravském CZJUGu o Apache Wicket

AbstractReadOnlyModel – jen pro čteníResourceModel – lokalizace textůCompoundPropertyModel – jméno atributu=jméno

komponentyIChainingModel – zřetězení modelůLoadableDetachableModel – odpojení

neserializovatelných objektů

Některé modely Wicketu

Page 22: MoroSystems na ostravském CZJUGu o Apache Wicket

public class Model<T extends Serializable> implements IModel<T> {private static final long serialVersionUID = 1L;private T object;public T getObject() {

return object;}public void setObject(final T object) {

this.object = object;}

}

Triviální modelTato implementace je součástí Wicketu:

ALE:Model musí být serializovatelný – entity serializované být nesmí

(ukládají se pouze do databáze, ne kamsi na disk/síť/cache...)Jak zajístíme vzájemnou aktualizaci dat v modelech více komponent?Jak zajistíme aktualizaci dat při změně v dB?

Page 23: MoroSystems na ostravském CZJUGu o Apache Wicket

public class CurrentTimeModel extends AbstractReadOnlyModel<String> {

public String getObject() {SimpleDateFormat fmt=new SimpleDateFormat("d.M. hh:mm");return fmt.format(new Date());

}}

Volat metodu je často výhodnější, než uchovávat datový obsah.Můžeme takto rovnou volat DAO...

„Počítaný“ model

Page 24: MoroSystems na ostravském CZJUGu o Apache Wicket

public class OrderListModel extends AbstractReadOnlyModel<List<Order>> { @SpringBean transient OrderDAO dao; public LoggedUserModel(){ InjectorHolder.getInjector().inject(this); } public List<Order> getObject() { return dao.getLoggedUserOrders(); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); InjectorHolder.getInjector().inject(this); }}

Metoda vrátí vždy čerstvá data

Model napojený na DAO

Page 25: MoroSystems na ostravském CZJUGu o Apache Wicket

Část třetí: JavaScript a AJAX

Page 26: MoroSystems na ostravském CZJUGu o Apache Wicket

public class HTMLEditor extends TextArea<String>{ @Override protected void onAfterRender() { super.onAfterRender(); getResponse().write(JavascriptUtils.SCRIPT_OPEN_TAG); getResponse().write("makeTinyMCE('" + getMarkupId() + "');"); getResponse().write(JavascriptUtils.SCRIPT_CLOSE_TAG); }}

Upozornění: toto je jen ilustrační příklad...

JavaScript v komponentě

Page 27: MoroSystems na ostravském CZJUGu o Apache Wicket

Label clockLabel=new Label("clock", new AbstractReadOnlyModel<String>() {private static final long serialVersionUID = 1L;public String getObject() {

SimpleDateFormat fmt=new SimpleDateFormat("d.M. hh:mm:ss");return fmt.format(new Date());

}};add(clockLabel);

add(new AjaxLink<Void>("refresh") {private static final long serialVersionUID = 1L;@Overridepublic void onClick(AjaxRequestTarget target) {

target.addComponent(clockLabel);target.addJavascript("window.defaultStatus='"

+Runtime.getRuntime().freeMemory()+"'");}

};

Aktualizace komponenty AJAXem

požadavek vznikl na klientu, ale o tom, co se bude dít,

rozhodne server.

Page 28: MoroSystems na ostravském CZJUGu o Apache Wicket

Část pátá: RIA

Page 29: MoroSystems na ostravském CZJUGu o Apache Wicket

Aplikace běží v prohlížeči a na webovém serveru (=nulové náklady na instalaci na klientech)

Napodobuje GUI klient-server aplikace● ovládání: drag&drop, kontextové menu, ukládání stavu

GUI mezi sezeními...● pokročilé komponenty: datový grid, pulldown menu,

autocomplete...● složitý, často dynamický, layout aplikace

Rich Internet Application

Jak na to? Wicket na serveru a JS komponenty na klientu.

Page 30: MoroSystems na ostravském CZJUGu o Apache Wicket

Unobtrusive javascript

Nevtíravý javascript ● chceme, aby javascript byl „přidanou

hodnotou“ a aplikace fungovala i bez něj● je to best practice pro klasické webové stránky● užitečný koncept pro napojení serverového

komponentového frameworku a klientských javascriptových komponent

Page 31: MoroSystems na ostravském CZJUGu o Apache Wicket

Unobtrusive javascript - ukázkaHTML<div id="tabs"> <ul> <li><a href="#foo">foo</a></li> <li><a href="#bar">bar</a></li> <li><a href="#baz">baz</a></li> </ul> <div> <div id="foo"> <p>foo content</p> </div> <div id="bar"> <p>bar content</p> </div> <div id="baz"> <p>baz content</p> </div> </div></div>

JSvar tabview = new Y.TabView({srcNode:'#tabs'});tabview.render();

Toto je ukázkový kód ze stránek YUI3.

Page 32: MoroSystems na ostravském CZJUGu o Apache Wicket

Porovnání jQuery a YUIjQuery– populární a známý v ČR– krátké, čitelné, elegatní kódy

Komponenty v jQuery od různých autorů– rozdílné API, rozdílné licence, nejednotná grafika

YUI – používají též velké firmy (eBay, Yahoo)– „nudné“ API

Komponenty v YUI jsou součástí fw– podobné API, stejná grafika

Page 33: MoroSystems na ostravském CZJUGu o Apache Wicket

http://wicket.apache.orghttp://wicket.sourceforge.net/wicket-extensionshttp://wicketstuff.org/wicket14http://wicketstuff.org/grid-example https://cwiki.apache.org/WICKET/spring.htmlhttp://developer.yahoo.com/yui/3/examples/

Další informace: