JavaRush /Java-Blog /Random-DE /Erstellen einer einfachen Webanwendung mit Servlets und J...
Стас Пасинков
Level 26
Киев

Erstellen einer einfachen Webanwendung mit Servlets und JSP (Teil 1)

Veröffentlicht in der Gruppe Random-DE
Erforderlicher Wissensstand zum Verständnis des Artikels: Sie haben Java Core bereits mehr oder weniger verstanden und möchten sich mit JavaEE-Technologien und Webprogrammierung befassen. Dies ist am sinnvollsten, wenn Sie sich gerade mit der Quest „Java-Sammlungen“ befassen, die Themen abdeckt, die dem Artikel nahe stehen. Erstellen einer einfachen Webanwendung mit Servlets und JSP (Teil 1) – 1Dieses Material ist eine logische Fortsetzung meines Artikels „Erstellen eines einfachen Webprojekts in IntelliJ Idea Enterprise“ . Darin habe ich gezeigt, wie man eine funktionierende Webprojektvorlage erstellt. Dieses Mal zeige ich Ihnen, wie Sie mit den Technologien Java Servlet API und JavaServer Pages API eine einfache, aber hübsche Webanwendung erstellen. Unsere Anwendung wird eine Homepage mit zwei Links haben:
  • zur Seite zum Hinzufügen des Benutzers;
  • zur Seite mit der Benutzerlistenansicht.
Ich werde weiterhin IntelliJ Idea Enterprise Edition, Apache Maven (nur ein paar Abhängigkeiten einschließen) und Apache Tomcat verwenden. Am Ende werden wir unsere Anwendung mit dem W3.CSS- Framework „dekorieren“ . Wir gehen davon aus, dass Sie im Moment bereits ein leeres Projekt haben, das wir hier entwickeln werden. Wenn nicht, gehen Sie den ersten Artikel durch und erstellen Sie ihn. Es dauert nur ein paar Minuten :)

Ein wenig über die Struktur der zukünftigen Anwendung

Unsere Hauptseite ( / ) wird die gewöhnlichste statische HTML-Seite mit einer Kopfzeile und zwei Links/Schaltflächen sein:
  • einen neuen Benutzer hinzufügen (wird an /add gesendet );
  • Sehen Sie sich die Liste der Benutzer an (sendet an /list ).
Tomcat fängt Anfragen an diese Adressen ab und sendet sie an eines der beiden Servlets, die wir erstellen werden (wir werden die Zuordnung in der Datei web.xml beschreiben ). Und die Servlets wiederum verarbeiten Anfragen, bereiten Daten vor (oder speichern sie, wenn ein Benutzer hinzugefügt wird) und übertragen die Kontrolle an die entsprechenden JSP-Dateien, die das Ergebnis bereits „rendern“. Wir speichern die Daten in der am häufigsten verwendeten Liste (Liste).

Lassen Sie uns eine statische Homepage erstellen

Wenn sich index.jsp in Ihrem Webordner befindet , löschen Sie es. Stattdessen erstellen wir in diesem Ordner eine einfache HTML-Datei namens index.html :
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My super project!</title>
</head>
<body>
    <!-- header -->
    <div>
        <h1>Super app!<//h1>
    </div>

    <div>       <!-- content -->
        <div>    <!-- buttons holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
Hier gibt es nichts Kompliziertes. Im Titel geben wir den Titel unserer Seite an. Im Hauptteil der Seite haben wir zwei Haupt-Divs: Header (Header) und Content (Inhalt). Im Inhalt haben wir einen Halter für unsere Buttons, und zwar zwei Buttons, die beim Anklicken an die entsprechenden Adressen gesendet werden. Sie können das Projekt ausführen und sehen, wie es jetzt aussieht. Wenn Sie auf die Schaltflächen klicken, öffnen sich Seiten mit einem 404-Fehler, da wir sie noch nicht haben. Dies deutet jedoch darauf hin, dass die Tasten funktionieren. Ich möchte anmerken, dass dies nicht die universellste Option ist, denn wenn Sie JavaScript plötzlich deaktiviert haben, sind diese Schaltflächen im Browser nutzlos. Aber wir gehen davon aus, dass niemand JavaScript deaktiviert hat :). Es ist klar, dass einfache Links verwendet werden könnten, aber ich bevorzuge Schaltflächen. Du machst das, was Dir am besten gefällt. Und denken Sie nicht daran, dass es in meinen Beispielen viele Divs geben wird . Dann werden wir sie mit Stilen füllen und alles wird schöner aussehen :).

