JSP (Java Server Pages) Grundlagen

+ andere TechDocs
+ andere Java-Docs
+ andere JSP-Docs
+ JSP-Einfuehrung
+ Webanwendungen
+




Inhalt

  1. Einführung zu dynamischen Webseiten mit JSP (Java Server Pages)
  2. JSP-Aufrufe im HTML-Dokument
  3. Predefined Variables (Implicit Objects)
  4. Sonderzeichen
  5. Directives, Declarations, Scriptlets, Expressions
  6. Actions
  7. URL-Rewriting statt Cookies
  8. Threads
  9. Programmierbeispiel: Alle Formulardaten anzeigen
  10. Programmierbeispiel: Datenbank-Tabelle anzeigen
  11. Java-Code von JSP aus aufrufen
  12. Weiterführende Informationen


Einführung zu dynamischen Webseiten mit JSP (Java Server Pages)

Eine Einfuehrung zu JSP finden Sie unter jsp-einfuehrung.htm

Installationsbeschreibungen finden Sie unter jsp-install.htm



JSP-Aufrufe im HTML-Dokument

<html>
  <head>
    <title>Meine erste JSP</title>
  </head>
  <body>
    <h1>Meine erste JSP</h1>
    <%
      // beliebiger Java-Code
      out.println( "Hallo" );
    %>
    <%= request.getRemoteHost() %>
    ...
  </body>
</html>
<html> schließt das gesamte HTML-Dokument ein.
<head> schließt den Header ein.
<body> schließt den Hauptteil ein.
JSP-Kommandos sind in <% ... %> oder <jsp:... .../> eingeschlossen.
Sie können auch in einer externen Datei enthalten sein, die per Include eingebunden wird:
'<%@ include file="Header.html" %>' (Compilierzeit) oder
'<jsp:include page="Header.html"/>' (Laufzeit)


Predefined Variables (Implicit Objects)

request.getAttribute();
request.getParameterNames();
request.getParameter();
request.getParameterValues();
request.getQueryString();
request.getRemoteHost();

request (HttpServletRequest)
Anfrage vom Client.
response.setContentType("text/plain"); response (HttpServletResponse)
Antwort an den Client, z.B. MIME-Typ.
out.println( "Hallo !" );
out.flush();

out (JspWriter, buffered PrintWriter).
session.getId();
session.getAttributeNames();
session.getAttribute();
session.setAttribute();

session (HttpSession).
config.getInitParameter();
config.getInitParameterNames();

config (ServletConfig).
application.log();
application.getServerInfo();
application.getMimeType();
application.getRealPath();
application.getResourceAsStream();
application.getAttribute();
application.setAttribute();

application (ServletContext, getServletConfig().getContext()).
pageContext.findAttribute();
pageContext.getAttribute();

pageContext (PageContext)
Seitenattribute, implizite Objekte und Kapselung Server-spezifischer Features.
page... page (this)
Wird mit Java nicht benötigt.
exception.getMessage();
exception.printStackTrace();
exception.toString();

exception (Throwable)
Ausnahmen.


Sonderzeichen

<\% <% im statischen HTML-Template oder Attribut.
%\> %> im JSP-Java-Code oder Attribut.
\' \" ' und " im Attribut.


Directives, Declarations, Scriptlets, Expressions

<!-- ... -->
Beispiel:
<!-- HTML Kommentar -->
HTML Comment, ist in Ergebnis-HTML-Datei sichtbar.
<%-- ... --%>
Beispiel:
<%-- JSP Kommentar --%>
JSP Comment, in Ergebnis-HTML-Datei nicht mehr sichtbar.
<%@ ... %>
Beispiele:
<%@ page import="java.util.*" %>
<%@ page isThreadSafe="false" %>
<%@ include file="url" %>

JSP Directives sind Anweisung zum globalen Dokument und Anweisungen an die JSP-Engine.
<%! ... %>
Beispiel:
<%! private int accessCount = 0; %>
Accesses to page since server reboot:
<%= ++accessCount %>

JSP Declarations sind Dokument-weite Deklarationen und werden außerhalb der service-Methode implementiert.
Hier können bei Bedarf die Funktionen jspInit() und jspDestroy() des Interface JspPage implementiert werden.
Hier deklarierte Variablen sind von allen Threads gemeinsam genutzte Instanzvariablen, weshalb wegen der Thread-Sicherheit hier normalerweise nur Konstanten und Methoden Sinn machen.
<% ... %>
Beispiel:
<%
String s = request.getQueryString();
out.println( "GET data: " + s );
if( boolVar )
{
%>
<jsp:forward page='<%= Second.jsp %%>' /%>
<%
}
%>
JSP Scriptlets stellen innerhalb der service-Methode implementierten Code dar.
Wichtig: Eine geschweifte Klammer ('{ ... }'), die in einem '<% ... %>'-Block beginnt, kann im nächsten '<% ... %>'-Block geschlossen werden, wie das Beispiel links zeigt.
<%= ... %>
Beispiele:
Date: <%= new java.util.Date() %>
Host: <%= request.getRemoteHost() %>

