Folge mir auf Twitter.

Webentwicklung - Web-Frontends

Hochschule für Technik und Wirtschaft Berlin

Dipl.-Inform. Thomas Ziemer

Webentwicklung - Web-Frontends

Dipl.-Inform. Thomas Ziemer

Webentwicklung - Web-Frontends

Statischer und dynamischer HTTP-Request-Response-Cycle

Statischer HTTP-Request-Response-Cycle

Ausführung von Server-Skripten (z.B. PHP)

Für jede einzelne Dokumentanforderung muss die Kette zwischen Web-Server und PHP-Prozess neu etabliert werden!
Die Kommunikation geschieht mittels CGI (Common Gateway Interface), das den Datenaustausch mittels Umgebungsvariablen (environment variables) vorsieht.

Ständig neu aufgerufen.
Vorkompiliert bzw. stets neu interpretiert.

Dynamischer HTTP-Request-Response-Cycle

Webentwicklung - Web-Frontends

JavaServer Pages (JSP)

Warum so eine alte Technologie?

Viele der in JSP verwendeten Konzepte werden auch in modernen Frameworks verwendet:

JavaServer Pages

<html>
   <head>
      <title>Meine tolle Webseite mit einem Datum</title>
   </head>
   <body>
      Es ist: <%= new java.util.Date().toString() %>
   </body>
</html>
Das angezeigte Datum mit Uhrzeit ist bei jedem Seitenaufruf aktuell.

JSP-Ausdruck

<%= auswertbarer Java-Ausdruck %>
<%= new java.util.Date().toString() %>
Der ermittelte Wert des Ausdrucks wird textuell in die Webseite eingefügt und damit angezeigt.

JSP-Scriptlet

<% beliebiger ausführbarer Java-Code %>
Der Code wird ausgeführt.
Ggf. gesetzte Attributwerte können im weiteren Verlauf der Seite genutzt werden, z.B. mittels JSP-Ausdrücken angezeigt.

JSP-Deklaration

<%! Deklaration einer Methode oder eines Instanzattributs %>
<%! String datetime = new java.util.Date().toString(); %>
Die deklarierten Methoden und Instanzattribute können an beliebiger anderer Stelle in der selben Webseite genutzt werden.

JSP-Kommentar

<%-- JSP-Kommentar, im HTML-Code unsichtbar --%>
<!-- HTML-Kommentar, im HTML-Code sichtbar -->

JSP-Direktiven

Datei-Direktive:
<%@ include file="Datei–Pfad relativ zur JSP-Seite" %>
Die Datei wird vor der HTML-Erzeugung textuell eingebunden.

Seiten-Direktive:
<%@ page pageEncoding="UTF-8" %>
<%@ page contentType="text/html" %>
<%@ page import="java.util.Date" %>
Globale Angaben über die JSP-Seite

Ein JSP-Beispiel

<%-- Import-Direktive (globale Angabe) --%>
<%@ page import="java.util.Date" %>
<html>
   <body>
      <h3>JSP-Uhrzeit</h3>
      <%-- JSP-Deklaration (Attr. oder Meth. deklarieren) --%>
      <%! String datetime = new Date().toString(); %>

      <%-- JSP-Ausdruck (ermittelten Wert einfügen) --%>
      Es ist: <%= datetime %>
   </body>
</html>
Das sieht erst einmal einfach aus, birgt aber eine große Problematik! Wir kommen gleich darauf zurück.

Ein schlimmes JSP-Beispiel

<html>
   <body>
      <h3>
         <%
           String[] valueArray = {"Rather", "dull", "example"};
           for (int i = 0; i < valueArray.length; i++) {
         %>
         <%= valueArray[i] %>
         <%
           }
         %>
      </h3>
   </body>
</html>

Webentwicklung - Web-Frontends

Ausführung einer JavaServer Page
oder: "Java ist nicht PHP"

Ausführung einer JavaServer Page

Java-Code steht nicht einfach so kontextlos herum. Er muss stets durch einen Klassenkontext umgeben werden. Jede JSP entspricht genau einer Java-Klasse.

Ausführung einer JavaServer Page

Ausführung einer JavaServer Page

Der JSP-Lebenszyklus

1. Transformieren 2. Kompilieren

Der JSP-Lebenszyklus

3. Instanziieren Die Schritte 1 bis 3 geschehen implizit beim Deployen.

4. Aufrufen

Abb. www.joerg-buchberger.de/jbde/inet2/index.html

Webentwicklung - Web-Frontends

Problematik mit Instanzattributen

Problematik mit Instanzattributen

Ergo: Dieselbe Instanz beantwortet Anfragen verschiedener Clients!

Instanzattribute machen den Code nicht "reentrant" und nicht "thread-safe"!

Problematik mit Instanzattributen

<html>
   <body>
      <h3>JSP-Uhrzeit</h3>
      <%-- JSP-Deklaration (Attr. oder Meth. deklarieren) --%>
      <%! String datetime = new java.util.Date().toString(); %>

      <%-- JSP-Ausdruck (ermittelten Wert einfügen) --%>
      Es ist: <%= datetime %>
   </body>
</html>
Frage: Wo liegt das Problem?

Lokale Attribute sind thread-safe

<html>
   <body>
      <h3>JSP-Uhrzeit</h3>
      <%!
        String getDate() {
           String datetime = new java.util.Date().toString();
           return datetime;
        }
      %>
      Es ist: <%= getDate() %>
   </body>
</html>
Bei jedem Aufruf von getDate() wird das Attribut neu berechnet.

Aber warum nur eine Instanz?

Die Antwort lautet "Zeitersparnis".

Im Gegensatz zu Server-Skripten (z.B. in PHP) wird nur einmal Lade- und Instanziierungszeit benötigt.

Bei Bedarf werden JSPs mittels Load-Balancing und zusätzlichen Instanzen skaliert.

Webentwicklung - Web-Frontends

Servlet

Servlet

Ein JSP-Beispiel

<html>
   <body>
      <%-- JSP-Ausdruck (ermittelten Wert einfügen) --%>
      Ihr Browser ist: <%= request.getHeader("User-Agent") %><br/>
      Ihre IP-Adresse ist: <%= request.getRemoteAddr() %>
   </body>
</html>
Und wie sieht das daraus entstehende Java-Servlet aus?

Java-Servlet

public class MyServlet extends HttpServlet {
   public void doGet(HttpServletRequest request,
                     HttpServletResponse response)
                        throws IOException, ServletException {

      // 1. Process request-parameters and -headers
      String browser = request.getHeader("User-Agent");
      String ipAddress = request.getRemoteAddress();

      // 2. Prepare the response
      response.setContentType("text/html");

      // 3. Write to Response-PrintWriter
      ...
   }
}

Java-Servlet (Fortsetzung)

public class MyServlet extends HttpServlet {
   public void doGet(HttpServletRequest request,
                     HttpServletResponse response)
                        throws IOException, ServletException {
      ...

      // 3. Write to Response-PrintWriter
      PrintWriter out = response.getWriter();
      out.println("<html><body>");
      out.println("Ihr Browser ist: " + browser + "<br/>" +
                  "Ihre IP-Adresse ist: " + ipAddress); 
      out.println("</body></html>");
   }
} 

Webentwicklung - Web-Frontends

Datenverwaltung und JSP-Kontext

Wohin mit den Daten?

Der Web-Container muss uns Unterstützung leisten!

JSP-Kontext

Das Lebensdauer- und Zugehörigkeitsproblem wird durch den JSP-Kontext gelöst:
  Geeignet für Attribute, ...
Page context  ...die nur während der Seitengenerierung benötigt werden;
nach etwaigem Redirect kann darauf nicht mehr zugegriffen werden
Request context  ...die vom Eintreffen des HTTP-Requests bis zum Senden
des HTTP-Response verfügbar sein sollen (inkl. Redirect)
Session context  ...die über die Dauer der Benutzer-Session erhalten bleiben sollen
Application context  ...die während der gesamten Laufzeit der Webanwendung erhalten bleiben sollen

Implizite JSP-Kontextobjekte

Für jeden Kontext stellt der Web-Container ein implizites Java-Objekt zur Verfügung:
  Bedeutung
pageContext  javax.servlet.jsp.PageContext
request  javax.servlet.http.HttpServletRequest
session  javax.servlet.http.HttpSession
application  javax.servlet.http.ServletContext
Ausgewählt wird der gewünschte JSP-Kontext in der scope-Angabe
einer Bean-Definition.

Verwendung der JSP-Kontextobjekte

Der Web-Container verwaltet diese Java Beans vollkommen automatisch.

Webentwicklung - Web-Frontends

Java Beans

Verschiedene Beans zur Datenspeicherung

Was sind Beans?

Ein Java Bean-Beispiel

package beans;

public class UserBean {
   private String firstName;  // das ist ein Property

   public String getFirstName() {
      return this.firstName;
   }

   public void setFirstName(String firstName) {
      this.firstName = firstName;
   }
}

Verwenden der Java Bean in JSP

<jsp:useBean id="myUser"
             class="beans.UserBean"
             scope="session"/>

Webentwicklung - Web-Frontends

Properties in Java Beans

HTTP-Request-Parameter

HTML-Formular

<html>
   <body>
      <form action="nextPage.jsp" method="POST">
         <label for="firstName">Vorname</label>
         <input name="firstName" type="text" placeholder="Hein"/>
         <input value="Speichern" type="submit"/>
      </form>
   </body>
</html>

Varianten des Datentransfers

<jsp:setProperty name="myUser"
                 property="firstName"
                 value="Hein"/>
<jsp:setProperty name="myUser"
                 property="firstName"
                 param="firstName"/>

Varianten des Datentransfers (Fortsetzung)

<jsp:setProperty name="myUser"
                 property="firstName"/>
<jsp:getProperty name="myUser"
                 property="firstName"/>

Fazit: Java Beans zur Seitendynamisierung

Architektur mit JSPs und Java Beans

JSP-Session

Webentwicklung - Web-Frontends

Dynamische Navigation

Dynamische Navigation

<jsp:forward page="nextPage.jsp">
   <%-- optionale Angaben --%>
   <jsp:param name="firstName" value="Hein"/>
</jsp:forward>

Dynamische Navigation (Fortsetzung)

<% response.sendRedirect(
           "https://domain.tld/nextPage.jsp?firstName=Hein") %>

Webentwicklung - Web-Frontends

Fazit

Fazit

Abhilfe: Rückbesinnung auf Model-View-Controller (MVC), Nutzung eines flexibleren Frameworks.

Puh, fertig!

Nächster Foliensatz...