CodeGym /Java Blog /Willekeurig /Een eenvoudige webapplicatie maken met behulp van servlet...
John Squirrels
Niveau 41
San Francisco

Een eenvoudige webapplicatie maken met behulp van servlets en JSP's (deel 1)

Gepubliceerd in de groep Willekeurig
Kennis die nodig is om het artikel te begrijpen: U heeft Java Core al min of meer door en wilt JavaEE-technologieën en webprogrammering bekijken . Het zou voor u het meest logisch zijn om momenteel de Java Collections-zoektocht te bestuderen , die onderwerpen behandelt die dicht bij het artikel staan.
Een eenvoudige webapplicatie maken met behulp van servlets en JSP's (deel 1) - 1
Dit materiaal is de logische voortzetting van mijn artikel Het eenvoudigste webproject maken in IntelliJ Idea Enterprise . In dat artikel heb ik laten zien hoe je een werkende webprojectsjabloon kunt maken. Deze keer laat ik je zien hoe je een eenvoudige maar totaal aantrekkelijke webapplicatie kunt maken met behulp van de Java Servlet API en de JavaServer Pages API . Onze applicatie heeft een startpagina met twee links:
  • een link naar een pagina om gebruikers toe te voegen;
  • een link naar de lijst met gebruikers.
Net als voorheen zal ik IntelliJ Idea Enterprise Edition , Apache Maven (we zullen alleen enkele afhankelijkheden verbinden) en Apache Tomcat gebruiken . Uiteindelijk zullen we onze applicatie "verfraaien" met behulp van het W3.CSS- framework. We gaan ervan uit dat u al een leeg project heeft waaraan we nu iets gaan toevoegen. Zo niet, neem dan het eerste artikel door en maak er een. Het duurt maar een paar minuten :)

Iets over de structuur van onze toekomstige applicatie

Onze startpagina (/) zal een gewone statische HTML- pagina zijn met een koptekst en twee links/knoppen:
  • een nieuwe gebruiker toevoegen (navigeert naar / toevoegen );
  • bekijk de lijst met gebruikers (navigeert naar / lijst ).
Tomcat vangt verzoeken voor deze adressen op en stuurt ze naar een van de twee servlets die we gaan maken (we specificeren de mapping in web.xml ). De servlets verwerken vervolgens de verzoeken, bereiden gegevens voor (of slaan gegevens op als we een gebruiker toevoegen) en dragen de controle over aan de juiste JSP-bestanden , die vervolgens het resultaat 'weergeven'. We slaan de gegevens op in een eenvoudige lijst (Lijst).

Maak een statische startpagina

Als u index.jsp in uw webmap heeft, verwijdert u deze. Maak in plaats daarvan een eenvoudig HTML-bestand met de naam index.html in deze map:

<!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>    <!-- button holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
Er is hier niets ingewikkelds. In de title tag geven we de titel van onze pagina aan. In de hoofdtekst van de pagina hebben we twee hoofddivisies: header en content . De content div bevat een houder voor onze buttons. En daar hebben we twee knoppen die je met een klik naar het bijbehorende adres brengen. U kunt het project uitvoeren en zien hoe het er nu uitziet. Als u op de knoppen klikt, krijgt u pagina's met een 404-fout, omdat de bijbehorende pagina's nog niet bestaan. Maar we kunnen zien dat de knoppen werken. Merk op dat dit niet de meest universele benadering is: als JavaScript is uitgeschakeld in de browser, werken deze knoppen niet. Maar we gaan ervan uit dat niemand JavaScript uitschakelt. :) Uiteraard kun je volstaan ​​met eenvoudige links, maar ik geef de voorkeur aan knoppen. Je kunt het doen zoals je wilt. En maak je geen zorgen over het feit dat mijn voorbeelden veel divs zullen hebben . We vullen ze later met stijlen en alles ziet er mooier uit. :)

Maak JSP-bestanden om het resultaat weer te geven

Maak in dezelfde webdirectory een map aan waarin we onze JSP-bestanden zullen toevoegen . Ik noemde het ' views ', maar nogmaals, je kunt improviseren. In deze map maken we twee JSP-bestanden:
  • add.jsp — een pagina voor het toevoegen van gebruikers;
  • list.jsp — pagina om de lijst met gebruikers weer te geven.
Wijs er de juiste paginakopteksten aan toe. Iets als " Nieuwe gebruiker toevoegen " en " Gebruikerslijst ", en we laten het zo.

Maak twee servlets

