Einträge aus Datenbank einzeln darstellen (JSP, JAVA, HTML)

Schwupsi

Aktives Mitglied
Hallo Leute,

ich programmiere momentan für eine Webseite ein Gästebuch. Der User kann auf der Seite seinen Namen eingeben, einen Betreff und eine Nachricht verfassen. Mit Klicken auf den Absenden-Button werden die drei Werte über einen Controller in die Bean-Klasse übertragen, wo diese anschließend in eine Datenbank-Tabelle eingetragen werden per SQL-Statement.

Die Datenbank-Tabelle sieht so aus:

ID | Name | Betreff | Nachricht | Datum | Status

ID wird bei jedem Eintrag automatisch hochgezählt. Datum wird in einer Methode in der Bean ermittelt und zum Eintrag hinzugefügt. Status ist per Default auf "0" und wird auch mit einer Methode dem Eintrag hinzugefügt. Das ist später für die Freigabe der Einträge nötig (0=nicht freigegeben, 1=freigegeben).

Anschließend hole ich mir mittels Methoden die einzelnen Spalten aus der Tabelle heraus und rufe diese Methoden in der View-Klasse auf:

HTML:
<div id="guestbookentry">
   
   
           <div id="center">
                 <jsp:getProperty property="htmlDatum" name="gb"/>
                 <jsp:getProperty property="htmlName" name="gb"/>
           </div>
           <div id="center">
                 <jsp:getProperty property="htmlBetreff" name="gb"/>
           </div>
                 <jsp:getProperty property="htmlNachricht" name="gb"/>
             
                
</div>

Das Problem hier ist, dass die Methoden aus der View heraus nur einmal aufgerufen werden. Ich möchte aber, dass sie die Methode solange aufruft, bis sie alle Einträge aus der DB hat.
Momentan ist es so, dass eine Ausgabe bei einem Eintrag in der DB so aussieht, wie ich es möchte:

Eingetragen am: 09.03.18
von: Max Mustermann

Betreff: Nachricht 1

Nachricht: blabla1

Bei mehr als einem Eintrag sieht die Ausgabe so aus:

Eingetragen am: 09.03.18
07.03.18
von: Max Mustermann
Maria Musterfrau
Betreff: Nachricht 1
Nachricht2
Nachricht: blabla1
blabla2

Ich müsste es irgendwie hinkriegen, dass die Ausgabe Zeile für Zeile aus der DB erfolgt und nicht alle Daten geholt werden und einfach an den String den ich returne angehängt werden.

Am besten so:
Eingetragen am: 09.03.18
von: Max Mustermann

Betreff: Nachricht 1

Nachricht: blabla1
-------------------------------------------------------------------------------------------------
Eingetragen am: 07.03.18
von: Maria Musterfrau

Betreff: Nachricht 2

Nachricht: blabla2

Den SELECT Befehl für die Nachricht z.B. müsste ich irgendwie umbauen in "SELECT nachricht FROM tabelle WHERE id = " + i;

i wäre <= Anzahl Einträge in der DB und würde dann solange hochgezählt werden.
Aber es bringt mir nichts, wenn ich die Methode nur einmal aufrufen kann.

Ich hoffe ich konnte mein Anliegen einigermaßen verständlich schildern und würde mich über Anregungen und Tipps freuen.

MfG :)
 

Schwupsi

Aktives Mitglied
Java:
<c:forEach items="${alist}" var="listItem">
    ${listItem} <br />
</c:forEach>
http://www.javawebtutor.com/articles/jsp/jstl-foreach-tag.php

Danke dir. Wollte gerade deinen Vorschlag probieren, aber ich kriege JSTL nicht importiert. Habe es mit dem Code
HTML:
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt"%>
probiert, aber er zeigt mir einen Fehler "Can not find the tag library descriptor for "http://java.sun.com/jstl/core_rt"

Wie kriege ich JSTL importiert? Muss ich diese Schritte hier ausführen?
-> https://www.tutorialspoint.com/jsp/jsp_standard_tag_library.htm
 

Schwupsi

Aktives Mitglied
Update: Habe es mit JSTL hinbekommen.
Ich verstehe aber noch nicht so ganz wie du das mit dem forEach meinst.

Ich habe für jeden Wert, den ich darstellen möchte, eine Methode, die einen "String html" zurückliefert.
Für die "Nachricht" habe ich zum Beispiel folgende Methode:

Java:
    public String getHtmlNachricht () {
        String html = "";
        Vector <String> myKeys = this.nachrichtFromDB;       
        Iterator<String> iter = myKeys.iterator();   
       
        while (iter.hasNext()) {
        String mykey = iter.next();              
        html += "<h4>" + mykey + "</h4>" + "<br>";     
        }       
        return html ;       
    }

Für die Werte "Name", "Betreff" und "Datum" sehen die Methoden genauso aus.
Wie kann ich das mit dem forEach Code verknüpfen?
 

looparda

Top Contributor
Ich habe das mit den keys erstmal außen vor gelassen, weil ich es nicht als nötig sehe.
Der GaestebuchController kümmert sich darum die Einträge aus der Datenbank zu holen und stellt eine Liste von Einträgen bereit.
Java:
interface EintragDBO {
    String getNachricht();
}

interface EintraegeRepository {
    List<EintragDBO> getAll();
}

class Eintrag {

    private String nachricht;

    public Eintrag(EintragDBO eintragDBO) {
        this.nachricht = eintragDBO.getNachricht();
    }

    public String getHtmlNachricht () {
        //TODO: escape html to prevent XSS and other attacks
        return this.nachricht;
    }

    // ... andere getter
}

class GaestebuchController {

    private List<Eintrag> eintraege;

    public GaestebuchController(EintraegeRepository eintraegeRepository) {
        this.eintraege = new ArrayList<>();
        // Datenbank-Objekte laden
        List<EintragDBO> eintragDBOs = eintraegeRepository.getAll();
        // Trennung von Datenbank-Objekten und Objekten auf denen die Applikations-Logik arbeitet.
        for (EintragDBO eintragDBO: eintragDBOs) {
            this.eintraege.add( new Eintrag( eintragDBO ));
        }
    }

    public List<Eintrag> getEintraege() {
        return eintraege;
    }

}
Im JSP machst du deine Darstellung wie die Daten angezeigt werden sollen. Das ist für jeden Eintrag ja das gleiche Format. Deshalb eine Schleife über alle Einträge. Nur die Daten werden im Template ausgetauscht.
Code:
<c:forEach items="${gaestebuchController.getEintraege()}" var="eintrag">
<h4>Eingetragen am:</h4> ${eintrag.getDatum()}
<h4>von:</h4> ${eintrag.getVon()}
<h4>Betreff:</h4> ${eintrag.getBetreff()}
<h4>Nachricht:</h4> ${eintrag.getNachricht()}
<br />
</c:forEach>
So ist das Prinzip - die genaue Implementierung fehlt. Vor allem beim JSP kenne ich mich nicht aus und weiß nicht wie genau man es schreibt. Aber es geht ja nur darum zu zeigen wie es ablaufen kann. Den gaestebuchController muss man ins JSP injizieren - aber das müsstest du auch schon bei deinem vorherigen Template für den einzelnen Eintrag gemacht haben.
 

mrBrown

Super-Moderator
Mitarbeiter
Wenn ich mir den Code so angucke und an das dahinterliegende Design denke, offenbart das ziemliche Lücken in den Grundlagen (und eine zum Himmel schreiende XSS-Lücke) :/
 

Schwupsi

Aktives Mitglied
Wenn ich mir den Code so angucke und an das dahinterliegende Design denke, offenbart das ziemliche Lücken in den Grundlagen (und eine zum Himmel schreiende XSS-Lücke) :/
Danke für den Hinweis :)
Habe aber das XSS-Problem im Hinterkopf und werde das nachträglich fixen. Wollte erstmal mein Problem hier aus der Welt kriegen, mit dem Ziehen einzelner Gästebucheinträge. Aber habe es nun hinbekommen.

Danke an looparda für die großartige Hilfe!
 

looparda

Top Contributor
Ich möchte noch anmerken, dass das Mappen von dbo -> Applikations-Modell nicht in den Controller gehört sondern eher in das Repository. Sofern man da überhaupt eine Trennung für Datenklassen und Applikations-Modell haben möchte oder je nachdem welche Architektur man hat. Und statt dem kompletten Controller in JSP zu injizieren reicht es nur die Liste der Einträge zu übergeben.

@mrBrown galt deine Antwort mir?
 

Ähnliche Java Themen

Neue Themen


Oben