Erstellen Sie JSP-Dateien, um das Ergebnis darzustellen

Im selben Webverzeichnis erstellen wir einen Ordner, in dem wir unsere JSP-Dateien ablegen . Ich habe es Ansichten genannt, und auch hier kann man improvisieren. In diesem Ordner erstellen wir zwei JSP-Dateien:
  • add.jsp – Seite zum Hinzufügen von Benutzern;
  • list.jsp – Seite zum Anzeigen einer Benutzerliste.
Geben wir ihnen die passenden Seitenüberschriften. Etwas wie „Neuen Benutzer hinzufügen“ und „Benutzerliste“, und wir belassen es vorerst dabei.

Lassen Sie uns zwei Servlets erstellen

Servlets akzeptieren und verarbeiten Anfragen, die Tomcat an sie weiterleitet. Im Ordner src/main/java erstellen wir ein App- Paket , das unsere Quellen enthält. Dort werden wir weitere verschiedene Pakete haben. Damit diese Pakete nicht ineinander erstellt werden, erstellen wir daher eine Klasse im App- Paket (und löschen sie dann). Lassen Sie uns nun drei verschiedene Pakete im App- Paket erstellen:
  • Entitäten – hier liegen unsere Entitäten (die Klasse selbst, die Benutzerobjekte beschreibt);
  • Modell – unser Modell wird hier sein (mehr dazu später);
  • Servlets - nun, hier werden unsere Servlets sein.
Danach können Sie diese Klasse sicher aus dem App- Paket entfernen (natürlich nur, wenn Sie sie erstellt haben). Im Servlets- Paket erstellen wir zwei Klassen:
  • AddServlet – verarbeitet Anfragen, die unter /add eingehen ;
  • ListServlet – verarbeitet Anfragen, die unter /list eingehen .

Abhängigkeiten in Maven verbinden

Tomcat Version 9.* implementiert die Spezifikationen Servlet Version 4.0 und JavaServer Pages Version 2.3. Dies steht in der offiziellen Dokumentation von Tomcat 9 im ersten Absatz in der zweiten Zeile. Das heißt, wenn Sie, wie ich, diese Version von Tomcat verwenden, verwendet der Code, den wir schreiben und zur Ausführung senden, genau die angegebenen Versionen. Aber wir möchten diese Spezifikationen in unserem Projekt haben, damit unser Code, der sie verwendet, zumindest erfolgreich kompiliert werden kann. Und dafür müssen wir sie in unser Projekt laden. Hier kommt Maven zur Rettung.

Die allgemeine Regel lautet: Wenn Sie mithilfe von Maven etwas mit Ihrem Projekt verbinden müssen:

  • Gehen Sie zur Maven-Repository-Website.
  • Suchen Sie dort nach der benötigten Bibliothek und der benötigten Version;
  • Sie erhalten den Abhängigkeitscode, der in Ihre pom.xml eingefügt werden muss;
  • einfügen! :) :)
Also fangen wir an. Bereiten wir zunächst eine POM-Datei vor . Fügen Sie irgendwo nach /version , aber vor /project Folgendes ein:
<dependencies>

