ORACLE-Datenbank mit Internet-Anbindung

von Torsten Schülert

1. Allgemeiner Ablaufplan
2. Aufruf aus einem HTML-Dokument
3. Programmierung des CGI-Skripts
3.1. Auslesen der übermittelten Daten
3.1.1. Interpretieren der Daten
3.2. Datenbank-Verbindung
3.3. Absetzen von SQL-Befehlen
3.4. Auswerten des SELECT-Ergebnisses
3.5. Zurücksenden der Ergebnis-HTML-Seite


1. Allgemeiner Ablaufplan

Allgemein soll die Internet-Verbindung wie folgt ablaufen. Der Client bekommt vom Web-Server nach Eingabe der Adresse eine HTML-Seite. Die Suchanfrage wird durch den Anwender gestellt und die Daten des ausgefühlten Formulars an den Server zurückgeschickt. Dieser startet das entsprechende CGI-Programm, welches sich die dazugehörigen Daten aus der Datenbank per SELECT-Befehl holt, auswertet und danach eine HTML-Seite erstellt. Diese sendet der Web-Server nach Beendigung des CGI-Programms zurück an den Client bzw. an den Web-Browser. Dieser Ablauf wird im folgenden Bild noch einmal graphisch dargestellt.

Datenbankzugriff

2. Aufruf aus einem HTML-Dokument

Zu Beginn wird eine HTML-Seite (Formular) erstellt, die die entsprechenden Eingabe- oder Auswahlfelder enthält. Ein einfaches Suchformular enthält meist folgende Komponenten:


Hier der dazugehörige HTML-Code:

<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <title>Suchanfrage</title>
</head>

<body>

<center><b><font size=+3>Suchanfrage</font></b></center>
<form name="formular" method="POST" action="/suche/cgi-bin/suchen.bat" >
<div align=center>
<b><font size=-1>Suchkriterium:&nbsp;</font></b>
<input type="text" name="Beschreibung" size="50">
</div>
<br>
<center>
<input type="submit"  value="     Suchen     " name="send" >
<input type="reset" value="    Loeschen    " name="clear">
</center>
</form>
</body>
</html>
 

Wichtig ist hierbei, das alle Daten, die übermittelt werden sollen, in einem Formular zusammengefasst werden. Die Daten werden mit der Methode POST abgeschickt. Diese Methode wird nur verwendet, wenn der Anwender Formulardaten sendet. Die Daten des Anwenders werden der CGI-Anwendung über die Standardeingabe übermittelt, allerdings sendet der Web-Server den Rest der verfügbaren Informationen (z.B. REMOTE_ADDR, REMOTE_HOST, CONTENT_LENGTH, ...) über Umgebungsvariablen.
Leider können Java-Programm nicht direkt auf Umgebungsvariablen zugreifen, somit muß vorher ein ausführbares Skript (Unix, Linux) oder eine Batch-Datei (Windows) geschrieben werden, welche die benötigten Variablen ausliest und dem Java-Programm als Parameter übergibt.

Bsp.: SUCHEN.BAT

@echo off

rem ggf. Pfadnamen des Java-Interpreters angegeben
-----------------------------------------------------
set path=c:\jre11\bin;%path%

java cgiprog_suchen "%CONTENT_LENGTH%"

In der Umgebungsvariable steht die Anzahl der Zeichen, welche im Formular eingegeben wurden. Sie wird benötigt, um im Java-Programm die eigentlichen Daten aus der Standard-Eingabe (STDIN) einzulesen.

 

3. Programmierung des CGI-Skripts

3.1. Auslesen der übermittelten Daten

Zuerst wird der Wert des übergebenen Parameter ermittelt, und dann genauso viele Zeichen aus der STDIN gelesen.

 public static void main (String args [])
   {
    int content_length;
    content_length=Integer.parseInt (args [0]);
    byte buffer [] = new byte [content_length +1];
    try {System.in.read (buffer,0,content_length);}
      catch (IOException e) {System.out.println ("Lesefehler");};
    query_string=new String (buffer);
    ...
  }


3.1.1. Interpretieren der Daten

Die Variable query_string enthält jetzt alle Angaben aus dem Formular in der Form Name=Wert. Dabei sind die einzelnen Einträge mit einem & getrennt. Leerzeichen werden dabei durch ein + ersetzt. Enthaltene Sonderzeichen beginnen mit einem %-Zeichen und der hexadezimalen UniCode-Repräsentation.
Für das obige Suchformular würde der query_string, wie folgt aussehen:

query_string = "Beschreibung=suchstring&send=+++++Suchen+++++&clear=++++Loeschen++++"

Es ist sinnvoll, sich eine Funktion zu schreiben, die den Wert der als Parameter übergebenen Variable auszulesen und zurückzugeben.

