Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MoroSystems na ostravském CZJUGu o Apache Wicket

2,479 views

Published on

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

Published in: Education
  • Be the first to comment

  • Be the first to like this

MoroSystems na ostravském CZJUGu o Apache Wicket

  1. 1. Apache WicketMoroSystems, s.r.o.Pavel KlobásaSenior Java Developerpavel.klobasa@morosystems.cz
  2. 2. 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
  3. 3. 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
  4. 4. Obsah Porovnání s jinými frameworky Komponenty Modely Podpora JavaScriptu a Ajaxu Jak vytvořit RIA
  5. 5. Část první: porovnání s jinými frameworky
  6. 6. Principy webových frameworků MVC Klientský fw Komponentový fwStruts, Spring MVC... Flex, GWT JSF, Tapestry, WicketServer: celá aplikace Server: REST API Server: celá aplikaceKlient: statické HTML Klient: celá aplikace Klient: statické HTMLStav v URL Stav na klientu Stav v komponentáchInternet Intranet IntranetVelká zatěž Velká zatěž Střední zatěž
  7. 7. Principy frameworků vs. AJAXMVCImplementace AJAXu jde proti principu MVC. Musíme implementovatvykreslení 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í doAJAXové odpovědi – dojde k aktualizaci fragmentu HTML stránky.Pokud fw podporuje AJAX, je jeho použití snadné.
  8. 8. 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ů
  9. 9. ...tak trochu jako Swing... ● Anonymní třídy ● Model oddělený od komponenty ● Dědičnost ● Kompozice komponent ● (Generické datové typy)
  10. 10. Část druhá:O komponentách
  11. 11. Component WebComponentHierarchie Label Imagekomponent WebMarkupContainer Link Border Form Panel FormComponent TreeGrid Button DataGrid CheckBox TabbedPanel FileUploadDalší komponenty viz téžhttp://wicket.sourceforge.net/wicket-extensions/ TextField
  12. 12. Grid
  13. 13. Ukázka šablony AddressPanel.html <html xmlns:wicket="http://wicket.apache.org/"> <body> ID komponenty <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>
  14. 14. Je to znovupoužitelná komponta, Ukázka kódu vzniklá jako kompozice komponentpublic 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")); Název komponenty odpovídá add(new TextField<String>("city").add(new IValidator(){ názvu atributu modelu 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); Anonymní třída není problém } } }); add(new CountryDropDown("country")); }}
  15. 15. IBehavior – modifikace komponentypublic 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...} Dědičnost komponent umožňuje totéž, ale IBehavior je často elegantnější...
  16. 16. IBehavior – ukázka public class Highlighter extends AbstractBehavior { @Override public void onComponentTag(Component comp,ComponentTag tag) { if (isHighlighted(component)) { tag.getAttributes().put("class","hglt"); } } private boolean isHighlighted(component){ // TODO: implement it } }
  17. 17. IVisitor 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; } }); } } - IBehavior lze opakovaně využít - jedna komponenta může mít více IBehavior
  18. 18. Spring Dependency Injectionpublic class MyComponent extends Component{ @SpringBean ProductDAO productDAO; ...}public class MyApplication extends WebApplication { public void init() { super.init(); addComponentInstantiationListener( new SpringComponentInjector(this)); } <dependency>} <groupId>org.apache.wicket</groupId> <artifactId>wicket-spring</artifactId> <version>${wicket.version}</version> </dependency>
  19. 19. Část druhá:O modelech
  20. 20. Modelpublic interface IModel<T> extends IDetachable{ T getObject(); void setObject(final T object);} Pro srovnání: Model v MVC = mapa objektů Model ve Swingu = ad hoc interface dle komponenty
  21. 21. Některé modely WicketuAbstractReadOnlyModel – jen pro čteníResourceModel – lokalizace textůCompoundPropertyModel – jméno atributu=jméno komponentyIChainingModel – zřetězení modelůLoadableDetachableModel – odpojení neserializovatelných objektů
  22. 22. Triviální model Tato implementace je součástí Wicketu: 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; } }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?
  23. 23. „Počítaný“ modelpublic 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...
  24. 24. Model napojený na DAOpublic class OrderListModel extends AbstractReadOnlyModel<List<Order>> { @SpringBean transient OrderDAO dao; public LoggedUserModel(){ InjectorHolder.getInjector().inject(this); Metoda vrátí } vždy čerstvá data public List<Order> getObject() { return dao.getLoggedUserOrders(); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); InjectorHolder.getInjector().inject(this); }}
  25. 25. Část třetí:JavaScript a AJAX
  26. 26. JavaScript v komponentě 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...
  27. 27. Aktualizace komponenty AJAXem 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()); } }; požadavek vznikl na klientu, add(clockLabel); ale o tom, co se bude dít, add(new AjaxLink<Void>("refresh") { rozhodne server. private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget target) { target.addComponent(clockLabel); target.addJavascript("window.defaultStatus=" +Runtime.getRuntime().freeMemory()+""); } };
  28. 28. Část pátá: RIA
  29. 29. Rich Internet Application 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 Jak na to? Wicket na serveru a JS komponenty na klientu.
  30. 30. 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
  31. 31. Unobtrusive javascript - ukázkaHTML JS<div id="tabs"> var tabview = new Y.TabView({srcNode:#tabs}); <ul> tabview.render(); <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> Toto je ukázkový kód ze stránek YUI3. <div id="baz"> <p>baz content</p> </div> </div></div>
  32. 32. Porovnání jQuery a YUI jQuery – 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
  33. 33. Další informace:http://wicket.apache.orghttp://wicket.sourceforge.net/wicket-extensionshttp://wicketstuff.org/wicket14http://wicketstuff.org/grid-examplehttps://cwiki.apache.org/WICKET/spring.htmlhttp://developer.yahoo.com/yui/3/examples/

×