</dependencies>
Daher haben wir angegeben, dass wir in diesen Tags die Abhängigkeiten auflisten, die wir benötigen. Gehen Sie nun zu mvnrepository.com . Oben befindet sich ein Suchfeld. Geben Sie zunächst Servlet in die Suche ein. Das erste Ergebnis, bei dem es mehr als siebentausend Verwendungsmöglichkeiten gibt, passt zu uns. Wir erinnern uns, dass wir Version 4.0 benötigen (für Tomcat 9; für andere Versionen sind möglicherweise ältere Implementierungen geeignet). Dies ist eine relativ neue Version, daher gibt es nicht viele Verwendungsmöglichkeiten, aber es ist die, die wir brauchen. Es öffnet sich eine Seite, auf der Sie den Code für diese Abhängigkeit für verschiedene Paketmanager erhalten und ihn sogar einfach herunterladen können. Da wir es aber über Maven anbinden wollen, wählen wir den Code auf der Registerkarte Maven aus. Wir kopieren es und fügen es in unsere POM-Datei im Abschnitt „Abhängigkeiten“ ein. Wenn in der unteren rechten Ecke von IDEA eine Benachrichtigung erscheint, in der Sie gefragt werden, ob wir den automatischen Import aktivieren möchten, stimmen wir zu. Wenn Sie versehentlich abgelehnt haben, gehen Sie zu „Einstellungen“ und aktivieren Sie den automatischen Import manuell: Einstellungen (Strg + Alt + S) -> Build, Ausführung, Bereitstellung -> Maven -> Importieren. Dadurch bleiben die POM-Datei und die IDEA-Konfigurationsdateien dafür erhalten Projekt synchron. Nach dem gleichen Prinzip werden wir nun JavaServer Pages Version 2.3 finden und verbinden (geben Sie jsp in die Suche ein). Und da wir uns bereits mit Maven beschäftigt haben, sagen wir ihm gleich, dass unsere Quellen der Java-8-Syntax entsprechen und in Bytecode derselben Version kompiliert werden müssen. Nach all diesen Manipulationen wird unsere pom.xml etwa so aussehen:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ru.javarush.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compile.source>
        <maven.compiler.target>1.8</maven.compile.target>
    </properties>

    <dependencies>
        <!-- Servlet API 4.0 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JavaServer Pages API 2.3 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

Damit unsere Servlets echte Servlets werden

Zu diesem Zeitpunkt handelt es sich bei den von uns erstellten Servlets eigentlich nur um reguläre Klassen. Sie haben keine Funktionalität. Aber jetzt haben wir die Servlet-API mit unserem Projekt verbunden und können in diesem Fall Klassen von dort verwenden. Um unsere Servlets zu „echten“ Servlets zu machen, müssen wir sie lediglich von der HttpServlet- Klasse erben .

Zuordnung oder Partitionierung

Jetzt wäre es schön, Tomcat irgendwie mitzuteilen, dass Anfragen von /add von unserem AddServlet- Servlet verarbeitet werden und Anfragen von /list daher vom ListServlet- Servlet verarbeitet werden . Dieser Vorgang wird Mapping genannt . Dies erfolgt in der Datei web.xml nach diesem Prinzip:
  • Zuerst beschreiben wir das Servlet (wir geben einen Namen und geben den Pfad zur Klasse selbst an);
  • Dann binden wir dieses Servlet an eine bestimmte Adresse (wir geben den Namen des Servlets an, das wir ihm gerade gegeben haben, und geben die Adresse an, von der aus Anfragen an dieses Servlet gesendet werden sollen).
Beschreiben wir das Servlet:
<servlet>
    <servlet-name>add</servlet-name>
    <servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
Jetzt binden wir es an die Adresse:
<servlet-mapping>
    <servlet-name>add</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
Wie Sie sehen, ist der Servlet-Name in beiden Fällen derselbe. Dadurch weiß Tomcat, dass, wenn eine Anfrage an die Adresse /add kommt, diese an das Servlet app.servlets.AddServlet weitergeleitet werden muss . Dasselbe machen wir mit dem zweiten Servlet. Dadurch hat unsere web.xml ungefähr folgenden Inhalt:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- add servlet -->
    <servlet>
        <servlet-name>add</servlet-name>
        <servlet-class>app.servlets.AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>add</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>

    <!-- list servlet -->
    <servlet>
        <servlet-name>list</servlet-name>
        <servlet-class>app.servlets.ListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>list</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>