JSP Expressions sind einzelne Ausdrücke (ohne abschließendes Semikolon), die ausgegeben werden (Abkürzung für out.println()).
<jsp:... ... />
Beispiele:
<jsp:include page="relativeUrl" />
<jsp:useBean att="val" />
<jsp:forward page='<%= Second.jsp %%>' /%>

JSP Actions starten zusätzliche Funktionalität zur Laufzeit.


Actions

<jsp:include page="relativeUrl" flush="true"/> Einfügen einer HTML- oder JSP-Seite zur Laufzeit.
(<%@ include file="..." %> dagegen fügt zu Compilierzeit ein.)
<jsp:useBean id="myName" class="myPackage.MyClass"/> Aufruf einer JavaBean. Bei class=... muss der komplette Pfad angegeben werden. Weiteres zu JavaBeans unter: Java-Basics-JavaBean.
<jsp:useBean id="myName" class="myPackage.MyClass">
...
</jsp:useBean>

Aufruf einer JavaBean im Container-Format. Die Anweisungen im Body werden nur bei erster Instanziierung ausgeführt und nicht, wenn die Bean bereits in Benutzung ist.
<jsp:useBean id="myName" class="myPackage.MyClass" scope="..." type="..." beanName="..."/> Aufruf einer JavaBean mit zusätzlichen Parametern.
scope definiert den Kontext: page, request, session oder application.
type definiert den Variablentyp.
beanName übergibt den Name der Bean für die instantiate-Methode.
<jsp:getProperty name="myName" property="someProperty"/>
<jsp:setProperty name="myName" property="someProperty" value="someValue"/>
<jsp:setProperty name="myName" property="someProperty" param="someRequestParam"/>

Ermitteln und Ändern von Eigenschaften einer JavaBean.
<jsp:setProperty name="myName" property="*"/> Übertragung aller gleichnamiger Request-Parameter zur JavaBean.
<jsp:forward page="errorReport.jsp"/>
<jsp:forward page="<%= ... %>"/>

Weiterleiten auf andere Seite.
<jsp:plugin type="applet" code="NervousText.class" codebase="/applets/NervousText" height="50" width="375"/>
<params>
<param name=text value="..." >
</params>
<fallback>Error</fallback>
</jsp:plugin>

Web-Browser-spezifischen Code (OBJECT bzw. EMBED) für Java-Plug-in.


URL-Rewriting statt Cookies

<form action='<%=
  response.encodeURL("my.jsp") %>'>

<% response.sendRedirect(
  response.encodeRedirectURL("my.jsp"));%>

Normalerweise funktioniert die Wiedererkennung des Clients per im Client-Webbrowser gesetzten temporären Cookies.
Für den Fall, dass der Benutzer nicht nur permanente, sondern unnötigerweise auch temporäre Cookies verbietet, kann URL-Rewriting eingesetzt werden, wie es die nebenstehenden Beispiele zeigen.


Threads


Falls Objekte von mehreren Threads benutzt werden können, muss auf Thread-Sicherheit geachtet werden.
Dies gilt insbesondere für Objekte in JSP Declarations (<%! ... %>), JavaBeans und für Datenbankverbindungen, aber auch für andere Objekte.
Andererseits sollte Serialisierung nur erzwungen werden, wo nötig, um die Performance nicht zu beeinträchtigen.
<%@ page isThreadSafe="false" %>
Mit der JSP Directive <%@ page isThreadSafe="false" %> kann die gesamte .jsp-Seite als nicht multithread-fähig gekennzeichnet werden, damit der Webserver entweder mehrere Instanzen der JSP-Klasse erzeugt oder wartet, bis die vorherige Instanz beendet ist.
synchronized (this) {
seitenZugriffsZaehler++;
if( 0 == seitenZugriffsZaehler % 30 ) seitenZugriffsZaehlerSpeichern(); }


public synchronized void myCriticalFunction() { ...; }

Mit synchronized können sowohl Objekte als auch Methoden geschützt werden.


Programmierbeispiel: Alle Formulardaten anzeigen

