wir bauen uns eine webapplikation!
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 PresentationTRANSCRIPT
Wir bauen uns eine Webapplikation!
MySQL, Java und einiges mehr
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
Client
Der BrowserFirefoxChromeSafari
Internet Explorer…
Server
ApacheTomcat
JettyMicrosoft
IIS…
Internet
URLhttp://localhost:8080/html/index.html
Die darzustellende WebseiteHTML
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.
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());
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.
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
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
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;}
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;}
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
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
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»).
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
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.
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
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
Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)
Client Imdb-Server
Resource-Handler
ActorsQuery-Handler
Velocity MySQL
localhost:8080/html/index.html
Die «Schnitzeljagd» durch die Webapplikation (vereinfacht!)
Client Imdb-Server
Resource-Handler
ActorsQuery-Handler
Velocity MySQL
localhost:8080/html/index.html
/html/index.html
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>…
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());
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
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());
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 …
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; } /*…*/ }
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(…)
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)
… …
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>…
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>
Die «Schnitzeljagd»: Der Kern
ActorsQuery-Handler
Velocity MySQL
SELECT * FROMactors where …
AbstractQuery-Handler
Imdb-Serverquery/
actors handle(…)
answerQuery(…)
prepareQuery(…)
mapResult(…)mapResultSet(…)
…