</web-app>
Übrigens haben wir hier (unter / ) kein Markup für die Hauptseite erstellt. Tatsache ist, dass wir es in diesem Fall nicht brauchen. Unsere Homepage ist eine einfache HTML-Datei , die lediglich zwei Schaltflächen anzeigt. Es gibt keinen dynamischen Inhalt, daher macht es für uns keinen Sinn, dafür ein separates Servlet zu erstellen, an das Anfragen von der Adresse / gesendet werden und das nichts anderes tut, als die Ausführung an eine JSP zu übertragen (was auch sein müsste). erstellt), was zeichnen würde, wenn wir nur zwei Knöpfe hätten. Wir brauchen das nicht; wir sind mit einer statischen Ressource zufrieden. Wenn Tomcat eine Anfrage erhält, prüft es, ob es kein einziges Servlet gibt, das die Anfrage an einer solchen Adresse verarbeiten könnte, und erkennt dann, dass an dieser Adresse tatsächlich eine fertige HTML-Datei vorhanden ist , die erfolgreich gesendet wird . Wir können unsere Anwendung erneut ausführen (den Server neu starten oder nach Wunsch erneut bereitstellen) und sicherstellen, dass die Hauptseite gerendert wird und nichts kaputt geht. Wenn wir auf die Schaltflächen klicken, treten Übergänge auf, aber im Moment liegt auch ein Fehler vor geschrieben. Übrigens, wenn wir zuvor einen 404-Fehler hatten, haben wir jetzt einen 405-Fehler. Das bedeutet, dass die Zuordnung funktioniert hat, die Servlets gefunden wurden, aber sie hatten einfach keine geeigneten Methoden, um die Anfrage zu verarbeiten. Wenn Sie zu diesem Zeitpunkt immer noch einen 404-Fehler erhalten, obwohl alles korrekt durchgeführt wurde, sollten Sie möglicherweise die Bereitstellungskonfiguration in der Idee korrigieren. Dazu müssen Sie zu „Konfigurationen bearbeiten“ gehen (oben neben der Startschaltfläche), zur Registerkarte „Bereitstellung“ auf der rechten Seite des Fensters gehen und sicherstellen, dass im Anwendungskontext einfach „/“ angezeigt wird.

Ein kurzer lyrischer Exkurs: Was passiert „unter der Haube“?

Sie haben sich wahrscheinlich schon gefragt, wie unsere Anwendung in Tomcat funktioniert? Was ist da los? Und wo ist die main()- Methode ? Sobald Sie „localhost:8080“ in Ihren Browser eingeben und diese Adresse aufrufen, sendet der Browser über das http- Protokoll eine Anfrage an diese Adresse . Ich hoffe, Sie wissen bereits, dass Anfragen unterschiedlicher „Art“ sein können, wobei GET und POST am beliebtesten sind . Auf jede Anfrage muss es eine Antwort geben. Die GET-Anfrage erwartet, dass sie als Antwort einen vorgefertigten HTML-Code erhält , der an den Browser zurückgegeben wird, und der Browser ersetzt diesen Code wunderbar durch alle möglichen Buchstaben, Schaltflächen und Formulare. Die POST-Anfrage ist etwas interessanter, da sie auch einige Informationen mit sich bringt. Beispielsweise haben Sie im Benutzerregistrierungs- oder Autorisierungsformular Ihre Daten eingegeben und auf „Senden“ geklickt. In diesem Moment wurde eine POST-Anfrage mit Ihren persönlichen Daten an den Server gesendet. Der Server hat diese Informationen akzeptiert, verarbeitet und eine Antwort zurückgegeben (z. B. eine HTML-Seite mit Ihrem Profil). Der grundlegende Unterschied zwischen ihnen besteht darin, dass GET-Anfragen nur dazu gedacht sind, Daten vom Server zu empfangen, während POST-Anfragen einige Informationen mit sich führen und sich die Daten auf dem Server ändern können (z. B. wenn Sie Ihr Foto auf den Server hochladen). wird die POST-Anfrage einfliegen und der Server fügt sie der Datenbank hinzu, d Sehen Sie nach, ob es ein geeignetes Servlet gibt, das Anfragen an eine solche Adresse verarbeiten würde (oder eine vorgefertigte Ressource, die sofort zurückgegeben werden kann). Wenn es nichts zum Zurückgeben findet, antwortet es nicht mit einer HTML-Seite, sondern mit einer 404-Antwort. Wenn es ein passendes Servlet findet, das auf dieser Adresse „sitzt“, prüft es, welche Art von Anfrage es erhalten hat (GET, POST oder eine andere) und fragt dann das Servlet, ob es eine Methode dafür hat könnte diese Art von Anfrage verarbeiten. Wenn das Servlet sagt, dass es diese Art nicht verarbeiten kann, antwortet Tomcat dem Client mit dem Code 405. Das ist uns gerade passiert. Wenn jedoch ein geeignetes Servlet gefunden wird und es über eine geeignete Methode verfügt, erstellt Tomcat ein Objekt dieses Servlets, führt es in einem neuen Thread ( Thread ) aus, wodurch das Servlet in einem separaten Thread arbeiten kann, und Tomcat arbeitet weiter in sich selbst, das Empfangen und Senden von Anfragen. Darüber hinaus erstellt Tomcat zwei weitere Objekte: eines vom Typ HttpServletRequest (ich werde es in Zukunft kurz als Anfrage bezeichnen) und das zweite vom Typ HttpServletResponse(Ich nenne es die Antwort). Im ersten Objekt werden alle Daten abgelegt, die es in einer Anfrage vom Client erhalten hat, sodass alle Daten aus diesem Objekt abgerufen werden können. Nun, nach all dem werden diese beiden Objekte an die entsprechende Methode des Servlets übergeben, das in einem separaten Thread ausgeführt wird. Sobald das Servlet seine Arbeit beendet hat und eine Antwort zum Senden an den Client bereit hat, setzt es eine Flagge an Tomcat und sagt: „Ich bin fertig, alles ist bereit.“ Tomcat akzeptiert die Antwort und sendet sie an den Client. Dadurch kann Tomcat ohne Unterbrechung Anfragen annehmen und Antworten senden, während die gesamte Arbeit von Servlets erledigt wird, die in separaten Threads laufen. Wenn wir Servlet-Code schreiben, definieren wir dementsprechend die auszuführende Arbeit. Und ja, Sie können sich die Methode main() so vorstellen , als wäre sie in Tomcat selbst (ja, sie ist in Java geschrieben), und wenn wir Tomcat „starten“, wird die main().