Dieser JSP-Code zeigt sowohl GET- als auch POST-Parameter an.
Er muss als .jsp-Datei von der das Formular enthaltenden HTML-Seite aufgerufen werden mit:
<form action="formulardatenanzeige.jsp" method="post">
Mehrere selektierte Elemente einer Mehrfachauswahlliste (<select multiple ...>) können nicht mit request.getParameter() erfragt werden, und werden deshalb mit request.getParameterValues() ermittelt.

<html><body>
<%@ page import = "java.util.*" %>
<b>Parameters:</b><br>
<%
  Enumeration parameterList = request.getParameterNames();
  while( parameterList.hasMoreElements() )
  {
    String   sName     = parameterList.nextElement().toString();
    String[] sMultiple = request.getParameterValues( sName );
    if( 1 >= sMultiple.length )
      out.println( sName + " = " + request.getParameter( sName ) + "<br>" );
    else
      for( int i=0; i<sMultiple.length; i++ )
        out.println( sName + "[" + i + "] = " + sMultiple[i] + "<br>" );
  }
%>
</body></html>

Weiteres zu HTML-Formularen finden Sie in: html.htm#Formulare.
Hinweise zur Behandlung von Formularen mit JavaScript gibt es in: javascript.htm.
Wie Datei-Upload per JSP erfolgen kann ist beschrieben in: jsp-upload.htm.

Das folgende Beispiel vereint ein HTML-Formular mit der gerade gezeigten Parameterausgabefunktion:
<%@ page import = "java.util.*" %>
<%
  final String s1 = "<tr bgcolor='#EBEEEE'><td>";
  final String s2 = "</td><td>";
  final String s3 = "</td></tr>\n";
  StringBuffer sb = new StringBuffer();
  Enumeration parameterList = request.getParameterNames();
  while( parameterList.hasMoreElements() )
  {
    String   sName     = parameterList.nextElement().toString();
    String[] sMultiple = request.getParameterValues( sName );
    if( 1 >= sMultiple.length )
      sb.append( s1 + sName + s2 + request.getParameter( sName ) + s3 );
    else
      for( int i=0; i<sMultiple.length; i++ ) {
        sb.append( s1 + sName + "[" + i + "]" + s2 + sMultiple[i] + s3 );
      }
  }
  if( 0 < sb.length() )
    sb.insert( 0, "<table border=0 cellspacing=3 cellpadding=3>\n"
                + "<tr bgcolor='#EBEEEE'><th colspan='2'>"
                + "<big>Erhaltene Parameter</big></th></tr>\n" )
      .append( "</table>\n" );
%>

<html>
<body>

<form action="FormShow.jsp?urlParm=seeUrl#Scroll" method="post">
  <input type="hidden" name="hidden" value="hid">
  <table border=0 cellspacing=3 cellpadding=3>
    <tr bgcolor='#EBEEEE'><th colspan='2'>
        <big>Formular</big><br>
        Bitte Eingaben ändern und Submit betätigen</th></tr>
    <tr bgcolor="#EBEEEE"><td>SelectDropDown</td>
      <td>
        <select name="SelectDropDown" size=1>
          <option value="1">Opt. 1</option>
          <option value="2" selected>Opt. 2</option>
          <option value="3">Opt. 3</option>
          <option value="4">Opt. 4</option>
        </select>
      </td></tr>
    <tr bgcolor="#EBEEEE"><td>SelectMultiple</td>
      <td>
        <select name="SelectMultiple" size=3 multiple>
          <option value="1">Opt. 1</option>
          <option value="2">Opt. 2</option>
          <option value="3" selected>Opt. 3</option>
          <option value="4" selected>Opt. 4</option>
        </select>
      </td></tr>
    <tr bgcolor="#EBEEEE"><td>Textarea</td>
      <td>
        <textarea name="Textarea" cols=20 rows=3>Text ...</textarea>
      </td></tr>
    <tr bgcolor="#EBEEEE"><td>Textfeld</td>
      <td>
        <input type="text" name="Textfeld" value="Text ..." size=20 maxlength=50>
      </td></tr>
    <tr bgcolor="#EBEEEE"><td>Passwort</td>
      <td>
        <input type="password" name="Passwort" value="xx" size=20 maxlength=10>
      </td></tr>
    <tr bgcolor="#EBEEEE"><td>Checkboxen cb1...cb3</td>
      <td>
        <input type="checkbox" name="cb1">
        <input type="checkbox" name="cb2" checked>
        <input type="checkbox" name="cb3">
      </td></tr>
    <tr bgcolor="#EBEEEE"><td>Radiobuttons ra</td>
      <td>
        <input type="radio" name="ra" value="1">
        <input type="radio" name="ra" value="2" checked>
        <input type="radio" name="ra" value="3">
      </td></tr>
    <tr bgcolor="#EBEEEE"><td>Submit</td>
      <td>
        <button type="submit" name="Submit" value="SubmitImg">
          <img src="http://www.torsten-horn.de/logo.gif" alt="Submit">
        </button>
        <input type="submit" name="Submit" value="Submit1">
        <input type="submit" name="Submit" value="Submit2">
      </td></tr>
  </table>
