Da der Aufruf des Servlets sowohl aus dem Navigations-Fenster (nach erfolgter Katalogauswahl beziehungsweise Aufruf der Suchfunktion) als auch aus dem Produktfenster (Navigieren zum vorhergehenden beziehungsweise nachfolgenden Produkt) heraus erfolgen kann, muß vom Servlet eine entsprechende Fallunterscheidung getroffen werden. Diese ergibt sich anhand der Auswertung verschiedener Formular-Parameter des Requests.
// Verarbeitung der Client-Anfrage
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Formatierung der ermittelten Links zu den Produktbildern
String pictures = "";
// Formatierung von Produktgruppenname und Katalog-Hierarchie
String[] groupPath = {"","",""};
// zur Entgegennahme der Ergebnismenge aus Abfrage
Vector product = new Vector();
// akt. Produktnummer und Gesamtanzahl
int pos = 0;
int cnt = 0;
// Formatierung der Navigations-Button
String button_left = null;
String button_right = null;
// globale Fehlervariable
noError = true;
// Parameter "n_group_id" der Navigationsseite abfragen (gid)
String group_id = request.getParameter("n_group_id");
// wenn Anfrage nicht vom Navigations-Fenster kommt, sondern vom Produktfenster selbst
if (group_id == null) {
// Parameter "p_group_id" der Produktseite abfragen (gid)
group_id = request.getParameter("p_group_id");
if (group_id == null) group_id = "";
}
// Parameter "n_searchtext" der Navigationsseite abfragen (Schnellsuch-Funktion)
String searchtext = request.getParameter("n_searchtext");
// falls Anfrage nicht vom Navigations-Fenster stammt, sondern aus Produktfenster selbst
// (Navigieren zwischen Produkten einer Suchabfrage)
if (searchtext == null) {
// Parameter "p_searchtext" der Produktseite abfragen
searchtext = request.getParameter("p_searchtext");
if (searchtext == null) searchtext = "";
}
// Parameter "p_product_id" der Produktseite abfragen (pid)
String product_id = request.getParameter("p_product_id");
if (product_id == null) product_id = "";
// Parameter "p_direction" der Produktseite abfragen (voriges/folgendes Produkt)
String direction = request.getParameter("p_direction");
if (direction == null) direction = "0";
// Produktdaten ermitteln mittels Methode getProduct() und Übergabe der ermittelten Parameter
// (Methode wird nachfolgend noch genauer beschrieben)
product = getProduct(product_id, group_id, searchtext, Integer.parseInt(direction));
// wenn bei Ausführung von getProduct() keine Fehler aufgetreten ist
if (noError) {
if (product != null) {
// wenn mindestens ein Produkt vorhanden ist
if (product.size() > 1) {
// Produkt-ID des aktuellen Produktes merken
product_id = (String)product.elementAt(0);
// Gruppen-ID des aktuellen Produktes merken
group_id = (String)product.elementAt(8);
// Bilder zum Produkt mittels Methode getPicture() ermitteln
// (Methode wird nachfolgend noch genauer beschrieben)
pictures = getPicture(product_id);
}
else {
product_id = "";
}
}
else product_id = "";
// wenn bisher kein Fehler aufgetreten ist
if (noError) {
// Kopfzeile der Produktseite mittels der Methode getGroupPath() generieren
// (Methode wird nachfolgend noch genauer beschrieben)
groupPath = getGroupPath(group_id);
// wenn bisher kein Fehler aufgetreten ist
if (noError) {
if (groupPath != null) {
// wenn Anfrage über Suchfeld vorliegt
if (!searchtext.equals("")) {
// anstatt der Produktgruppen-Bezeichnung
groupPath[0] = "Ergebnis der Suchanfrage";
}
}
// Navigationsschaltflächen der Produktseite bzgl. Datensatzposition generieren
if (product != null) {
// wenn Produktdaten vorhanden
if (product.size() > 1) {
// aktuelle Produktnummer gemessen an der Zahl aller entsprechend der Auswahl betrachtbaren Produkte
pos = Integer.parseInt((String)product.elementAt(11)) + 1;
// Anzahl aller Produkte, die entsprechend der Auswahl betrachtet werden können
cnt = Integer.parseInt((String)product.elementAt(10));
}
else cnt = 0;
}
else cnt = 0;
// akt. Produktnummer gleich 0, wenn Gesamtzahl gleich 0
if (cnt == 0) pos = cnt;
// Schaltfläche "zurück"
button_left = "src=\"../images/arrow_left.jpg\"";
// wenn nicht gerade das 1. Produkt angeigt wird
if (pos > 1) {
// Navigations-Button aktiviert
button_left = "<INPUT name=\"prev\" type=image " + button_left + " onClick=\"setDirection(document.frmProduct.prev.value);\">";
}
else {
// Navigations-Button deaktiviert
button_left = "<IMG " + button_left + ">";
}
// Schaltfläche "weiter"
button_right = "src=\"../images/arrow_right.jpg\"";
// wenn nicht gerade das letzte Produkt angeigt wird
if (pos < cnt) {
// Navigations-Button aktiviert
button_right = "<INPUT name=\"next\" type=image " + button_right + " onClick=\"setDirection(document.frmProduct.next.value);\">";
}
else {
// Navigations-Button deaktiviert
button_right = "<IMG " + button_right + ">";
}
}
}
}
// Erzeugung und Ausgabe der HTML-Seite mit event. Fehlerauswertung
try {
// wenn bei Abarbeitung kein Fehler aufgetreten ist
if (noError) {
// vorgefertigte HTML-Seite einlesen und Platzhalter ersetzen
// absolute Pfadangabe muß bei Verwendung angepaßt werden
page = pageGen.readPage("/export/pub/jakarta-tomcat-4.0.3/webapps/adia/servlets/product.html");
page = pageGen.replaceParam(page,groupPath[0],"@group@");
page = pageGen.replaceParam(page,groupPath[1],"@path@");
page = pageGen.replaceParam(page,groupPath[2],"@catalog_id@");
// Prüfung auf NULL-Wert des Objektes product
if (product != null) {
// wenn Produktdaten vorhanden
if (product.size() > 0) {
page = pageGen.replaceParam(page,(String)product.elementAt(1),"@pname@");
page = pageGen.replaceParam(page,(String)product.elementAt(9) + " " + (String)product.elementAt(5),"@price@");
page = pageGen.replaceParam(page,(String)product.elementAt(2),"@description@");
page = pageGen.replaceParam(page,(String)product.elementAt(7),"@articlenr@");
page = pageGen.replaceParam(page,(String)product.elementAt(3),"@item@");
page = pageGen.replaceParam(page,(String)product.elementAt(4),"@itemprice@");
page = pageGen.replaceParam(page,(String)product.elementAt(6),"@producer_id@");
}
}
// bei nicht vorhandenen Produktdaten Platzhalter entfernen
else {
page = pageGen.replaceParam(page,"","@pname@");
page = pageGen.replaceParam(page,"","@price@");
page = pageGen.replaceParam(page,"","@description@");
page = pageGen.replaceParam(page,"","@articlenr@");
page = pageGen.replaceParam(page,"","@item@");
page = pageGen.replaceParam(page,"","@itemprice@");
page = pageGen.replaceParam(page,"","@producer_id@");
}
// Platzhalter ersetzen
page = pageGen.replaceParam(page,pictures,"@picture@");
page = pageGen.replaceParam(page,product_id,"@product_id@");
page = pageGen.replaceParam(page,group_id,"@group_id@");
page = pageGen.replaceParam(page,searchtext,"@searchtext@");
page = pageGen.replaceParam(page,button_left,"@button_left@");
page = pageGen.replaceParam(page,button_right,"@button_right@");
page = pageGen.replaceParam(page,String.valueOf(pos),"@position@");
page = pageGen.replaceParam(page,String.valueOf(cnt),"@count@");
}
// falls während Abarbeitung ein Fehler aufgetreten ist
else {
// absolute Pfadangabe muß bei Verwendung angepaßt werden
page = pageGen.readPage("/export/pub/jakarta-tomcat-4.0.3/webapps/adia/servlets/error.html");
page = pageGen.replaceParam(page,error,"@error@");
}
}
// falls beim Laden der vorgefertigten Seite oder beim Ersetzen der Platzhalter ein Fehler auftritt
catch (Exception e) {
page = e.toString();
}
// generierte Seite an Client senden
out.println(page);
}
Die vorgefertigte HTML-Seite mit den Platzhaltern kann hier betrachtet werden.
Im folgenden sollen nun die drei Methoden des Servlets Product beschrieben werden, die in der zuvor beschrieben doGet(HttpServletRequest request, HttpServletResponse response)-Methode nicht näher beschrieben wurden. Als erstes wäre da die Methode getGroupPath(String group_id). Sie ermittelt die Produktgruppen-Bezeichnung und den hierarchischen Pfad zur angegebenen Gruppen-ID. Der Rückgabewert dieser Methode dient der Ersetzung der Platzhalter @group@, @path@ und @catalog_id@ der vorgefertigten HTML-Seite und gibt nach außen hin einen aufgetretenen Fehler zu erkennen, falls er dem NULL-Wert entspricht. Außerdem wird beim Auftreten eines Fehlers auch die globale Fehlervariable noError mit dem Wahrheitswert FALSE belegt. Im nachfolgenden Auszug des Quell-Codes wird dies genauer beschrieben.
// Ermittlung von Produktgruppe und Produktpfad
private String[] getGroupPath(String group_id) {
String[] groupPath = {"","",""};
String tmp_id = group_id;
String arrow = "";
int typnr = 0;
// Pfad zur Wurzel hin verfolgen und Abspeichern sowie untersten Gruppennamen merken,
// falls gültige Gruppen-ID vorhanden
if (!group_id.equals("")) {
try {
do {
// Parameterliste für Datenbankabfrage initialisieren
String[] param = {"NAME","MUTTERGRUPPE_ID","TYPNR","CID"};
// Datenbankabfrage durchführen
Vector result = dbcon.OraDBgetResult("SELECT name,muttergruppe_id,typnr,cid FROM struktur WHERE gid=" + tmp_id, param, 0);
// wenn Abfrage keine leere Ergebnismenge zurückgeliefert hat
if (result != null) {
// Gruppen-ID der übergeordneten Ebene merken
tmp_id = (String)result.elementAt(1);
// Typnummer merken (kennzeichnet Hierarchie)
typnr = Integer.parseInt((String)result.elementAt(2));
// wenn nicht bereits die Wurzel vorliegt
if (typnr != 1 && typnr != 4) arrow = " > "; else arrow = "";
// aktuelle Gruppe an eventuell bereits vorhandenen Pfad vorn anfügen
groupPath[1] = arrow + "<U>" + (String)result.elementAt(0) + "</U>" + groupPath[1];
// wenn erster Durchlauf dieser Schleife (unterste Ebene in aktueller Katalog-Hierarchie)
if (groupPath[0].equals("")) {
// Name der Produktgruppe abspeichern
groupPath[0] = (String)result.elementAt(0);
// zugehörige Katalog-ID (cid) abspeichern
groupPath[2] = (String)result.elementAt(3);
}
}
// Abbruch bei leerer Ergebnismenge der Abfrage kenntlich machen
else {
typnr = 0;
}
// solange kein Abbruch, Wurzelkatalog oder nicht hierarchisch gegliederter Katalog vorliegt
} while (typnr != 0 && typnr != 1 && typnr != 4);
}
// Fehlerbehandlung
catch (SQLException e) {
noError = false;
groupPath = null;
error = e.toString();
}
}
// Ergebnis zurückgeben
return groupPath;
}
Zur Ermittlung der Produktdaten dient die Methode getProduct(String product_id, String group_id, String searchtext, int direction). Durch den bereits angesprochenen Umstand, daß der Aufruf des Servlets sowohl aus dem Navigations-Fenster (Anzeigen des ersten Produktes einer Produktgruppe bzw. entsprechend Suchanfrage) als auch aus dem Produktfenster (Navigation zwischen Produkten einer Produktgruppe oder entsprechend Suchanfrage) heraus erfolgen kann, muß hier eine entsprechende Fallunterscheidung getroffen werden. Desweiteren ist zu Unterscheiden, ob die anzuzeigenden Produkte zu einer Produktgruppe gehören, oder ob sie einem Suchbegriff entsprechen müssen. Entsprechend den hier genannten Kriterien müssen dann die Datenbankabfragen formuliert werden, um daß Ergebnis in Form eines Vector()-Objektes zurückgeben zu können. Der Rückgabewert dieser Methode gibt nach außen hin einen aufgetretenen Fehler zu erkennen, falls er dem NULL-Wert entspricht. Außerdem wird beim Auftreten eines Fehlers auch die globale Fehlervariable noError mit dem Wahrheitswert FALSE belegt. Im nachfolgenden Auszug des Quell-Codes wird das dabei angewendete Vorgehen dargestellt und durch Kommentare erläutert.
// Produktdaten ermitteln
private Vector getProduct(String product_id, String group_id, String searchtext, int direction) {
Vector products = new Vector();
Vector tmp = new Vector();
String query1 = "";
String query2 = "";
String query3 = "";
try {
// Parameterlisten zu Datenbankabfragen initialisieren
String[] param1 = {"PID","BEZEICHNUNG","BESCHREIBUNG","EINHEIT","PREIS_EINHEIT","WAEHRUNG","HID","HPNR","GID","PREIS"};
String[] param2 = {"CNT"};
// Produktdaten ermitteln
// Abfrage zum Produkt aus Navigation-Fenster heraus
if (product_id.equals("")) {
// erstes Produkt für eine Produktgruppe anzeigen
if (searchtext.equals("")) {
// erstes Produkt des Gesamtbestandes anzeigen
if (group_id.equals("")) {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND ORDER BY p.pid";
}
// erstes Produkt einer Gruppe/Untergruppe anzeigen
else {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND j.gid=" + group_id + " ORDER BY p.pid";
}
}
// erstes Produkt entspr. Suchanfrage anzeigen
else {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND UPPER(p.bezeichnung) LIKE UPPER('%" + searchtext + "%') ORDER BY p.pid";
}
}
// Aufruf aus Produktfenster heraus, d.h. nächstes/voriges Produkt anzeigen
else {
// Produkt einer Produktgruppe anzeigen
if (searchtext.equals("")) {
// Produkt aus Gesamtbestand anzeigen
if (group_id.equals("")) {
// nächstes Produkte des Gesamtbestandes
if (direction == 1) {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND j.pid>" + product_id + " ORDER BY p.pid";
}
// voriges Produkte des Gesamtbestandes
else {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND j.pid<" + product_id + " ORDER BY p.pid DESC";
}
}
// Produkt einer Produktgruppe anzeigen
else {
// nächstes Produkt einer Gruppe/Untergruppe
if (direction == 1) {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND j.gid=" + group_id + " AND j.pid>" + product_id + " ORDER BY p.pid";
}
// voriges Produkt einer Gruppe/Untergruppe
else {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND j.gid=" + group_id + " AND j.pid<" + product_id + " ORDER BY p.pid DESC";
}
}
}
// Produkt entspr. Suchanfrage anzeigen
else {
// nächstes Produkt entspr. Suchanfrage
if (direction == 1) {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND UPPER(p.bezeichnung) LIKE UPPER('%" + searchtext + "%') AND j.pid>" + product_id + " ORDER BY p.pid";
}
// voriges Produkt entspr. Suchanfrage
else {
query1 = "SELECT p.*, j.gid, j.preis FROM produkt p, join_g_p j WHERE p.pid=j.pid AND UPPER(p.bezeichnung) LIKE UPPER('%" + searchtext + "%') AND j.pid<" + product_id + " ORDER BY p.pid DESC";
}
}
}
// Queries zum Zählen der Datensätze und der aktuellen Datensatznummer generieren
// Produktanzahl und Position entspr. Produktgruppe oder Gesamtbestand
if (searchtext.equals("")) {
// Produktanzahl und Position des Gesamtbestandes
if (group_id.equals("")) {
// Gesamtzahl
query2 = "SELECT COUNT(pid) cnt FROM produkt";
// dient der Berechnung der aktuellen Position gemessen an Gesamtzahl
query3 = "SELECT COUNT(pid) cnt FROM produkt WHERE pid<";
}
// Produktanzahl und Position einer Produktgruppe
else {
// Gesamtzahl
query2 = "SELECT COUNT(j.pid) cnt FROM produkt p, join_g_p j WHERE p.pid=j.pid AND j.gid=" + group_id;
// dient der Berechnung der aktuellen Position gemessen an Gesamtzahl
query3 = "SELECT COUNT(j.pid) cnt FROM produkt p, join_g_p j WHERE p.pid=j.pid AND j.gid=" + group_id + " AND j.pid<";
}
}
// Produktanzahl und Position entspr. Suchanfrage
else {
// Gesamtzahl
query2 = "SELECT COUNT(pid) cnt FROM produkt WHERE UPPER(bezeichnung) LIKE UPPER('%" + searchtext + "%')";
// dient der Berechnung der aktuellen Position gemessen an Gesamtzahl
query3 = "SELECT COUNT(pid) cnt FROM produkt WHERE UPPER(bezeichnung) LIKE UPPER('%" + searchtext + "%') AND pid<";
}
// Queries ausführen
products = dbcon.OraDBgetResult(query1, param1, 1);
// wenn Ergebnismenge nicht leer, dann Position und Gesamtanzahl ermitteln
if (products != null) {
// Gesamtanzahl ermitteln
tmp = dbcon.OraDBgetResult(query2, param2, 1);
// wenn Ergebnismenge nicht leer, dann Wert zur Berechnung edr Position ermitteln
if (tmp != null) {
// Gesamtanzahl abspeichern
products.addElement(tmp.elementAt(0));
// wenn gültige Gesamtanzahl
if (!((String)products.elementAt(0)).equals("")) {
// query3 um aktuelle Produkt-ID ergänzen
query3 += (String)products.elementAt(0);
// Agfrage ausführen
tmp = dbcon.OraDBgetResult(query3, param2, 1);
// wenn Ergebnismenge nicht leer
if (tmp != null) {
// ermittelten Wert abspeichern
products.addElement(tmp.elementAt(0));
}
else products.addElement("0");
}
else products.addElement("0");
}
}
}
// Fehlerbehandlung
catch (SQLException e) {
noError = false;
products = null;
error = e.toString();
}
// Ergebnis zurückgeben
return products;
}
Die Methode getPicture(String product_id) generiert schließlich eine Tabelle im HTML-Format, deren Inhalt aus Links zu den Produktbildern besteht. Als Parameter muß dieser Methode die entsprechende Produkt-ID zur Ermittlung der Links per Datenbankabfrage übergeben werden. Der Rückgabewert dieser Methode dient der Ersetzung des Platzhalters @picture@ der vorgefertigten HTML-Seite und gibt nach außen hin einen aufgetretenen Fehler zu erkennen, falls er dem NULL-Wert entspricht. Außerdem wird beim Auftreten eines Fehlers auch die globale Fehlervariable noError mit dem Wahrheitswert FALSE belegt. Nachfolgend ein Auszug aus dem Quell-Code, der diese Methode genauer beschreibt.
// Generierung einer HTML-Tabelle mit den Links zu den Produktbildern
private String getPicture(String product_id) {
Vector pictures = new Vector();
Vector tmp = new Vector();
String result = "";
try {
// parameterliste zur Datenbankabfrage initialisieren
String[] param1 = {"QUELLE"};
// Abfrage ausführen
tmp = dbcon.OraDBgetResult("SELECT quelle FROM bilder WHERE pid=" + product_id, param1, 0);
// falls kein Bild für Produkt vorhanden ist
if (tmp == null) {
// Standardbild zuweisen
pictures.addElement("../images/no_pic.jpg");
}
// Bildinformationen (Links) zuweisen
else {
pictures = tmp;
}
// Ergebnismenge ins HTML-Tabellenformat umwandeln
String[] param2 = {"","","<IMG src=\"","\" width=300>"};
result = pageGen.formatTable(pictures, 1, param2);
}
// Fehlerbehandlung
catch (SQLException e) {
noError = false;
error = e.toString();
result = null;
}
// Ergebnis zurückgeben
return result;
}