Wir bauen uns eine Webapplikation!

32
Wir bauen uns eine Webapplikation! MySQL, Java und einiges mehr

description

MySQL, Java und einiges mehr. Wir bauen uns eine Webapplikation!. Unsere Webapplikation kann nach Schauspieler/innen suchen… . Unsere Webapplikation kann nach Schauspieler/inne suchen…. … und alle Filme mit einer Schauspielerin anzeigen. Wie funktioniert das? Client-Server Applikationen. - PowerPoint PPT Presentation

Transcript of Wir bauen uns eine Webapplikation!

Page 1: Wir bauen uns eine  Webapplikation!

Wir bauen uns eine Webapplikation!

MySQL, Java und einiges mehr

Page 2: Wir bauen uns eine  Webapplikation!

Unsere Webapplikation kann nach Schauspieler/innen suchen…

Page 3: Wir bauen uns eine  Webapplikation!

Unsere Webapplikation kann nach Schauspieler/inne suchen…

Page 4: Wir bauen uns eine  Webapplikation!

… und alle Filme mit einer Schauspielerin anzeigen

Page 5: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Client-Server Applikationen

Client

Der BrowserFirefoxChromeSafari

Internet Explorer…

Server

ApacheTomcat

JettyMicrosoft

IIS…

Internet

URLhttp://localhost:8080/html/index.html

Die darzustellende WebseiteHTML

Page 6: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Jetty und seine Handler

Jetty-Server

addContext

("/html", "html/");

ResourceHandler

Liest angefragte

Datei index.html

in Verzeichnis

html/

URLhttp://

localhost:8080/html/index.html

angefragte Datei

Ressource

Dateipfadindex.html

angefragte Datei

Ressource

Der ResourceHandler ist eine Klasse von Jetty. Er liefert einfach Dateien

zurück.

Page 7: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Jetty und seine HandlerKlasse ImdbServer, Hauptprogramm main:

ContextHandler htmlHandler = handlers.addContext("/html", "html/");htmlHandler.setHandler(new ResourceHandler());

ContextHandler cssHandler = handlers.addContext("/css", "css/");cssHandler.setHandler(new ResourceHandler());

ContextHandler imgHandler = handlers.addContext("/images", "images/");imgHandler.setHandler(new ResourceHandler());

Page 8: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Jetty und unser eigener Handler

Jetty-Server

addContext

("/query/actors",

"");

ActorsQueryHandl

er

Macht Datenbank-Abfrage

und Darstellun

g der Webseite

URLhttp://

localhost:8080/query/actors/?name=watson%2C+emma

Fixfertiges HTML

Ressource

Parametername=watson

%2C+emma

Fixfertiges HTML

Ressource

Der ActorsQueryHandler ist eine unserer eigenen Klassen. Er sucht in der Datenbank nach Schauspieler/innen und stellt die

Treffer in einer Webseite dar.

Page 9: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Unser Handler: Datenbank-Abfrage

ActorsQueryHandl

er

1. Datenbank-Abfrage

Parametername=watson

%2C+emma

Gefundene Datensätze

SQL AbfrageSELECT * FROM actors WHERE

name like ? ORDER BY name

Abfrage-Parameter:

"%watson, emma%"

Der ActorsQueryHandler sucht als erstes in unserer MySQL-Datenbank nach Schauspieler/innen, deren Namen ähnlich ist wie

der URL-Parameter name.

MySQLDatenba

nkServer

Enthält die

Tabellen mit den IMDB-Daten

Page 10: Wir bauen uns eine  Webapplikation!

