geliftete web-applikation mit scala - tobias joch - inovex gmbh
Post on 10-Nov-2014
2.195 Views
Preview:
DESCRIPTION
TRANSCRIPT
GeLiftete Web-Applikation mit Scala
JAX 2009
Tobias Jochinovex GmbH
Wir nutzen Technologien, um unsere Kunden glücklich zu machen. Und uns selbst.
2
ScalaLift
GrundlagenArchitektur ÜberblickModuleTemplate VerarbeitungTags und SnippetsHead MergeScopesI18nPersistenzAJAX
in ActionFazit / Ausblick / weiterführende Informationen
3
4
Scala = SCAlable LAnguage
4
wächst mit den Bedürfnissen der Userkleine Skripte bis hin zu großen und komplexen SystemenMultiparadigmensprache
verbindet objektorientierte (imperative) und funktionale Programmierung
pragmatisch, typsicher, strikt objektorientiertinteroperabel mit Standard Plattformen (Java, .NET)
Scala = SCAlable LAnguage
5
Wurzeln reichen zurück in das Jahr 1995Philip Wadler und Martin Odersky
Funktionale Programmiersprachen für die JVMPizzaGJ (Generic Language Extension für Java)javacJava Generics
1999 verfolgte Martin Odersky das Ziel funktionale mit OO Programmierung zu kombinieren
FunnelScala
*2001, 2003 erstes Public Release, 2006 Version 2.0, aktuell 2.7.4 RC1
Ziel von Scala:Das Beste aus beiden Welten (OO und FP)
Statisch typisiert + TypinferenzFunktionen höherer OrdnungTraits, Mixin-KompositionOption-Klasse (None und Some vs. null)Pattern MatchingAlgebraische TypenNative XML-Unterstützung inkl. XPath Unterstützung (Bibliothek)Actor ModelCurryingAnonyme FunktionenParametrische Polymorphie 6
Einige reservierte Schlüsselwörter in Scalaclass, case class, objectnew withextends abstract sealedtraitdef, var, valoverridematch, case
7
8
in Action ;)
Scala ShellInteractive Ruby Shell (IRB) ./scalaOptimal für schnelle Tests
9
Scala ShellInteractive Ruby Shell (IRB) ./scalaOptimal für schnelle Tests
9
Scala ShellInteractive Ruby Shell (IRB) ./scalaOptimal für schnelle Tests
9
10
Imperative vs. funktionale Programmierung (I)
public class Example1 { public static void main(String[] args) { for (String arg : args) { System.out.println(arg); } }}
10
Imperative vs. funktionale Programmierung (I)
object Example1 {def main(args: Array[String]) {
args.foreach(println)}
}
public class Example1 { public static void main(String[] args) { for (String arg : args) { System.out.println(arg); } }}
11
Imperative vs. funktionale Programmierung (II)public class Example2 { public static void main(String[] args) { for (String arg : args) { if (arg.startsWith("JAX09")) { System.out.println(arg); } } }}
11
Imperative vs. funktionale Programmierung (II)
object Example2 { def main(args: Array[String]) { args.filter(_.startsWith("JAX09")).foreach(println) }}
public class Example2 { public static void main(String[] args) { for (String arg : args) { if (arg.startsWith("JAX09")) { System.out.println(arg); } } }}
12
Imperative vs. funktionale Programmierung (III)public class Example3 { public static void main(String[] args) { boolean exists = false; for (String arg : args) { if (arg.startsWith("JAX09")) { exists = true; break; } } System.out.print(exists); }}
12
Imperative vs. funktionale Programmierung (III)
object Example3 { def main(args: Array[String]) { print(args.exists(_.startsWith("JAX09"))) }}
public class Example3 { public static void main(String[] args) { boolean exists = false; for (String arg : args) { if (arg.startsWith("JAX09")) { exists = true; break; } } System.out.print(exists); }}
13
Grundlagen
David PollakGründer von LiftKommerzielle Softwareentwicklung seit 1977Web-Applikationen seit 1996
15. Februar 2007:Initial Import (GitHub) in der Version 0.1.0Gründung von Lift als OS Projekt in 200726. Februar 2009:Lift 1.0Aktuelles Lift-Team besteht aus 13 ComitterAktive Community
http://groups.google.com/group/liftweb 14
„Best of all“Scala als zugrundeliegende Sprache
nativer XML-Support (XHTML nativ innerhalb von Snippets!)Scala Actors für mächtige Comet-Anwendungen
fein granulare Sessions und Security (Seaside)schnelles Projektsetup durch „convention over configuration“ + geringe Turnaround-Zeiten (Rails)Django's "more than just CRUD is included"Designer freundliche Templates (Wicket / Lift View First)Offen für die Nutzung von zahlreichen OSS-Bibliotheken (Java)Etablierte Deployment-Prozesse (JEE / Java) 15
Weitere Eigenschaften / Ziele von LiftSicherheit
XSS, replay Attacken, Parameter tamperingWartbarkeitSkalierbarkeitPerformanceHohe ProduktivitätEinfachConvention over configurationDRY
16
„View First“ Design-PrinzipTemplates enthalten keinen CodePures XHTMLKönnen mit Standard Design-Werkzeugen bearbeitet werdenFrontend ist ohne Scala-Kenntnisse von einem Designer realisierbar
17
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
18
Architektur Überblick
Lift-Framework
19
Lift-Framework
19Scala Framework
Lift-Framework
19Scala Framework
Lift-Framework
Lift-Framework
19Scala Framework
Lift-Framework
Lift Core
Lift-Framework
19Scala Framework
Lift-Framework
Lift Core
Lift Webkit
Com
et
SH
tml
S
LiftR
ule
s
LiftS
essio
n
JS
AP
I
SiteM
ap
Menu, M
sgs,
CS
S
HT
TP
Auth
LiftR
esponse
Lift-Framework
19Scala Framework
Lift-Framework
Lift Core
Lift Webkit
Com
et
SH
tml
S
LiftR
ule
s
LiftS
essio
n
JS
AP
I
SiteM
ap
Menu, M
sgs,
CS
S
HT
TP
Auth
LiftR
esponse
Mapper Record
Lift-Framework
19Scala Framework
Lift-Framework
Lift Core
Lift Webkit
Com
et
SH
tml
S
LiftR
ule
s
LiftS
essio
n
JS
AP
I
SiteM
ap
Menu, M
sgs,
CS
S
HT
TP
Auth
LiftR
esponse
Mapper Record Testkit
Lift-Framework
19Scala Framework
Lift-Framework
Lift Core
Lift Webkit
Com
et
SH
tml
S
LiftR
ule
s
LiftS
essio
n
JS
AP
I
SiteM
ap
Menu, M
sgs,
CS
S
HT
TP
Auth
LiftR
esponse
Mapper Record Testkit
Lift Util
Lift-Framework
19Scala Framework
Lift-Framework
Lift Core
Lift Webkit
Com
et
SH
tml
S
LiftR
ule
s
LiftS
essio
n
JS
AP
I
SiteM
ap
Menu, M
sgs,
CS
S
HT
TP
Auth
LiftR
esponse
Mapper Record Testkit
Lift Util
Lift XMPP
Lift Facebook
Lift Widgets
Lift OpenId
Lift OAuth
Lift Paypal
Lift AMQP
Grobe Architektur einer Lift-Applikation
20
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Lift Framework
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Templates
Lift Framework
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Templates
Snippets
Lift Framework
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Templates
Views
Snippets
Lift Framework
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Templates
Views
Snippets
Boot.scala (LiftRules etc,)
Lift Framework
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Templates
Views
Snippets
Boot.scala (LiftRules etc,)
Model
Lift Framework
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Templates
Views
Snippets
Boot.scala (LiftRules etc,)
LiftFilter Model
Lift Framework
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Templates
Views
Snippets
Boot.scala (LiftRules etc,)
LiftServlet
LiftFilter Model
Lift Framework
Java Virtual Machine
Grobe Architektur einer Lift-Applikation
20
Servlet Container (e.g. Jetty or Tomcat)
Templates
Views
Snippets
Boot.scala (LiftRules etc,)
LiftServlet
LiftFilter Model
Lift Framework
DefaultServlet
Grober Ablauf einer Anfragenbearbeitung
21
Request URL rewrite View Responsecustom dispatch
Response
Response
ResponseTemplate
Grober Ablauf einer Anfragenbearbeitung
21
Request URL rewrite View Responsecustom dispatch
Response
Response
Response
Template
Template VerarbeitungRequest Mapping nach folgendem Schema
22
Template
Template VerarbeitungRequest Mapping nach folgendem Schema
22
<path>[_<language, optional>][.<suffix>]
Template
Template VerarbeitungRequest Mapping nach folgendem Schema
22
<path>[_<language, optional>][.<suffix>]
Lift wählt die passende Sprache und Endung
Template
Template VerarbeitungRequest Mapping nach folgendem Schema
22
<path>[_<language, optional>][.<suffix>]
Lift wählt die passende Sprache und EndungLinks ohne Sprache und Endung angeben
Template
Template VerarbeitungRequest Mapping nach folgendem Schema
22
<path>[_<language, optional>][.<suffix>]
Lift wählt die passende Sprache und EndungLinks ohne Sprache und Endung angeben
Lift versteckt Templates und Ressourcen in Verzeichnissen welche als Endung -hidden im Namen tragen
Template
Template VerarbeitungRequest Mapping nach folgendem Schema
22
<path>[_<language, optional>][.<suffix>]
Lift wählt die passende Sprache und EndungLinks ohne Sprache und Endung angeben
Lift versteckt Templates und Ressourcen in Verzeichnissen welche als Endung -hidden im Namen tragen
Template
23
Template
Templates = Content + Tags + Snippets
23
Template
Templates = Content + Tags + SnippetsTags = Lift spezifische Funktionen
surroundbindembedcometloc
23
Template
Templates = Content + Tags + SnippetsTags = Lift spezifische Funktionen
surroundbindembedcometloc
Snippetsvergleichbar mit Taglibs<lift:snippet type=Jax:render /> <lift:Jax.render /> <lift:Jax /> 23
Template
›
24
Template Verarbeitung von Außen nach Innen
Template
›
24
Template Verarbeitung von Außen nach Innen
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:HelloWorld.howdy /></p> </lift:surround>
/index.html
Template
›
24
Template Verarbeitung von Außen nach Innen
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:HelloWorld.howdy /></p> </lift:surround>
/index.html
/templates-hidden/default.html
<html xmlns="..." xmlns:lift="http://liftweb.net/"> <head>...</head> <body>
...<lift:bind name="content" />
</body></html>
Template
›
24
Template Verarbeitung von Außen nach Innen
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:HelloWorld.howdy /></p> </lift:surround>
/index.html
/templates-hidden/default.html
<html xmlns="..." xmlns:lift="http://liftweb.net/"> <head>...</head> <body>
...<lift:bind name="content" />
</body></html>
Ausführung von HelloWorld#howdy
Template
25
Head Merge
Template
25
Head Merge
Template
<lift:surround with="default" at="content"> <head><script type="text/javascript">...</script>...</head> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p></lift:surround>
/index.html
25
Head Merge
Template
<lift:surround with="default" at="content"> <head><script type="text/javascript">...</script>...</head> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p></lift:surround>
/index.html
/templates-hidden/default.html
<html xmlns="..." xmlns:lift="http://liftweb.net/"> <head>...</head> <body>
...<lift:bind name="content" />
</body></html>
25
Head Merge
Template
<lift:surround with="default" at="content"> <head><script type="text/javascript">...</script>...</head> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p></lift:surround>
/index.html
/templates-hidden/default.html
<html xmlns="..." xmlns:lift="http://liftweb.net/"> <head>...</head> <body>
...<lift:bind name="content" />
</body></html>
ScopesSStateful SnippetRequestVarSessionVarScala Object (Singleton)
26
Internationalisierung / I18njava.util.Localejava.util.ResourceBundle
LiftRules.resourceNames
Ermittlung der aktuellen SpracheLiftRules.localeCalculator
Request-HeaderFallback: Locale.getDefault()
SnippetsS.?
Templates
27
<lift:loc locid="lift">Aufzug</lift:loc><lift:loc>lift</lift:loc>
Persistenz in LiftMapperRecordJPAJDOHibernate...
Lift selbst ist Persistenz agnostisch
28
AJAX in LiftSHtml
ajaxButtonajaxTextajaxCheckbox...
29
def render(in: NodeSeq): NodeSeq =SHtml.ajaxButton("Click me ;)", () => {
println("Yes, thanks!") JsCmds.SetHtml("click-div", Text("Yes, thanks!"))
})
30
in Action ;)
EntwicklungsumgebungJava (>= 5)Maven (>= 2.0.9)Web-Container (Jetty, Tomcat, ...)
Optional, aber nützlichJavaRebel (JVM Plugin / Java Agent)IDE mit Scala Support / Plugin (Eclipse, IDEA, Netbeans, ...)
http://www.scala-lang.org/scala-eclipse-plugin
31
32
Projekt anlegen
32
Projekt anlegen
$mvn archetype:generate -U -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-basic -DarchetypeVersion=1.0 -DgroupId=de.inovex.jax2009.lift -DartifactId=lift-demo
32
Projekt anlegen
$mvn archetype:generate -U -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-basic -DarchetypeVersion=1.0 -DgroupId=de.inovex.jax2009.lift -DartifactId=lift-demo
$cd lift-demo && mvn eclipse:eclipse
Import in Eclipse vorbereiten
33
Projektlayout
33
Projektlayout
33
Projektlayout
34
Ausführen
34
Ausführen
$mvn jetty:run
34
Ausführen
$mvn jetty:run
35
index.html
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
HelloWorld.scala
import java.util.Date
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date}</span> }
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
HelloWorld.scala
import java.util.Date
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date}</span> }
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
HelloWorld.scala
import java.util.Date
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date}</span> }
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
HelloWorld.scala
import java.util.Date
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date}</span> }
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
HelloWorld.scala
import java.util.Date
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date}</span> }
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
HelloWorld.scala
import java.util.Date
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date}</span> }
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
HelloWorld.scala
import java.util.Date
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date}</span> }
<lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround>
35
index.html
HelloWorld.scala
36
default.html
<div class="container"> <div class="column span-12 last" style="text-align: right"> <h1 class="alt">lift-demo <img id="ajax-loader" style="display:none; margin-bottom: 0px; margin-left: 5px" src="/images/ajax-loader.gif"/></h1> </div> <hr/> <div class="column span-6 colborder sidebar"> <hr class="space" /> <lift:Menu.builder /> <div> <lift:snippet type="msgs"/> <hr class="space" /> </div> </div> <div class="column span-17 last"> <lift:bind name="content" /> </div> <hr /> <div class="column span-23 last" style="text-align: center"> <h4 class="alt"> <a href="http://liftweb.net"><i>Lift</i></a> is Copyright 2007-2009 WorldWide Conferencing, LLC. Distributed under an Apache 2.0 License.</h4> </div> </div> 36
default.html
<div class="container"> <div class="column span-12 last" style="text-align: right"> <h1 class="alt">lift-demo <img id="ajax-loader" style="display:none; margin-bottom: 0px; margin-left: 5px" src="/images/ajax-loader.gif"/></h1> </div> <hr/> <div class="column span-6 colborder sidebar"> <hr class="space" /> <lift:Menu.builder /> <div> <lift:snippet type="msgs"/> <hr class="space" /> </div> </div> <div class="column span-17 last"> <lift:bind name="content" /> </div> <hr /> <div class="column span-23 last" style="text-align: center"> <h4 class="alt"> <a href="http://liftweb.net"><i>Lift</i></a> is Copyright 2007-2009 WorldWide Conferencing, LLC. Distributed under an Apache 2.0 License.</h4> </div> </div> 36
default.html
<div class="container"> <div class="column span-12 last" style="text-align: right"> <h1 class="alt">lift-demo <img id="ajax-loader" style="display:none; margin-bottom: 0px; margin-left: 5px" src="/images/ajax-loader.gif"/></h1> </div> <hr/> <div class="column span-6 colborder sidebar"> <hr class="space" /> <lift:Menu.builder /> <div> <lift:snippet type="msgs"/> <hr class="space" /> </div> </div> <div class="column span-17 last"> <lift:bind name="content" /> </div> <hr /> <div class="column span-23 last" style="text-align: center"> <h4 class="alt"> <a href="http://liftweb.net"><i>Lift</i></a> is Copyright 2007-2009 WorldWide Conferencing, LLC. Distributed under an Apache 2.0 License.</h4> </div> </div> 36
default.html
<div class="container"> <div class="column span-12 last" style="text-align: right"> <h1 class="alt">lift-demo <img id="ajax-loader" style="display:none; margin-bottom: 0px; margin-left: 5px" src="/images/ajax-loader.gif"/></h1> </div> <hr/> <div class="column span-6 colborder sidebar"> <hr class="space" /> <lift:Menu.builder /> <div> <lift:snippet type="msgs"/> <hr class="space" /> </div> </div> <div class="column span-17 last"> <lift:bind name="content" /> </div> <hr /> <div class="column span-23 last" style="text-align: center"> <h4 class="alt"> <a href="http://liftweb.net"><i>Lift</i></a> is Copyright 2007-2009 WorldWide Conferencing, LLC. Distributed under an Apache 2.0 License.</h4> </div> </div> 36
default.html
<div class="container"> <div class="column span-12 last" style="text-align: right"> <h1 class="alt">lift-demo <img id="ajax-loader" style="display:none; margin-bottom: 0px; margin-left: 5px" src="/images/ajax-loader.gif"/></h1> </div> <hr/> <div class="column span-6 colborder sidebar"> <hr class="space" /> <lift:Menu.builder /> <div> <lift:snippet type="msgs"/> <hr class="space" /> </div> </div> <div class="column span-17 last"> <lift:bind name="content" /> </div> <hr /> <div class="column span-23 last" style="text-align: center"> <h4 class="alt"> <a href="http://liftweb.net"><i>Lift</i></a> is Copyright 2007-2009 WorldWide Conferencing, LLC. Distributed under an Apache 2.0 License.</h4> </div> </div> 36
default.html
<div class="container"> <div class="column span-12 last" style="text-align: right"> <h1 class="alt">lift-demo <img id="ajax-loader" style="display:none; margin-bottom: 0px; margin-left: 5px" src="/images/ajax-loader.gif"/></h1> </div> <hr/> <div class="column span-6 colborder sidebar"> <hr class="space" /> <lift:Menu.builder /> <div> <lift:snippet type="msgs"/> <hr class="space" /> </div> </div> <div class="column span-17 last"> <lift:bind name="content" /> </div> <hr /> <div class="column span-23 last" style="text-align: center"> <h4 class="alt"> <a href="http://liftweb.net"><i>Lift</i></a> is Copyright 2007-2009 WorldWide Conferencing, LLC. Distributed under an Apache 2.0 License.</h4> </div> </div> 36
default.html
37
Boot.scala
37
Boot.scala def boot { if (!DB.jndiJdbcConnAvailable_?) DB.defineConnectionManager(DefaultConnectionIdentifier, DBVendor)
// where to search snippet LiftRules.addToPackages("de.inovex.jax2009.lift") // create or update the database schema Schemifier.schemify(true, Log.infoF _, User)
// build site map val entries = Menu(Loc("Home", List("index"), "Home")) :: User.sitemap LiftRules.setSiteMap(SiteMap(entries:_*))
// Show the spinny image when an Ajax call starts LiftRules.ajaxStart = Full(() => LiftRules.jsArtifacts.show("ajax-loader").cmd)
// Make the spinny image go away when it ends LiftRules.ajaxEnd = Full(() => LiftRules.jsArtifacts.hide("ajax-loader").cmd)
// force the request to be UTF-8 LiftRules.early.append(makeUtf8)
S.addAround(DB.buildLoanWrapper) }
38
Rekursive Template Komposition
38
Rekursive Template Komposition
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date} at <lift:helloWorld.howdy2 /></span> def howdy2 = <span>JAX 2009!</span> }
38
Rekursive Template Komposition
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date} at <lift:helloWorld.howdy2 /></span> def howdy2 = <span>JAX 2009!</span> }
38
Rekursive Template Komposition
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date} at <lift:helloWorld.howdy2 /></span> def howdy2 = <span>JAX 2009!</span> }
38
Rekursive Template Komposition
class HelloWorld { def howdy = <span>Welcome to lift-demo at {new Date} at <lift:helloWorld.howdy2 /></span> def howdy2 = <span>JAX 2009!</span> }
39
Formulare <lift:surround with="default" at="content">
<h2>Very first form example:</h2> <p> <lift:FormExample form="POST"> <f:name><input type="text"/></f:name> <input type="submit" value="Post"/> </lift:FormExample> </p> </lift:surround>
39
Formulare <lift:surround with="default" at="content">
<h2>Very first form example:</h2> <p> <lift:FormExample form="POST"> <f:name><input type="text"/></f:name> <input type="submit" value="Post"/> </lift:FormExample> </p> </lift:surround>
class FormExample { def render(xhtml: NodeSeq) = { bind("f", xhtml, "name" -> text("", println(_))) } }
39
Formulare <lift:surround with="default" at="content">
<h2>Very first form example:</h2> <p> <lift:FormExample form="POST"> <f:name><input type="text"/></f:name> <input type="submit" value="Post"/> </lift:FormExample> </p> </lift:surround>
class FormExample { def render(xhtml: NodeSeq) = { bind("f", xhtml, "name" -> text("", println(_))) } }
39
Formulare <lift:surround with="default" at="content">
<h2>Very first form example:</h2> <p> <lift:FormExample form="POST"> <f:name><input type="text"/></f:name> <input type="submit" value="Post"/> </lift:FormExample> </p> </lift:surround>
class FormExample { def render(xhtml: NodeSeq) = { bind("f", xhtml, "name" -> text("", println(_))) } }
39
Formulare <lift:surround with="default" at="content">
<h2>Very first form example:</h2> <p> <lift:FormExample form="POST"> <f:name><input type="text"/></f:name> <input type="submit" value="Post"/> </lift:FormExample> </p> </lift:surround>
class FormExample { def render(xhtml: NodeSeq) = { bind("f", xhtml, "name" -> text("", println(_))) } }
39
Formulare <lift:surround with="default" at="content">
<h2>Very first form example:</h2> <p> <lift:FormExample form="POST"> <f:name><input type="text"/></f:name> <input type="submit" value="Post"/> </lift:FormExample> </p> </lift:surround>
class FormExample { def render(xhtml: NodeSeq) = { bind("f", xhtml, "name" -> text("", println(_))) } }
// in boot.scala: val entries = Menu(Loc("Home", List("index"), "Home")) :: Menu(Loc("form1", List("veryFirstForm"), "Example")) :: User.sitemap LiftRules.setSiteMap(SiteMap(entries:_*))
39
Formulare <lift:surround with="default" at="content">
<h2>Very first form example:</h2> <p> <lift:FormExample form="POST"> <f:name><input type="text"/></f:name> <input type="submit" value="Post"/> </lift:FormExample> </p> </lift:surround>
class FormExample { def render(xhtml: NodeSeq) = { bind("f", xhtml, "name" -> text("", println(_))) } }
// in boot.scala: val entries = Menu(Loc("Home", List("index"), "Home")) :: Menu(Loc("form1", List("veryFirstForm"), "Example")) :: User.sitemap LiftRules.setSiteMap(SiteMap(entries:_*))
40
Formulare
40
Formulare
40
JAX 2009! INFO - Service request (POST) /veryFirstForm took 61 Milliseconds
Formulare
40
JAX 2009! INFO - Service request (POST) /veryFirstForm took 61 Milliseconds
Formulare
41
more in Action ;)
Beispiel-Applikation(en)Scala Actors / CometModelle / OR-MappingSiteMapMessages...
42
Beispiel-Applikation(en)Scala Actors / CometModelle / OR-MappingSiteMapMessages...
42
Demo !
43
Zusammenfassung
44
ProSehr schicke Sprachfeatures„Best of all“ PrinzipJunge und dynamische CommunitySehr gut für interaktive Webbapplikationen („Real time web“)Native, volle JVM Geschwindigkeit100% kompatibel mit JavaLäuft auf Standard Servlet-Container (Jetty, Tomcat, ...)
44
ProSehr schicke Sprachfeatures„Best of all“ PrinzipJunge und dynamische CommunitySehr gut für interaktive Webbapplikationen („Real time web“)Native, volle JVM Geschwindigkeit100% kompatibel mit JavaLäuft auf Standard Servlet-Container (Jetty, Tomcat, ...)
ConsSteile LernkurveWenig Scala Ressourcen am Markt verfügbar (XING: 164)Noch weniger Lift Ressourcen verfügbar (XING: 3)Keine mir bekannten große Installationen aktuell vorzeigbar 44
Aktuell Roadmap 1.1 (Auszug der Lift Newsgroup)Improved documentation: better VScalaDoc coverage as well as better tutorial and cook-book documentation.Improved J2EE support including JTA and Portlets.Finish Record/Field code with backing store including JDBC, JPA and Goat Rodeo (what's Goat Rodeo? http://goatrodeo.org)Improved client-side JavaScript support and better JavaScript abstractions.Client/Server data synchronization (integrated with Record/Field)Improved support for REST.Improved performance including caching templates when running in production mode.OSGi support.Improved testing framework and better testing support when running in "test" mode.Implement Servlet 3.0 support.HTML 5 and Web Sockets support and integration with Kaazing's Web Sockets server. Also, sensing which browser is making the request and performing optimizations based on that browser's characteristics (specifically, Chrome and Firefox 3.1 support) 45
Ressourcen im NetzScala
http://scala-lang.orgLift
http://liftweb.net/http://liftweb.net/docs/getting_started.htmlhttp://wiki.liftweb.net/http://github.com/dpp/liftweb
Lift Buch: „Exploring Lift“http://groups.google.com/group/the-lift-bookhttp://github.com/tjweir/liftbook/
46
Exploring Lift Mail 2009, oder LyX Version!Derek Chen-Becker, Tyler Weir, Marius Danciu
Beginning ScalaMail 2009David Pollak
Programming in ScalaMartin Odersky, Lex Spoon, and Bill Venners
...47
Tobias JochSystem ArchitectureProject Management
inovex GmbHKarlsruher Straße 7175179 Pforzheim
0173.3181 004tobias.joch@inovex.dewww.inovex.de
Fragen & Antworten
Wir nutzen Technologien, um unsere Kunden glücklich zu machen. Und uns selbst.
Tobias JochSystem ArchitectureProject Management
inovex GmbHKarlsruher Straße 7175179 Pforzheim
0173.3181 004tobias.joch@inovex.dewww.inovex.de
Vielen Dank! ;)
Wir nutzen Technologien, um unsere Kunden glücklich zu machen. Und uns selbst.
top related