Tapestry 5 preview release
Er is net een preview release beschikbaar van Tapestry 5 (http://tapestry.apache.org/tapestry5/) die er veelbelovend uitziet. Deze versie (5.0.1) laat veel verbeteringen zien waaruit blijkt dat er goed is gekeken naar bijvoorbeeld Ruby on Rails en naar Wicket.
Tapestry is een webframework dat uitgaat van HTML bij het ontwerpen van je webpagina (geen taglibs) en waarbij de componenten worden geschreven in java classes.
Nieuw
Hier een overzicht van de vernieuwende features:
- Eenvoudige API die is gebaseerd op annotaties.
- Geen base class nodig waarvan je moet extenden; components zijn echte Pojos.
- Geen abstracte classes meer, waardoor ze beter testbaar worden.
- Vriendelijke URLs.
- Geen XML descriptors voor pagina’s en componenten. Alleen nog maar annotaties.
- Automatisch herladen van templates en zelfs van Java classes!
- Ajax integratie met Dojo.
- Eenvoudig unit testen van pagina’s en componenten.
Als je met Tapestry 3 als 4 hebt gewerkt is het al snel duidelijk dat dit echt goede verbeteringen zijn.
Webpagina’s werden altijd beschreven met abstracte classes waardoor ze in de praktijk ontestbaar werden. Verder werden er op basis van configuratie bestanden runtime implementaties gemaakt van de abstracte pagina’s met als gevolg dat fouten in de configuratie ook pas runtime aan het licht kwamen. Deze “problemen�? zijn nu allemaal opgelost met Tapestry 5.
Maar de meest in het oog springende verbetering is wel het automatisch herladen van HTML templates en java classes. Na het opnieuw compileren van de sources is een refresh in je browser voldoende om de aangepaste class opnieuw te laden. Dat is pas echt een productieverhogende toevoeging in de stijl van Ruby on Rails.
Voorbeeld
En om te laten zien hoe eenvoudig een simpel Login scherm kan worden gebouwd, hier een voorbeeld.
<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> <head> <title>Tapestry 5 Login formulier</title> </head> <body> <form t:id="form" t:type="Form"> <t:comp type="Errors"/> <label t:type="Label" for="userName"/>: <input t:type="TextField" t:id="userName" t:validate="required,minlength=3" size="30"/> <br/> <label t:type="Label" for="password"/>: <input t:type="PasswordField" t:id="password" t:validate="required,minlength=3" size="30"/> <br/> <input type="submit" value="Login"/> </form> </body> </html>
In het Login.html bestand hierboven kun je zien dat er een formulier wordt gedefinieerd door met html attribuut t:type het type te definiëren. In dit geval: t:type=”Form”.
Dit component moet beschikbaar zijn in de Login.java pagina class door een member van het type Form te declareren en te markeren als een component:
@Component private Form _form
Verder worden er in de Login.html pagina componenten gedeclareerd van het type TextField en PasswordField waaraan een id wordt gekoppeld. Dit id verwijst naar een javabean property. In dit geval moeten er properties zijn voor userName en password in de Login class.
En als laatste moet de submit van het formulier worden gekoppeld aan de class. Die wordt gedaan op basis van de value=�?Login�?. In de Login class moet er een methode doLogin() zijn die een OnEvent annotatie heeft.
[code]@OnEvent(”submit”)
private Object doLogin()
[/code]
De hele pagina class Login.java ziet er nu als volgt uit:
/** * Voorbeeld login pagina waarin op * username/password wordt gecontroleerd. */ @ComponentClass public class Login { @Persist private String _userName; private String _password; @Component private Form _form; // Op de Login.html pagina wordt dit component // als volgt gedefinieerd: // <form t:id="form" t:type="Form"> @InjectPage private Start _startPage; // Na een succesvolle login, springen we naar een startpagina. // Die wordt hier geïnjecteerd. @OnEvent("submit") private Object doLogin() { // De inlog actie wordt hier afgehandeld door de annotatie // OnEvent te gebruiken. // In de HTML code wordt deze actie als volgt gekoppeld: // <input type="submit" value="Login"/> if ("rudie".equals(_userName)) { // Redirect naar de geïnjecteerde startpagina. return _startPage; } // Validatie fout, dus blijf op de pagina en // plaats een foutboodschap. _formulier.recordError("Ongeldig gebruikersnaam of wachtwoord."); return null; } public String getUserName() { return _userName; } public String getPassword() { return _password; } public void setUserName(String userId) { _userName = userId; } public void setPassword(String password) { _password = password; } }
Configuratie
Om nu de tapestry 5 applicatie te configureren is er enkel een eenvoudige web.xml nodig. Deze ziet er als volgt uit.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>myapp Tapestry 5 Application</display-name> <context-param> <param-name>tapestry.app-package</param-name> <param-value>org.example.myapp</param-value> </context-param> <filter> <filter-name>app</filter-name> <filter-class>org.apache.tapestry.TapestryFilter</filter-class> </filter> <filter-mapping> <filter-name>app</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Door de URL http://domain/myapp/login in een browser te openen wordt de login pagina gestart.
Configuratie is dus erg eenvoudig.
Conclusie
Tapestry 5 is zeer veelbelovend en zeker een webframework om in de gaten te houden. Op dit moment is het echter nog wel echt een preview release, wat betekent dat er nog nauwelijks documentatie is. Om er mee aan de slag te gaan, zijn de test sources het beste om mee te beginnen.



Goed verhaal Rudie,
ben benieuwd hoe Tapestry 5 zich verder gaat ontwikkelen. Op het eerste gezicht ziet het er veelbelovend en vooral ook erg productief uit. Jammer dat ze overal Maven voor gebruiken, maar dat is persoonlijk :o)
mvg,
Onno
Onno - februari 19, 2007 11:15
Leuk om dit eens te vergelijken met Wicket
* Eenvoudige API die is gebaseerd op annotaties.
In Wicket heb je zowiezo geen annotaties nodig. Zie http://chillenious.wordpress.com/2006/08/01/does-wicket-need-ajax-annotations/.
* Geen base class nodig waarvan je moet extenden; components zijn echte Pojos.
Models hebben in Wicket nooit een base class gehad. Componenten zijn wel altijd een subclass van wicket.Component. Maar omdat Wicket niet bepaalt wanneer componenten worden geïnstantieerd, heb ik hier nooit veel last van gehad.
* Geen abstracte classes meer, waardoor ze beter testbaar worden.
Ik ken Tapestry niet goed genoeg om hier iets nuttigs over te zeggen. In Wicket worden alle componenten en models door de programmeur geïnstantieerd. Dit zijn dus nooit abstract classes.
* Vriendelijke URLs.
In Wicket kun je je eigen URL parser/writer schrijven.
* Geen XML descriptors voor pagina’s en componenten. Alleen nog maar annotaties.
In Wicket: alleen maar java code, geen XML (behalve web.xml), geen annotaties.
* Automatisch herladen van templates en zelfs van Java classes!
Dit zal in Tapestry iets gemakkelijker gaan omdat Tapestry componenten beheerd. Echter, als ik Wicket in debug mode draait vanuit Eclipse mbv Jetty, is het mogelijk om kleine veranderingen te maken in java code welke werken zonder herstart. Html files en andere resources veranderen is nooit een probleem zolang je in development mode draait.
* Ajax integratie met Dojo.
Wicket heeft een eigen Ajax library, maar heeft ook extenties voor Dojo en Prototype. Er wordt gewerkt aan YUI integratie. Er bestaat ook een heel mooi component voor Google Maps.
* Eenvoudig unit testen van pagina’s en componenten.
Dit is altijd al mogelijk geweest in Wicket. Voor het grotere werk zoals regressie testen blijft het handiger (ook bij Tapestry) om Selenium te gebruiken.
Goed om te zien dat Tapestry competitie blijft voor Wicket.
Veel plezier,
Erik.
Erik van Oosten - februari 19, 2007 12:48
Bedankt voor het aardige voorbeeld. Ik gebruik inmiddels T5.0.5, en dan dien je een paar kleine zaken aan te passen:
- In Login.java moet je _formulier.error… etc vervangen door _form.error…
- In Login.html werkte t:Border niet (titel), noch t:Comp. De eerste heb ik verwijderd, de tweede heb ik vervangen door een label, en dan werkt het wel weer.
Ik hoop dat je in de toekomst nog andere voorbeelden kunt tonen!
Bvd
Erik
Erik Vullings - juni 9, 2007 20:30