Wir fangen GET-Methoden mit Servlets ab und senden einfache Antworten

Im Moment verfügen unsere Servlets nicht über geeignete Methoden (GET), daher gibt uns Tomcat einen 405-Fehler zurück. Machen wir sie! Die HttpServlet- Klasse , von der wir unsere Servlets erben, definiert verschiedene Methoden. Um Code für Methoden festzulegen, überschreiben wir diese einfach. In diesem Fall müssen wir die doGet()- Methode in beiden Servlets überschreiben .
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
Wie Sie sehen, akzeptiert diese Methode zwei Objekte: req (Anfrage) und resp (Antwort). Dies sind genau die Objekte, die Tomcat für uns erstellt und füllt, wenn es die entsprechende Methode in diesem Servlet aufruft. Lassen Sie uns zunächst die einfachsten Antworten geben. Nehmen Sie dazu das resp- Objekt und erhalten Sie daraus ein PrintWriter- Objekt , das zum Verfassen von Antworten verwendet werden kann. Nun, damit drucken wir eine einfache Zeichenfolge.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("Method GET from AddServlet");
}
Wir machen etwas Ähnliches im ListServlet- Servlet und starten anschließend unseren Server erneut. Wie Sie sehen, funktioniert alles! Wenn Sie auf die Schaltflächen klicken, öffnen sich Seiten mit dem Text, den wir mit PrintWriter „aufgezeichnet“ haben . Es ist nur so, dass unser JSP , das wir zum Generieren von Seiten mit Antworten vorbereitet haben, in keiner Weise verwendet wird. Dies liegt daran, dass die Ausführung sie einfach nicht erreicht. Das Serverlet selbst generiert nun eine Antwort und beendet seine Arbeit, wodurch Tomcat signalisiert wird, dass eine Antwort für den Client bereitsteht. Tomcat nimmt diese Antwort einfach entgegen und sendet sie an den Client zurück. Wir übertragen die Kontrolle von den Servlets an JSP. Ändern wir den Code unserer Methoden folgendermaßen:
  • Wir erhalten vom Anforderungsobjekt ein Anforderungsmanagerobjekt, in dem wir die JSP- Adresse der Seite übergeben, an die wir die Kontrolle übertragen möchten.
  • Mithilfe des empfangenen Objekts übertragen wir die Kontrolle auf die angegebene JSP- Seite und vergessen nicht, dort die Anforderungs- und Antwortobjekte anzuhängen, die wir von Tomcat erhalten haben.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
Im Hauptteil von JSP-Seiten (innerhalb des Hauptteil-Tags) können wir etwas schreiben, damit wir klar erkennen können, welche Seite angezeigt wird. Danach starten wir den Server neu und überprüfen. Schaltflächen auf der Hauptseite werden gedrückt, Seiten werden geöffnet, was bedeutet, dass Anforderungen an Servlets gesendet werden, wonach die Steuerung an JSP-Seiten übertragen wird, die bereits gerendert sind. Das ist alles. Im nächsten Teil des Artikels beschäftigen wir uns mit der Funktionalität unserer Anwendung.

Was gibt es sonst noch zu lesen:

Erstellen eines einfachen Webprojekts in IntelliJ Idea Enterprise. Schritt für Schritt, mit Bildern


Mein Chat
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION