package com.muchsoft.scala.servletsDas sieht doch fast wie Java aus, oder? Nicht ganz: Beim Import können wir Umdefinitionen vornehmen, das
import javax.servlet.http.HttpServlet
import javax.servlet.http.{HttpServletRequest => Request,
HttpServletResponse => Response}
class MeinErstesScalaServlet extends HttpServlet {
override def doGet(request: Request, response: Response) {
val ausgabe =
<html>
<head><title>Hallo Scala</title></head>
<body>
<h1>Hallo Scala-Welt!</h1>
</body>
</html>
response.getWriter().print(ausgabe)
}
}
override
vor der Methodendefinition ist zwingend notwendig, zudem ein Schlüsselwort und keine Annotation. Der Rückgabetyp der Methode doGet()
ist nicht angegeben und entspricht dadurch dem Java-void
. Für Scala hätten wir vor die öffnende geschweifte Methodenklammer :Unit=
schreiben können.Innerhalb von
doGet()
legen wir das XML-Literal ausgabe
an (als nicht änderbaren Wert mit val
; mit var
angelegte Variablen versucht man in funktionalen Sprachen zu vermeiden). Dieses XML-Literal schreiben wir ganz normal in den Ausgabestrom des Response-Objekts. Der Typ von ausgabe
ist scala.xml.Elem
.Die Struktur der Web-Applikation entspricht dem JavaEE-Standard:
Der vom Scala-Compiler erzeugte Java-Bytecode landet in
WEB-INF/classes
. Die Scala-Standardbibliothek scala-library.jar
(aus dem Scala-Installationsverzeichnis) muss in WEB-INF/lib
mit ausgeliefert werden. In WEB-INF/web.xml
mappen wir die Klasse com.muchsoft.scala.servlets.MeinErstesScalaServlet
auf die URL "hallo.scala". Nach dem Bereitstellen (Deployment) z.B. in Tomcat oder GlassFish kann das Servlet im Web-Browser dann mit der URL http://localhost:8080/halloscala/hallo.scala aufgerufen werden.Zum Übersetzen der Servlet-Klasse muss sich noch die Servlet-API auf dem Build-Path (Classpath) befinden. Dazu kann man z.B. aus dem Tomcat-Installationsverzeichnis
servlet-api.jar
oder aus dem GlassFish-Verzeichnis javaee.jar
als externe Bibliothek einbinden.Nun verbessern wir das erste Scala-Servlet und trennen Darstellung und Steuerung etwas besser voneinander:
class MeinZweitesScalaServlet extends HttpServlet {
def ausgabe =
<html>
<head><title>Hallo Scala</title></head>
<body>
<h1>Hallo Scala-Welt!</h1>
<p>Zeit auf dem Server: {jetzt} </p>
</body>
</html>
def jetzt = new java.util.Date
override def doGet(request: Request, response: Response) {
response.getWriter().print(ausgabe)
}
}
ausgabe
ist nun eine Funktion außerhalb von doGet()
, die auf die Funktion jetzt
zurückgreift, um einen aktuellen Zeitstempel auszugeben. Beide Funktionen sind ohne Parameterklammern definiert und müssen daher ohne Klammern aufgerufen werden. Hätten wir die Funktionen mit leeren Parameterklammern definiert, hätten wir es uns beim Aufruf aussuchen können, ob wir die Klammern hinschreiben oder nicht. Es hat sich die Konvention herausgebildet, die Klammern bei der Definition wegzulassen, wenn eine Funktion keine Nebenwirkungen (Seiteneffekte) hat.Für eine "vollständige" Web-Applikation fehlt noch ein Formular. Bitteschön:
class MeinDrittesScalaServlet extends HttpServlet {
def ausgabe(benutzername: String) =
<html>
<head><title>Hallo Scala-Welt</title></head>
<body>
<h1>Hallo {benutzername}</h1>
<p>Zeit auf dem Server: {jetzt}</p>
<form method="GET" action="hallo3.scala">
<p>Wie heißt Du?
<input name="benutzer" />
<input type="submit" value="Abschicken" />
</p>
</form>
</body>
</html>
def jetzt = new java.util.Date
override def doGet(request: Request, response: Response) {
val param = request getParameter "benutzer"
val benutzername =
if ((param == null) || (param.isEmpty))
"Scala"
else
param capitalize
val antwort = ausgabe(benutzername)
response.getWriter().print(antwort)
}
}
ausgabe()
bekommt nun einen String-Parameter übergeben, der in doGet()
anhand des Request-Parameters "benutzer" ermittelt wird. Statt des ?:
-Operators von Java, den es in Scala nicht gibt, verwenden wir ein besser lesbares if-else
, das in Scala ein Ausdruck ist und entsprechend ein Ergebnis liefert.Wenn diese dritte Servlet-Klasse in
web.xml
auf die URL "hallo3.scala" gemappt wird, kann der Aufruf im lokalen Applikations-Server mit http://localhost:8080/halloscala/hallo3.scala?benutzer=Thomas erfolgen.In der Praxis wird man Servlets wohl eher nicht direkt programmieren, sondern ein Framework wie Struts, JSF, Wicket o.ä. einsetzen. Man sieht hier aber gut, wie problemlos man Scala in bestehende Java-(Web-)Anwendungen integrieren kann. Und wenn man Web-Applikationen so richtig funktional entwickeln möchte, kann man das Scala-Lift-Framework nutzen.