GeLiftete Web-Applikation mit Scala - Tobias Joch - inovex GmbH

Post on 10-Nov-2014

2,195 views 2 download

description

Webframeworks für Java müssen nicht zwangsläufig in Java geschrieben sein. Neben prominenten Vertretern wie Grails oder JRuby entstehen weitere, wie z.B. das erst kürzlich in der Version 1.0 erschiene Framework Lift. Lift ist in der funktionalen und objektorientierten Programmiersprache Scala geschrieben und lässt sich nahtlos in bestehende Java-Anwendungen integrieren. Innerhalb dieses Vortrags wird Lift anhand einer Beispielanwendung vorgestellt.

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.