1. Die Datenbankabfrage aufbereiten in ActorsQueryHandler:1.1. Prüfen, ob ein Parameter name vorhanden ist if (request.getParameter("name") != null) { PreparedStatement statement = connection.prepareStatement( "SELECT * FROM actors "+ "WHERE name like ? ORDER BY name" ); statement.setString(1, "%"+request.getParameter("name")+"%« ); return statement;}

Wie funktioniert das?Unser Handler: Datenbank-Abfrage

Page 11: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Unser Handler: Datenbank-Abfrage

1. Die Datenbankabfrage aufbereiten in ActorsQueryHandler:1.2. SQL-Abfrage vorbereiten, ohne Input-Daten if (request.getParameter("name") != null) { PreparedStatement statement = connection.prepareStatement( "SELECT * FROM actors "+ "WHERE name like ? ORDER BY name" ); statement.setString(1, "%"+request.getParameter("name")+"%« ); return statement;}

Page 12: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Unser Handler: Datenbank-Abfrage

1. Die Datenbankabfrage aufbereiten in ActorsQueryHandler:1.3. Input-Daten auf vorbereiteter Abfrage setzen if (request.getParameter("name") != null) { PreparedStatement statement = connection.prepareStatement( "SELECT * FROM actors "+ "WHERE name like ? ORDER BY name" ); statement.setString(1, "%"+request.getParameter("name")+"%« ); return statement;}

Page 13: Wir bauen uns eine  Webapplikation!

Warum vorbereitete Abfragen?Achtung Gefahr: SQL Injection!Der naïve Ansatz einer SQL-Abfrage: Die Benutzereingabe (in rot dargestellt) direkt in der SQL-Abfrage verwenden:

executeQuery("SELECT * FROM actors WHERE name like '%watson, emma%' ORDER BY name");

Aber was passiert, wenn der Benutzer böswillige Eingaben macht?

executeQuery("SELECT * FROM actors WHERE name like '%';DROP TABLE actors;%' ORDER BY name");

Nach SELECT wird DROP TABLE ausgeführt. Uups.

de.wikipedia.org/wiki/SQL-Injection

Page 14: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Unser Handler: HTML-Erstellung

ActorsQueryHandl

er

2. Erstellung von HTML

mit Treffern der DB-Abfrage

Datenresult_list={

{ name=Watson, Emma (I), id=1935796 },

{ name=Watson, Emma (II), id=1935797 }

}

Der ActorsQueryHandler erstellt anschliessend das HTML. Dazu verwendet er das Framework Velocity. So können wir unsere

Daten in HTML «mischen».

Velocity

HTML-Template

plus Daten ergibt

HTML für Browser

Fixfertiges HTML

Ressource

Fixfertiges HTML

Ressource

Page 15: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Unser Handler: HTML-Erstellung

2. Die Daten der Abfrage für Velocity aufbereiten in ActorsQueryHandler:

Map<String, Object> hm = new HashMap<String, Object>();hm.put("name", resultSet.getString("name"));hm.put("id", resultSet.getInt("actorid"));return hm;

Maps sind Paare von (Name, Wert). Auf die Werte kann zugegriffen werden, indem ein Name abgefragt wird. Die obige Map wird mit zwei Paaren befüllt, die zum Beispiel die Werte haben könnten («name», «Streep, Meryl») und («id», «1235454»).

Page 16: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Velocity: HTML mit Befehlen

Datenresult_list={

{ name=Watson, Emma (I), id=1935796 },

{ name=Watson, Emma (II), id=1935797 }

}

Ein Velocity-Template erhält vom Java-Programm Daten. Diese können mit einfach Befehlen ausgelesen und in das HTML

eingebaut werden.

Auszug aus unserem Velocity-Template

<h1>Gefundene Schauspieler</h1>

<ul>#foreach ($actor in $result_list) <li><a href="/query/movies?actor_id=$actor.id">$actor.name</a></li>#end</ul>

Fixfertiges HTML

Ressource

Page 17: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Jetty und unser eigener Handler

War das alles? Es braucht noch mehr Code, um Jetty mit MySQL via JDBC und mit Velocity zu integrieren.

Wenn eine einzelne SQL-Abfrage ausreicht, können wir die Klasse AbstractSingleQueryHandler erweitern (ca. 200 Zeilen).

Diese Klasse stellt die ganze Infrastruktur zur Verfügung. So können sich unsere eigenen Handler die wenigen Teile ergänzen, die spezifisch für unsere SQL-Abfrage sind.

Page 18: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Jetty und unser eigener Handler

Die Klasse AbstractSingleQuery-Handler und ihre Unterklassen sind ein Beispiel des Design Patterns «Schablonenmethode».

Die Methode handle verwendet Methoden wie prepareQuery. Diese Methoden sind nicht in der abstrakten Klasse, sondern erst in den Unterklassen definiert.

Siehe auch de.wikipedia.org/wiki/Template_Method

Page 19: Wir bauen uns eine  Webapplikation!

Wie funktioniert das?Bausteine unserer Webapplikation

Clie

nt

Jett

y-Se

rver

Inte

rne

t

Acto

rsQ

uery

Han

dle

r

MyS

QL

Velo

city

Page 20: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

Page 21: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html

Page 22: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

Page 23: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

ImdbServer: Handler für /html konfigurierenContextHandler htmlHandler = handlers.addContext("/html", "html/");htmlHandler.setHandler(new ResourceHandler());

Page 24: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

localhost:8080/query/actors/?name=watson

query/actors

Page 25: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

localhost:8080/query/actors/?name=watson

query/actors

index.html: Das Formular definiert Input Parameter<form action="/query/actors" method="get"> <input name="name" type="text" size="30" /> <input type="submit" value=" Absenden " /></form>ImdbServer: Handler für /query/actors konfigurierenContextHandler actorsQueryHandler = handlers.addContext("/query/actors", "");actorsQueryHandler.setHandler(new ActorsQueryHandler());

Page 26: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

localhost:8080/query/actors/?name=watson

query/actors prepareQuery(…) SELECT * FROM

actors where …

Page 27: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

localhost:8080/query/actors/?name=watson

query/actors prepareQuery(…) SELECT * FROM

actors where …ActorsQueryHandler: Abfrage vorbereitenpublic PreparedStatement prepareQuery(HttpServletRequest request, Connection connection) /*…*/ { if (request.getParameter("name") != null) { PreparedStatement statement = connection.prepareStatement("SELECT * FROM actors WHERE name like ? ORDER BY name"); statement.setString(1, "%" + request.getParameter("name") + "%"); return statement; } /*…*/ }

Page 28: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

localhost:8080/query/actors/?name=watson

query/actors prepareQuery(…) SELECT * FROM

actors where …

mapResult(…)

Page 29: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

localhost:8080/query/actors/?name=watson

query/actors prepareQuery(…) SELECT * FROM

actors where …

mapResult(…)ActorsQueryHandler: Resultate aufbereitenpublic Map<String, Object> mapResult(ResultSet resultSet) { Map<String, Object> hm = new HashMap<String, Object>(); hm.put("name", resultSet.getString("name")); hm.put("id", resultSet.getInt("actorid")); return hm;}

actorid name

123456789 Watson, Emma (II)

… …

Page 30: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

localhost:8080/query/actors/?name=watson

query/actors prepareQuery(…) SELECT * FROM

actors where …

mapResult(…)

actors.vmgetVelocityTemplate()

…<h1>Gefundene Schauspieler</h1><ul><li><a href="/query/movies?actor_id=007">Bond, James</li></ul>…

Page 31: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)

Client Imdb-Server

Resource-Handler

ActorsQuery-Handler

Velocity MySQL

localhost:8080/html/index.html

/html/index.html html\index.html

…<form action="/query/actors"> <input name="name" …/></form>…

localhost:8080/query/actors/?name=watson

query/actors prepareQuery(…) SELECT * FROM

actors where …

mapResult(…)

actors.vmgetVelocityTemplate()

…<h1>Gefundene Schauspieler</h1><ul><li><a href="/query/movies?actor_id=007">Bond, James</li></ul>…

ActorsQueryHandler: Resultate aufbereitenpublic Map<String, Object> mapResult(ResultSet resultSet) { Map<String, Object> hm = new HashMap<String, Object>(); hm.put("name", resultSet.getString("name")); hm.put("id", resultSet.getInt("actorid")); return hm;}

actors.vm: HTML erstellen<ul> #foreach ($actor in $result_list) <li><a href="/query/movies?actor_id=$actor.id"> $actor.name</a></li> #end</ul>

Page 32: Wir bauen uns eine  Webapplikation!

Die «Schnitzeljagd»: Der Kern

ActorsQuery-Handler

Velocity MySQL

SELECT * FROMactors where …

AbstractQuery-Handler

Imdb-Serverquery/

actors handle(…)

answerQuery(…)

prepareQuery(…)

mapResult(…)mapResultSet(…)