Servlets zullen de verzoeken die Tomcat hen stuurt ontvangen en verwerken. Maak in de map src/main/java het app- pakket, waar we onze broncode zullen plaatsen. Daar gaan ook andere pakketten heen. Dus om te voorkomen dat deze pakketten in elkaar worden gemaakt, maken we een klasse in het app- pakket (we zullen het later verwijderen). Maak nu drie verschillende pakketten in het app- pakket:
  • entiteiten - onze entiteiten (de klasse die gebruikersobjecten beschrijft) komen hier;
  • model - dit is waar ons model naartoe gaat (we zullen hier later over praten);
  • servlets - en dit is waar onze servlets naartoe gaan.
Als je dit eenmaal hebt gedaan, kun je die klas rustig uit het app- pakket verwijderen (als je het natuurlijk hebt gemaakt). Maak in het servlets -pakket twee klassen:
  • AddServlet — verwerkt verzoeken die zijn verzonden naar / toevoegen ;
  • ListServlet — verwerkt verzoeken die zijn verzonden naar / list .

Afhankelijkheden verbinden in Maven

Tomcat 9. * implementeert de specificaties voor Servlet 4.0 en JavaServer Pages 2.3 . Dat staat in de tweede regel van de eerste alinea van de officiële documentatie van Tomcat 9. Dit betekent dat als je, zoals ik, deze versie van Tomcat gebruikt , de code die je gaat schrijven en uitvoeren deze versies zal gebruiken. Maar we zouden deze specificaties graag in ons project willen hebben, zodat onze code, die ze gebruikt, in ieder geval succesvol kan worden gecompileerd. En om dit te doen, moeten we ze in ons project laden. Dit is waar Maven te hulp schiet.

De algemene regel is deze: als u iets met uw project moet verbinden met Maven:

  • ga naar de repository-website van Maven;
  • zoeken naar de vereiste versie van de vereiste bibliotheek;
  • haal de afhankelijkheidscode op die in uw pom.xml moet worden geplakt;
  • Plakken! :)
Laten we beginnen. Bereid eerst het POM-bestand voor . Voeg ergens na het item /version , maar vóór /project het volgende in:

<dependencies>

</dependencies>
We doen dit om aan te geven dat we de vereiste afhankelijkheden binnen deze tags zullen vermelden. Ga nu naar mvnrepository.com . Bovenaan is een zoekveld. Zoek om te beginnen naar ' servlet '. Het eerste resultaat, dat meer dan zevenduizend keer is gebruikt, bevalt ons. Vergeet niet dat we versie 4.0 nodig hebben (voor Tomcat 9). Andere versies kunnen geschikt zijn voor oudere implementaties. Dit is een vrij recente versie, dus er zijn niet zoveel toepassingen. Maar we hebben het nodig. Er wordt een pagina geopend waar u de code voor deze afhankelijkheid kunt krijgen voor verschillende pakketbeheerders, of u kunt deze eenvoudig downloaden. Maar aangezien we het willen verbinden met Maven, selecteren we de code op het tabblad Maven. We kopiëren en plakken in het afhankelijkheidsgedeelte van ons POM-bestand. Als je een melding krijgt met de vraag of je automatisch importeren wilt inschakelen in de rechter benedenhoek van IDEA , ga je gang en ga je ermee akkoord. Als je per ongeluk hebt geweigerd, ga dan naar " Instellingen " en schakel handmatig automatisch importeren in: Instellingen (Ctrl + Alt + S) -> Build, Execution, Deployment -> Maven -> Importing .en de IDEA-configuratiebestanden voor dit project gesynchroniseerd. Volgens hetzelfde principe zullen we JavaServer Pages 2.3 vinden en verbinden (zoek naar "JSP"). En aangezien we al met Maven zijn begonnen, laten we zeggen dat onze bronbestanden de Java 8-syntaxis volgen en dat we ze voor die versie in bytecode moeten compileren. Na al deze stappen ziet onze pom.xml er ongeveer zo uit:

<?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>cc.codegym.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compile.source>1.8</maven.compile.source>
        <maven.compile.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>

Maak van onze servlets echte servlets

Op dit moment zijn het paar servlets dat we hebben gemaakt eigenlijk gewone klassen. Ze hebben geen functionaliteit. Maar nu hebben we de Servlet-API aan ons project gekoppeld en kunnen we de bijbehorende klassen gebruiken. Om onze servlets "echt" te maken, hoeven we ze alleen maar de klasse HttpServlet te laten erven .

In kaart brengen of markeren