static String getParameter (String name)
   {
    String backstring;
    int i;
    name+="=";
    for (i=0;
         (i<query_string.length()-name.length()) &&
          !(name.equalsIgnoreCase (query_string.substring (i,name.length()+i)));i++);
    if (i<query_string.length()-name.length())
      {
       backstring=query_string.substring(i+name.length());
       if (backstring.indexOf("&")>=0)
           backstring=backstring.substring(0,backstring.indexOf("&"));
      }
      else
       {
        backstring="";
       }
    backstring=backstring.replace('+',' ');
    i=0;
    while (i<backstring.length())
      {
       if (backstring.charAt(i)=='%')
           backstring=backstring.substring(0,i)+(char) Integer.parseInt(backstring.substring(i+1,i+3),16)+
           backstring.substring(i+3);      //Sonderzeichen von Hex->Dec->Zeichen
       i++;
      }
    return backstring;
   }
 

3.2. Datenbank-Verbindung

Bevor nun ein DB-Anfrage abgesetzt werden kann, muß zuvor eine Verbindung zur Datenbank aufgebaut werden. Unter JAVA gibt es dabei prinzipell zwei Möglichkeiten, entweder direkt über JDBC (Java DataBase Connectivity) oder aber über ODBC (Open DataBase Connectivity).
Mittlerweile unterstützen viele Datenbankmanagementsysteme JDBC. Sollte das DBMS keine JDBC-Unterstützung besitzen, besteht die Möglichkeit über ODBC auf die Datenbank zuzugreifen, dazu ist ein JDBC-to-ODBC Umsetzer nötig. Dieses Verbindungsglied ist im Java Developers Kit (ab Version 1.1x) enthalten. Zuvor muß die Datenbank mit dem ODBC-Treiber verbunden werden. Das geschieht bei Windows NT oder 9x in der Systemsteuerung/ODBC32. Dort wird ein DB-Alias (System-DSN) vergeben, über den dann auf die Datenbank zugegriffen werden kann. ORACLE8 ist ein DBMS, welches die JDBC-Unterstützung bestitzt.

Ob ODBC oder JDBC ist für den eigentlichen Datenbankzugriff uninteressant. Im Grunde ist nur der Verbindungsaufbau zur Datenbank unterschiedlich.

ODBC:

Die Treiber und Java-Klassen, um über JDBC auf die DB zugreifen zu können, sind auf der ORACLE-Homepage (http://www.oracle.com/database/download/o8_jdbc/html/download.html) für die meisten Betriebssysteme vorhanden.

JDBC:

Connection verbindung=DriverManager.getConnection ("jdbc:oracle:oci8:@DB-Aliasname,Login,Passwort");

Die Datenbankverbindung wird automatisch geschlossen, wenn das Programm beendet wird. Mit der Funktion close() kann die Verbindung auch eher geschlossen werden.
 

3.3. Absetzen von SQL-Befehlen

Nachdem die Verbindung zur Datenbank steht, kann der SQL-Befehl erstellt und abgesetzt werden. In Java geschieht das Auslesen und Schreiben aus bzw. in die Datenbank auf zwei Arten:

Auslesen:

Schreiben:

Liefert executeUpdate() einen Wert ungleich 1 zurück, konnte der Befehl nicht korrekt ausgeführt werden.
 

3.4. Auswerten des SELECT-Ergebnisses

Das Ergebnis der Anfrage ist vom Typ ResultSet. Dieser Typ ist eine Art zweidimensionales Feld, in dem sequentiell gelesen werden kann. Auf die gefundenen Daten kann entweder mit Nummern oder über den Spaltennamen zugegriffen werden.

...
ResultSet ergebnisse=query.executeQuery("SELECT Attribut1,Attribut2 FROM Tabelle");
int pos_Attribut1=ergebnisse.findColumn ("Attribut1");
int pos_Attribut2=ergebnisse.findColumn ("Attribut2");
String Attr1;
String Attr2;
int i=1;
while (ergebnisse.next())
       {
        Attr1=ergebnisse.getString (pos_Attribut1);
        Attr2=ergebnisse.getString (pos_Attribut2);
        System.out.println (i+". Datensatz: "+Attr1+"        "+Attr2);
        ...
      }
...
 

3.5. Zurücksenden der Ergebnis-HTML-Seite

Die HTML-Seite, welche das Suchergebniss enthält, wird in STDOUT geschrieben. Um die Performance zu steigern, ist es sinnvoll, soviel HTML-Code wie möglich mit einem System.out.println zu schreiben. Es ist darauf zu achten, daß die HTML-Seite am Ende komplett ist.
Die Seite muß nicht auf einmal "abgeschickt" werden. Es besteht die Möglichkeit, zuerst den Header zu schreiben, danach die Datenbankabfrage zu starten, das Ergebnis auszuwerten und in STDOUT zu schreiben, und zuletzt die Seite mit dem Foot abzuschließen.

static void htmlseite ()
   {
    System.out.println ("Content-type: text/html");                //WICHTIG!!!
    System.out.println ("");
    System.out.println ("<html>\n"+
     "<head>\n"+
     "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n"+
     "<meta name=\"GENERATOR\" content=\"CGI-Script (Java)\">\n"+
     "<title>Suchergebnis</title>\n"+
     "</head>\n"+
     "<body background=\"background.jpg\">");
     ...
    System.out.println ("</body>\n"+
     "</html>");
   }

Fragen, Hinweise, Kritiken, Bemerkungen und Ergänzungen bitte an torsten.schuelert@in.fh-merseburg.de!