</form>

<a name="Scroll"></a>
<%= sb.toString() %>

</body>
</html>


Programmierbeispiel: Datenbank-Tabelle anzeigen

Informationen zu SQL finden Sie in sql.htm, mysql.htm und postgresql.htm.
Informationen zur Anbindung von SQL-Datenbanken unter Java mit JDBC finden Sie in java-sql.htm.
Im Folgenden wird eine JSP-Datei beschrieben, in der sowohl das Eingabe-Formular ('<form ...') als auch der die Ergebnisse auswertende und darstellende Code ('out.println(rs.getString())') zusammen in einer Datei stehen.
Das Source-Code-Beispiel ist funktionsfähig, aber ohne Fehlerbehandlung.
Falls die gelesenen Daten nicht sofort ausgegeben werden (wie im Beispiel mit 'out.println()'), sondern zu einem langen String addiert werden sollen, darf dies nicht durch Addition von Strings mit dem '+'-Zeichen erfolgen, sondern muss mit StringBuffer.append() geschehen, da sonst enorm viele Ressourcen und Zeit verbraucht werden.
Falls die Datenbank-Verbindung von mehreren Threads benutzt werden kann, müssen alle entsprechenden Funktionen Thread-sicher gemacht werden, z.B. mit 'synchronized' oder mit '<%@ page isThreadSafe="false" %>'.
Beachtet werden muss, dass bei SQL die erste Spalte mit 1 statt 0 indiziert wird (siehe ResultSet.getString() und getColumnName()).
Außerdem muss beachtet werden, dass zwar mehrere Statements gleichzeitig geöffnet sein können, aber innerhalb eines Statements (hier: 'st') zu jedem Zeitpunkt immer nur höchstens ein ResultSet ('rs') offen sein darf.
Das ResultSet muss nach Gebrauch unbedingt geschlossen werden ('rs.close()').
Das geöffnete Statement ('st') muss nicht unbedingt geschlossen werden ('st.close()'), die Entsorgung kann der Java Garbage Collection überlassen werden. Allerdings kann es einen Datenbank-Fehler auf Grund zu vieler geöffneter Cursor geben, wenn viele Statements geöffnet werden, bevor die Garbage Collection die vorherigen schließen konnte.
Für höhere Performance sollte kein ODBC-Treiber, sondern möglichst ein direkter zur Datenbank passender JDBC-Type-4-Treiber verwendet werden.
Der JDBC-Treiber muss entweder in das Verzeichnis %JAVA_HOME%\jre\lib\ext kopiert werden, dann braucht er nicht dem CLASSPATH hinzugefügt werden, oder er wird in ein anderes Verzeichnis kopiert und muss im CLASSPATH eingetragen werden (Pfad plus Dateiname).
Genaueres hierzu finden Sie in java-sql.htm.

Mögliche Beispiele für JDBC-Type-4-Treiber und die Strings sDbDrv und sDbUrl für die Datenbanken MySQL, PostgreSQL und Oracle:

  JDBC-Type-4-Treiber sDbDrv
sDbUrl
MySQL mysql-connector-java-5.1.16-bin.jar com.mysql.jdbc.Driver
jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName
PostgreSQL pgjdbc2.jar org.postgresql.Driver
jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName
Oracle classes12.zip oracle.jdbc.OracleDriver
jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL

<html>
<body>

<%@ page import = "java.sql.*" isThreadSafe="false" %>

<%
  String sDbDrv = "com.mysql.jdbc.Driver";
  String sDbUrl = "jdbc:mysql://localhost:3306/test";
  String sUsr   = "";
  String sPwd   = "";
  String sTable = "TestTabelle";
  String sSql   = "";
  if( request.getParameterNames().hasMoreElements() == true )
  {
    sDbDrv = request.getParameter( "prmDbDrv" );
    sDbUrl = request.getParameter( "prmDbUrl" );
    sUsr   = request.getParameter( "prmUsr" );
    sPwd   = request.getParameter( "prmPwd" );
    sTable = request.getParameter( "prmTab" );
    sSql   = request.getParameter( "prmSql" );
    if( null != sTable && 0 <  sTable.length() &&
       (null == sSql   || 0 == sSql.length())  )
      sSql = "SELECT * FROM " + sTable;
  }
%>

<form method="post"><pre>
Db-Treiber   <input type="text"     name="prmDbDrv" value='<%= sDbDrv %>' size=60><br>
Db-URL       <input type="text"     name="prmDbUrl" value='<%= sDbUrl %>' size=60><br>
Benutzer     <input type="text"     name="prmUsr"   value='<%= sUsr   %>' size=60><br>
Kennwort     <input type="password" name="prmPwd"   value='<%= sPwd   %>' size=60><br>
Tabellenname <input type="text"     name="prmTab"   value='<%= sTable %>' size=60><br>
SQL-Kommando <input type="text"     name="prmSql"   value='<%= sSql   %>' size=60>
             (nach Änderung anderer Parameter muss SQL-Kommando gelöscht werden)<br>
             <input type="submit" name="submit" value="Datenbanktabelle anzeigen">
</pre></form>

<%
  if( request.getParameterNames().hasMoreElements() == true
      && null != sDbDrv && 0 < sDbDrv.length()
      && null != sDbUrl && 0 < sDbUrl.length()
      && null != sSql   && 0 < sSql.length() )
  {
    Connection cn = null;
    Statement  st = null;
    ResultSet  rs = null;
    try {
      Class.forName( sDbDrv );
      cn = DriverManager.getConnection( sDbUrl, sUsr, sPwd );
      st = cn.createStatement();
      rs = st.executeQuery( sSql );
      ResultSetMetaData rsmd = rs.getMetaData();
      int n = rsmd.getColumnCount();
      out.println( "<table border=1 cellspacing=0><tr>" );
      for( int i=1; i<=n; i++ )    // Achtung: erste Spalte mit 1 statt 0
        out.println( "<th>" + rsmd.getColumnName( i ) + "</th>" );
      while( rs.next() )
      {
        out.println( "</tr><tr>" );
        for( int i=1; i<=n; i++ )  // Achtung: erste Spalte mit 1 statt 0
          out.println( "<td>" + rs.getString( i ) + "</td>" );
      }
      out.println( "</tr></table>" );
    } finally {
      try { if( null != rs ) rs.close(); } catch( Exception ex ) {/*ok*/}
      try { if( null != st ) st.close(); } catch( Exception ex ) {/*ok*/}
      try { if( null != cn ) cn.close(); } catch( Exception ex ) {/*ok*/}
    }
  }
%>

</body>
</html>


Java-Code von JSP aus aufrufen

Eine JSP-Datei soll eine Funktion aus einer Klasse in einer JavaBean-ähnlichen Java-Datei aufrufen.

Die JSP-Datei 'MeinJspUndJavaBeansTest.jsp':

<html><body>
  <%@ page import = "torstenhorn.meinpackage.*" %>
  <h1>Mein JSP- und JavaBeans-Test</h1>
  <form action="MeinJspUndJavaBeansTest.jsp">
    Bitte Zahl eingeben: <input type="text" name="EingabeZahl" size=5 maxlength=5><br>
  </form>
  <%
    String s1 = request.getParameter( "EingabeZahl" );
    if( null != s1 )
      out.println( "Das Quadrat von '" + s1 + "' ist: '" + MeineBean.meineFunktion( s1 ) + "'." );
  %>
</body></html>

Die Java-Datei 'MeineBean.java':

package torstenhorn.meinpackage;
public class MeineBean
{
  public static String meineFunktion( String s )
  {
    try {
      int i = Integer.parseInt( s );
      return "" + (i * i);
    } catch( Exception ex ) {
      return "Fehler, bitte Zahl eingeben!";
    }
  }
}

Manchmal kann es etwas schwierig sein, die absoluten Pfadangaben im Dateisystem des JSP-Servers zu ermitteln. Dann sollten Sie mit folgender JSP-Datei die Pfade ermitteln:


<html>
<body>
  Absolute Pfade im Dateisystem des JSP-Servers:<br>
  <pre>
    <%= getServletConfig().getServletContext().getRealPath( "/" ) %><br>
    <%= getServletConfig().getServletContext().getRealPath( request.getRequestURI() ) %><br>
  </pre>
</body>
</html>

Wenn Sie Webanwendungen im Internet zugänglich machen wollen, sehen Sie sich Google App Engine und Red Hat OpenShift an.

Weiterführende Informationen





Weitere Themen: Webanwendungen | JSP-Einfuehrung | andere JSP-Docs | andere Java-Docs | JavaScript | HTML | SQL | andere TechDocs
© 1998-2005 Torsten Horn, Aachen