Nu zou het leuk zijn om Tomcat op de een of andere manier te vertellen dat aanvragen voor het / add- adres worden verwerkt door onze AddServlet , en verzoeken voor het / list- adres worden afgehandeld door de ListServlet . Dit proces wordt mapping (opmaak) genoemd. Dit gebeurt in web.xml volgens hetzelfde principe:
  • beschrijf om te beginnen de servlet (geef een naam en specificeer het pad naar de klasse zelf);
  • bind vervolgens deze servlet aan een specifiek adres (specificeer de naam van de servlet, die we hem zojuist hebben gegeven, en specificeer het adres waarvan de verzoeken naar deze servlet moeten worden verzonden).
Beschrijf de servlet:

<servlet>
    <servlet-name>add</servlet-name>
    <servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
Bind het nu aan het adres:

<servlet-mapping>
    <servlet-name>add</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
Zoals u kunt zien, is servletnaam in beide gevallen hetzelfde. Hierdoor weet Tomcat dat als een verzoek voor /add wordt ontvangen, dit naar de app.servlets.AddServlet moet worden gestuurd. We doen hetzelfde met de tweede servlet. Uiteindelijk heeft onze web.xml ongeveer de volgende inhoud:

<?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>
We hebben trouwens geen markeringen gemaakt voor de startpagina (/). Feit is dat we het in dit geval niet nodig hebben. Onze startpagina is een eenvoudig HTML-bestand dat slechts twee knoppen weergeeft. Het heeft geen dynamische inhoud, dus we hoeven geen aparte servlet te maken voor verzoeken van / die niets anders doen dan de uitvoering doorsturen naar een JSP (die ook zou moeten worden gemaakt) om twee knoppen voor ons te tekenen. We hebben dit niet nodig. Een statische pagina past bij ons. Wanneer Tomcat een verzoek ontvangt, zal het controleren of er een enkele servlet is die het verzoek voor dat adres kan verwerken, en zal vervolgens zien dat dit adres al het kant-en-klare HTML- bestand bevat, die het zal serveren. We kunnen onze applicatie opnieuw uitvoeren (de server opnieuw opstarten of opnieuw implementeren - wat u maar wilt) en ervoor zorgen dat de startpagina wordt weergegeven, er niets kapot gaat en dat de overgangen plaatsvinden wanneer we op de knoppen klikken (hoewel we opnieuw een foutmelding krijgen). Trouwens, terwijl we voorheen een 404-fout kregen, krijgen we nu een 405. Het betekent dat de mapping werkte en de servlets werden gevonden, maar ze hadden geen geschikte methode om het verzoek te verwerken.

Korte uitweiding: wat gebeurt er "onder de motorkap"?

Je hebt waarschijnlijk al nagedacht over hoe onze applicatie werkt in Tomcat. Wat gebeurt daarbinnen? En waar is de methode main()? Zodra je in je browser naar localhost:8080 gaat, stuurt de browser via het HTTP-protocol een verzoek naar dit adres. Ik hoop dat je al weet dat er veel verschillende soorten verzoeken zijn, en de meest populaire zijn GET en POST. Elk verzoek moet worden beantwoord. Van een GET-verzoek wordt verwacht dat het een antwoord ontvangt van kant-en-klare HTML-code, teruggestuurd naar de browser. De browser vervangt vervolgens de code door alle mooie letters, knoppen en formulieren. Een POST-verzoek is iets interessanter, omdat het ook wat informatie bevat. Stel dat u referenties invoert in een registratie- of aanmeldingsformulier op een website en op "Verzenden" klikt. Hierdoor wordt een POST-verzoek met uw persoonlijke gegevens naar de server verzonden. De server ontvangt deze informatie, verwerkt deze en stuurt een reactie terug (bijvoorbeeld een HTML-pagina met uw profiel). Het belangrijkste verschil tussen beide is dat GET-verzoeken alleen worden gebruikt om gegevens van de server op te halen, terwijl POST-verzoeken enige informatie bevatten (en de gegevens op de server kunnen veranderen). Wanneer u bijvoorbeeld uw foto naar de server uploadt, wordt deze daarheen vervoerd in een POST-verzoek en de server voegt deze toe aan de database, dwz er vindt een wijziging plaats. Nu terug naar Tomcat. Wanneer het een verzoek van een klant ontvangt, kijkt het naar het adres. Het controleert of er een geschikte servlet is om verzoeken voor dat adres te verwerken (of een beschikbare bron die onmiddellijk kan worden geretourneerd). Als het niets vindt om terug te keren, dan reageert het met een 404-fout in plaats van een HTML-pagina. Maar als het een geschikte servlet "zit" op dat adres, dan kijkt het naar het verzoektype (GET, POST of iets anders) en vraagt ​​het de servlet of het een methode heeft die dit type vraag aankan. Als de servlet zegt dat hij niet weet hoe hij met dit type moet omgaan, danTomcat retourneert een 405-code. En dit is precies wat er gebeurde in ons project. Maar als er een geschikte servlet wordt gevonden en deze een geschikte methode heeft, dan maakt Tomcat een servletobject en start het op een nieuwe thread(waardoor het zelfstandig kan werken), en Tomcat gaat door met zijn eigen werk, het accepteren en verzenden van verzoeken. Bovendien maakt Tomcat nog twee objecten: een HttpServletRequest (die ik kortweg de "request" zal noemen) en een HttpServletResponse (die ik de "response" zal noemen). Het plaatst alle gegevens die zijn ontvangen van het verzoek van de klant in het eerste object, zodat al die gegevens eruit kunnen worden gehaald. En na dit alles geeft het deze twee objecten door aan de juiste methode van de servlet die op een aparte thread is gestart. Zodra de servlet klaar is met zijn werk en een antwoord klaar heeft om naar de client te worden gestuurd, zwaait het met een vlag naar Tomcat en zegt: "Ik ben klaar. Alles is klaar". Tomcat ontvangt het antwoord en stuurt het naar de klant. Hierdoor kan Tomcat verzoeken ontvangen en antwoorden verzenden, zonder afgeleid te raken, en al het werk wordt gedaan door servlets die op afzonderlijke threads draaien. Dat betekent dat wanneer we de servletcode schrijven, we bepalen welk werk er zal worden uitgevoerd. En je kunt de methode main() beschouwen als gelokaliseerd in Tomcat zelf (ja, het is geschreven in Java), en wanneer we Tomcat "starten", wordt de methode main() gestart. Een eenvoudige webapplicatie maken met behulp van servlets en JSP's (deel 1) - 2

