
Hvad er en servlet?
Lad os først finde ud af, hvad servlets er, og hvorfor du hører om dem så ofte. Java Servlet API er en standardiseret API beregnet til at blive implementeret på serveren. Det interagerer med kunder i henhold til en anmodning-svar-ordning. En servlet er en klasse, der kan modtage anmodninger fra en klient og returnere svar til klienten. Faktisk er servlets præcis de byggeklodser, vi bruger til at skabe en klient-server-arkitektur i Java. Du husker måske, at vi allerede talte om den arkitektur i en anden af artiklerne i serien. Vi kommer ikke til at slå om busken: lad os skrive noget kode med det samme.Hvad du skal bruge for at oprette en webapplikation
For den største bekvemmelighed, når du arbejder med Java-servlets, har du brug for IntelliJ IDEA Ultimate Edition. Det er et betalt produkt, men du kan aktivere en 30-dages prøveversion eller bruge versionen med tidlig adgang, som altid er gratis. Installer også Apache Tomcat - vores applikations server. Tomcat er en servlet-beholder: den behandler indgående anmodninger og sender dem til vores applikation. Download Tomcat her .Lad os oprette vores første webapplikation
Hvis alt er klar, skal du oprette et Maven-projekt. Hvis du ikke er bekendt med Maven, så tag et kig på den forrige artikel . Lad os begynde!-
Tilføj en javax.servlet-api-afhængighed i pom.xml og angiv WAR-pakning:
<?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>org.example</groupId> <artifactId>servlets</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> </dependencies> </project>
Simpel servlet klasse:
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/hello") public class MainServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); PrintWriter printWriter = resp.getWriter(); printWriter.write("Hello!"); printWriter.close(); } }
-
For at køre programmet skal du oprette en Tomcat-konfiguration:
-
Dernæst angiver vi, hvilken version af Tomcat vi vil bruge, og URL'en og porten til at kommunikere med serveren. Du burde have sådan noget:
-
Nu mangler vi bare at specificere artefaktet (det samlede projekt i et JAR-arkiv), der vil blive implementeret i containeren. Du kan klikke på Fix- knappen og vælge war exploded : dette betyder, at efter projektet er genopbygget, vil artefakten automatisk blive placeret i servlet-beholderen.
-
Standardværdien for applikationskontekst er servlets_war_exploded . Det betyder, at vi får adgang til applikationen på: http://localhost:8080/servlets_war_exploded .
Hvorfor vil vi have ekstra tekst? Lad os slette det, der er unødvendigt. Nu er vores webapplikations adresse: http://localhost:8080 .
-
Klik på OK. Vi ser, at vi nu kan starte applikationen:
Når du nu åbner programmet i din browser, skulle du få en 404-fejl. Dette er fornuftigt, fordi adressen http://localhost:8080/ har brug for en servlet, der mapper til "/", men vores eneste servlet maps til "/hello" .
-
Vi kan få adgang til det på http://localhost:8080/hello . Når vi gør det, får vi det forventede svar - strengen "Hej"!
@WebServlet()
. Det er her, vi binder (eller kortlægger) servlet'en til en bestemt sti ("/hello"). Denne annotation dukkede kun op i Java Servlet API 3.0, så internettet har en masse eksempler, hvor servlet-mapping sker gennem en XML-fil. Dette er ikke længere nødvendigt. For at håndtere GET-anmodninger tilsidesætter vi doGet()
metoden. Vær opmærksom på metodens parametre: HttpServletRequest
og HttpServletResponse
. Objektet HttpServletRequest
giver os alle de nødvendige oplysninger om anmodningen. I HttpServletResponse
, skriver vi vores svar og sætter de nødvendige overskrifter.
Arbejde med parametre og en session
Lad os forbedre vores servlet, så den kan behandle anmodningsparametre og arbejde med en session:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/hello")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
Integer visitCounter = (Integer) session.getAttribute("visitCounter");
if (visitCounter == null) {
visitCounter = 1;
} else {
visitCounter++;
}
session.setAttribute("visitCounter", visitCounter);
String username = req.getParameter("username");
resp.setContentType("text/html");
PrintWriter printWriter = resp.getWriter();
if (username == null) {
printWriter.write("Hello, Anonymous" + "<br>");
} else {
printWriter.write("Hello, " + username + "<br>");
}
printWriter.write("Page was visited " + visitCounter + " times.");
printWriter.close();
}
}
Nu arbejder servletten med en session, hvilket øger værdien af visitCounter
hver gang siden besøges. Hvis visitCounter
attributten endnu ikke er oprettet (ved det første besøg på siden), getAttribute()
returnerer metoden null, så vi skal tjekke for null. Det samme gælder for anmodningsparametre. Hvis brugeren ikke videregiver brugernavnsparameteren, vil dens værdi være null. I dette tilfælde hilser vi brugeren som en anonym besøgende. For at sende en parameter i en GET-anmodning bruges en forespørgselsstreng. For eksempel kunne vi bruge følgende URL: http:// localhost:8080/hello? Brugernavn=Paul. Du kan læse mere om HTTP-anmodninger i den forrige artikeli serien. Vores applikation har i øjeblikket ikke meget logik, men det er lidt irriterende, at vi får en 404-fejl ved rodstien. For at rette op på dette, opretter vi en anden servlet og knytter den til startsiden: @WebServlet("/")
. Formålet med denne servlet er at omdirigere anmodninger til "/hello"-stien. Der er to måder at gøre dette på: ved at bruge "forward" eller "redirect". Måske er det umagen værd at forstå forskellen mellem dem. En videresender delegerer behandlingen af anmodningen til en anden servlet på serveren. Klienten er ikke involveret. For at gøre dette skal du tilføje følgende kode til den nye servlets doGet()-metode:
getServletContext().getRequestDispatcher("/hello").forward(req, resp);
I denne kode får vi adgang til servlet-konteksten, henter anmodningsdispatcheren for den relevante servlet og beder den behandle en specifik anmodning med de angivne argumenter (req, hhv.). En omdirigering returnerer til klienten den adresse, som klienten skal bruge til at behandle sin anmodning. De fleste browsere navigerer automatisk til den returnerede URL. For at implementere en omdirigering skal du tilføje denne kode:
resp.sendRedirect(req.getContextPath() + "/hello");
Vi kalder redirect()
metoden på HttpServletResponse
parameteren og giver den den adresse, som klienten skal bruge. Her er en vigtig detalje: HTTP-parametre skal også tilføjes i slutningen af den fulde omdirigeringssti, hvilket ikke er særlig praktisk. I vores situation er det at foretrække at bruge forward
, men nogle gange redirect
er det bedre at bruge. Hvis du forstår forskellen på, hvordan de fungerer, vil du ikke træffe det forkerte valg. Koden til den nye servlet ser sådan ud:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// getServletContext().getRequestDispatcher("/hello").forward(req, resp);
resp.sendRedirect(req.getContextPath() + "/hello");
}
}
GO TO FULL VERSION