Gebruik servlets om GET-methoden te vangen en supereenvoudige antwoorden te verzenden

Op dit moment hebben onze servlets geen geschikte methoden (GET), dus Tomcat retourneert een 405-fout. Laten we ze maken! De klasse HttpServlet, die wij onze servlets erven, declareert verschillende methoden. Om specifieke code aan de methoden toe te wijzen, overschrijven we ze gewoon. In dit geval moeten we de doGet()methode in beide servlets overschrijven.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
Zoals u kunt zien, heeft deze methode twee argumenten nodig: req (verzoek) en resp (antwoord). Dit zijn precies de objecten die Tomcat voor ons maakt en vult wanneer het de juiste methode in de servlet aanroept. Om te beginnen maken we de eenvoudigste reacties. Om dit te doen, nemen we het resp-object en halen er een PrintWriter-object uit. Dit type object wordt gebruikt om een ​​antwoord op te stellen. We zullen het gebruiken om een ​​eenvoudige string uit te voeren.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("GET method from AddServlet");
}
We zullen iets soortgelijks doen in de ListServlet, en dan zullen we onze server herstarten. Zoals je kunt zien, werkt alles! Als je op de knoppen klikt, krijg je pagina's met de tekst die we "schreven" met de PrintWriter. Maar de JSP-bestanden die we hebben voorbereid om pagina's met antwoorden te genereren, worden niet gebruikt. Dat komt simpelweg omdat ze nooit worden uitgevoerd. Onze servlet maakt het antwoord zelf en voltooit het uitvoeren, waarbij Tomcat wordt gesignaleerd dat het klaar is om op de client te reageren. Tomcat neemt gewoon het antwoord en stuurt het terug naar de klant. Laten we de controle overdragen van de servlets naar de JSP-bestanden. We zullen de code van onze methoden als volgt wijzigen:
  • we verkrijgen een verzoekverzenderobject van het verzoekobject en geven het het adres door van de JSP-pagina waarnaar we de controle willen overdragen;
  • we gebruiken dit object om de controle over te dragen aan de opgegeven JSP-pagina, en niet te vergeten om de verzoek- en antwoordobjecten door te geven die we van Tomcat hebben ontvangen.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
In de body-tag van de JSP-pagina's kun je iets toevoegen, zodat we duidelijk kunnen zien welke pagina wordt weergegeven. Zodra je dat hebt gedaan, start je de server opnieuw op en controleer je. We klikken op de knoppen op de hoofdpagina en de pagina's openen, wat betekent dat de verzoeken naar de servlets worden gestuurd. Vervolgens wordt de besturing doorgegeven aan de JSP-pagina's, die nu worden weergegeven. Dat is het voor nu. In het volgende deel van dit artikel werken we aan de functionaliteit van onze applicatie.
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION