Her er Danmarks fem bedste CIO’er lige nu:Se de fem nominerede til prisen som Årets CIO 2024

I gang med servlets

Servlets er Java-applikationer til webservere. De udgør rygmarven i Javas web-teknologier, og ligger bag JSP (Java Server Pages). I denne artikel introducerer vi servlets, som slet ikke er så svære at have med at gøre. Det er en god idé at benytte et program til at udvikle med, og her kigger vi på Suns gratis Forte for Java CE.

Hvorfor Java

En servlet er et lille Java-program, som kører under en webserver. Sun beskriver det pædagogisk som en applet uden ansigt. En servlet er i og for sig ikke anderledes en andre typer af det, man i gamle dage kaldte for CGI-programmering - altså programmering til en webserver-grænseflade, hvor webserveren klarer det hårde arbejde med at tage imod forespørgsler og allokere løbende ressourcer.

Det miljø, som en servlet lever i, kaldes en servlet-container, og det kan være en webserver som Tomcat, eller store dyre forkromede J2EE-maskiner fra for eksempel Sun, IBM, BEA eller Oracle.

Servlets ligger bag JSP, Java Server Pages, som vi kigger på i en kommende artikel. JSP minder lidt om andre webscripting-teknologier som PHP og ASP.NET, og hemmeligheden bag JSP-filer er, at de bliver kompileret til servlets automatisk.

Man kunne godt tro, at JSP var alt, hvad der er at sige om Java og webprogrammering, men servlets spiller stadig en rolle. Det gælder i den såkaldte Model 2-arkitektur, som er et bud på, hvorledes brugerflade og logik separeres. Det ser vi på i en tredje artikel.

Hvorfor Java til web
Men hvorfor overhovedet benytte Java og ikke nogle af de andre teknologier, kan man spørge. Svaret afhænger af, hvem man er, og hvad man pønser på. Hvis man i forvejen benytter Java, så er det jo oplagt at benytte miljøet. Java byder på et stort antal robuste klassebiblioteker i sit afviklingsmiljø, så man har de samme muligheder, som man har med andre typer af Java-baserede applikationer.

Som tidligere nævnt indgår servlets også i J2EE-arkitekturen, så hvis man beskæftiger sig med Java-baserede applikationsservere, er servlets vejen frem. Her skal det lige nævnes, at man altså ikke behøver at være J2EE- eller EJB-haj for at gakke til servlets. Hvis man kender lidt til webscripting i forvejen, er servlets nemme at gå til.

Udover J2EE som platform findes der servlet-containere til alle de kendte webservere på markedet.

Deployeringen, at lægge filerne op på webserveren og få det hele til at spille, er dog ikke nogen simpel proces - slet ikke i forhold til PHP, Perl og ASP, hvor man blot kan smække sin script-fil et sted i webserverens mappe-hierarki, hvorefter scriptet er køreklart.

Sådan er det ikke med servlet-containere, så i udviklingsfasen er man bedst tjent med et udviklingsprogram (IDE), som kan klare ærterne. Sådan en sag kan man heldigvis downloade gratis.

Skeletter

Hej verden
Servlets bygger på klassebibliotekerne javax.servlet og javax.servlet.http, som er dokumenteret på Suns hjemmeside. Suns egen introduktion i form af de såkaldte "trails" kan også findes online.

Hvis man kender lidt til webscripting, så finder man de sædvanlige emner her. Hvis man tidligere har programmeret gammeldags CGI-scripts i et sprog som Perl, så ser en servlet egentlig ikke så mystisk ud. Den grundlæggende funktionsmåde består i at udskrive HTML-koden, linje for linje.

Som sagt er det nemmest at udvikle servlets i et udviklingsmiljø. Her kigger vi på Suns Forte For Java CE, der netop har skiftet navn til Sun ONE Studio 4. Den er gratis, og kan downloades fra Sun hjemmeside.

I Forte skal man først oprette et såkaldt Web-modul, før man kan teste sine servlets på den indbyggede version af Tomcat, som følger med Forte.

I Forte 4.0 gøres det ved at vælge fanebladet Filesystems i Explorer-vinduet (til venstre). Højreklik på ikonet Filesystems, og i popup-menuen vælges Mount > Local Directory. Naviger frem til en arbejdsmappe. Vi valgte D:\Tania\Servlet. Herefter dukker et drev-ikon op i fanebladet Filesystems med sti-navnet ved siden af.

Nu højreklikkes på drev-ikonet, og i den fremkomne popup-menu vælges New > JSP & Servlet > Web Module. Her skal der navigeres frem til den mappe, hvor modulet ønskes oprettet. Her kan man vælge samme mappe som før. En dialog spørger, om man ønsker at konvertere filsystemet til et J2EE-module, og hertil svares OK.

Nu kan vi oprette skelettet til vores HejVerden-servlet.

Først skal man klikke på fanebladet Project (efterfulgt af projektnavnet) i Explorer-vinduet, og udfolde web-modulet, så ikonet Classes er synligt.

Højreklik på dette ikon, og i popup-menuen vælges New > JSP & Servlet > Servlet.

En New Wizard-dialog fremkommer, og her navngives servletten, for eksempel til HejVerden. Klik nu på knappen Finish.

De fleste andre IDE'er har deres egne servlet-wizards, og det er en god ide at kigge grundigt i manualer og dokumentation først.

Nu kan man passende lige tage et blik på det skelet, som programmet har skabt for os.

Fødsel og død

Skelettet består af en klasse (HejVerden), som er nedarvet fra HttpServlet, som er er servletternes moderklasse.

Herefter er en række af metoderne fra HttpServlet implementeret. De vigtigste, og let forståelige, er de tre metoder doGet(), doPost() og processRequest(), som henholdsvist håndterer GET-forespørgsler og POST-forespørgsler. Man behøver ikke at implementere begge metoder, man kan eksempelvis godt nøjes med at implementere doGet() og ikke doPost(). Det betyder blot, at serveren returnerer en fejlmeddelelse til klienten, hvis der afsendes en POST-forespørgsel. Metoden processRequest() udføres ved begge typer af forespørgsler, og den bruger vi her.

Lad os nu kreere det kendte Hej Verden-program i en servlet-version. Forte har allerede skrevet det meste af koden for os.

protected void processRequest(HttpServletRequest request, 
HttpServletResponse response)
throws ServletException, java.io.IOException {
response.setContentType("text/html");
java.io.PrintWriter out = response.getWriter();
/* output your page here
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet</title>");
out.println("</head>");

out.println("<body>");

out.println("</body>");
out.println("</html>");
*/
out.close();
}


Vi fjerner kommentar-symbolerne i midten, og linien

out.println("<body>");

ændrer vi til
out.println("<body><h1>Hej Verden</h1>");

Så højreklikkes på HejVerden-ikonet i Explorer-vinduet, og fra popup-menuen vælges Execute. Hvis alt går vel, skulle maskinens browser nu starte op med beskeden Hej Verden.

Som det ses af eksemplet udskrives HTML-koden til klienten ved at benytte HttpServletResponse-objektets getWriter()-metode, som returnerer et PrintWriter-objekt, som hedder out i eksemplet, og det er den som uddata skal skrives til.

Fødsel og død
En anden metode, som kan være nyttig at implemetere, er init() som udføres, når servletten startes. En servlet har en livscyklus, som består i at servletten initieres og håndterer forespørgsler, hvis der er nogen. Hvis der går lang tid uden forespørgsler, kan servlet-containeren vælge at fjerne servletten, så der frigøres ressourcer til andre opgaver. Servletten kan altså dø og genopstå gentagne gange. Når servlet-containeren fjerner servletten, kaldes servlettens destroy()-metode, som man kan implementere, hvis man har noget, der skal udføres før at servletten bliver fjernet af servlet-containeren.

Parametre

Parametre
Når man programmerer op imod en webserver, er der to ting, man skal have styr på for at kunne gøre noget som helst. Det ene er at kunne tilgå de parametre, som overføres fra forespørgslen, det andet er at kunne binde data til en bestemt klient med session-variabler og cookies.

Parametre kommer ind i billedet, enten som en querystring i en GET-forespørgsel (hvilket er det, der står efter spørgsmålstegnet i en webadresse som for eksempel http://www.pcworld.dk/default.asp?Mode=2&ArticleID=3509), eller som en POST-forespørgsel, hvor større mængder data kan sendes fra klienten til serveren.

Parametrene og deres værdier kommer fra objektet HttpServletRequest, som leveres som argument til doGet()- og doPost()-metoderne.

Vi kan for eksempel tilføje følgende linier til processRequest()-metoden i vores HejVerden-servlet:

String hejHvem = request.getParameter("hvem");
out.println("<body><h1>Hej "+hejHvem+"</h1>");

Og kalde servletten med querystringen ?hvem=Tania:

http://localhost:8081/servlet/test8?hvem=Tania

Metoden getParameter() fra HttpServletRequest returnerer altså en streng for et parameternavn. Hvis en parameter har mere end én værdi, kan man benytte metoden getParameterValues(), som returnerer et array, og slutteligt giver getParameterNames() et array bestående af alle parametrenes navne.

Man kan også vælge at parse data selv, ved hjælp af metoderne getQueryString() ved GET-forespørgsler, og getReader() samt getInputStream() ved POST-forespørgsler, men man kan ikke bruge dem samtidig med getParameter()-metoderne, så man må altså vælge.

Yderligere er der ikke nogle utility-funktioner til at håndtere for eksempel fil-uploading (som mere formelt hedder POST-forespørgsler med mime-typen multipart/mixed). Heldigvis er der flere biblioteker til rådighed, som kan klare sagen, for eksempel com.oreilly.servlet, som kan benyttes frit, også til kommercielle anvendelser, på betingelse af at man køber forfatterens Java-bog.

Sessioner og cookies

Tilstande
En anden vigtig ting er håndtering af sessioner, hvor data tilknyttes en bestemt klient, så flere servletter kan tilgå fælles data knyttet til en enkelt bruger, og cookies, som jo gør det muligt at gemme en lille smule data hos brugerne imellem sessionerne.

Sessioner håndteres af objektet HttpSession, og man initierer en session (hvis den ikke allerede er initieret) med metoden getSession(true) fra HttpServletRequest-objektet. Et eksempel fra Suns Servlet-tutorial viser anvendelsen:

public class CatalogServlet extends HttpServlet {

public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Get the user's session and shopping cart
HttpSession session = request.getSession(true);
ShoppingCart cart =
(ShoppingCart)session.getAttribute("examples.bookstore.cart");

// If the user has no cart, create a new one
if (cart == null) {
cart = new ShoppingCart();
session.putAttribute("examples.bookstore.cart", cart);
}
...
}
}


Objekter gemt i en instans af HttpSession-objektet kaldes attributter i servlet-sprogbrugen, og i linien

session.putAttribute("examples.bookstore.cart", cart);

gemmes cart-objektet med attribut-navnet "examples.bookstore.cart". Det tilrådes i øvrigt at benytte en eller anden type navnerum ved navngivning af session-værdier og cookies for at undgå kollisioner. Man kan for eksempel benytte det sædvanlige Java-navnerum med omvendt url, i stil med com.mitFirmaNavn.minServletsNavn.minTilstandsNavn.

Når cart-objektet skal bruges igen, sker det som i linien

ShoppingCart cart =  
(ShoppingCart) session.getAttribute("examples.bookstore.cart");

Det er jo lige ud af landevejen - objektet hentes ved sit navn, og castes så tilbage til sin oprindelige type.

Cookies
Cookies sættes ved hjælp af javax.servlet.http.Cookie-objektet, og derefter tilføjes det oprettde cookie-objekt til HttpServletResponse-objektet med dennes addCookie()-metode, som i eksemplet her:

Cookie getBook = new Cookie("Buy", bookId);
getBook.setComment("User has indicated a desire " +
"to buy this book from the bookstore.");
response.addCookie(getBook);

Ligesom i så mange andre webprogrammeringsmiljøer skal addCookie()-metoden benyttes, før man begynder at skrive data til kroppen i svaret, hvilket i servlet-verdenen er før man kalder getWriter()-metoden i HttpServletResponse.

Når cookies skal hentes fra forespørgslen, gøres det ved at kalde HttpServletResponse-objektets getCookies(), som returnerer et array af Cookies:

Cookie[] cookies = request.getCookies();

Man må så manipulere de enkelte cookies ved at gennemløbe arrayet og benytte Cookie-objektets getName()- og getValue()-metoder til at identificere den cookie, som man vil kigge nærmere på .

JSP og Model 2
Som det burde fremgå for den, der har erfaringer inden for andre typer af webprogrammering, så ligner Servlet-teknologien til forveksling "gammeldags" CGI-programmering, og den lider også af samme problem: Nemlig at præsentationen (HTML-koden) og logikken blandes sammen.

Derfor opfandt Sun for et par år tilbage Java Server Pages, som benytter XML-agtige tags til at indlejre logik, lidt i stil med eksempelvis PHP og ASP.

Ved hjælp af ren magi bliver JSP-sider faktisk omskabt til servlets. JSP-sider er på den måde i virkeligheden blot en slags skabelon for servlets, men det behøver JSP-udvikleren ikke bekymre sig om. I den næste om artikel om Java til webbrug gennemgår vi JSP og deployering med Web Archives, WAR-filer.

Selvom JSP løser en del af problemet med præsentation og logik, så lider teknologien af de samme unoder som ASP og PHP. Disse problem har en gradvis løsning med den såkaldte Model 2-arkitektur, som benytter servlets i den gammeldags udformning, og det ser vi på i en tredje artikel.




Brancheguiden
Brancheguide logo
Opdateres dagligt:
Den største og
mest komplette
oversigt
over danske
it-virksomheder
Hvad kan de? Hvor store er de? Hvor bor de?
Advania Danmark A/S
Hardware, licenser, konsulentydelser

Nøgletal og mere info om virksomheden
Skal din virksomhed med i Guiden? Klik her

Kommende events
OT og IT: Modernisér produktionen og byg sikker bro efter et årelangt teknologisk efterslæb

Moderne produkter skal have mere end strøm for at fungere – og deres navlestreng skal ikke klippes når de forlader fabrikshallen. På denne konference kan du derfor lære mere om hvordan du får etableret det sikre setup når der går IT i OT.

30. april 2024 | Læs mere


Roundtable for sikkerhedsansvarlige: Hvordan opnår man en robust sikkerhedsposition?

For mange virksomheder har Zero Trust og dets principper transformeret traditionelle tilgange til netværkssikkerhed, hvilket har gjort det muligt for organisationer at opnå hidtil usete niveauer af detaljeret kontrol over deres brugere, enheder og netværk - men hvordan implementerer man bedst Zero Trust-arkitekturer i et enterprise set up? Og hvordan muliggør Zero Trust-arkitekturen, at organisationer opnår produktivitetsfordele med AI-værktøjer samtidig med, at de forbliver sikre i lyset af fremvoksende trusler?

01. maj 2024 | Læs mere


ERP-trends 2024

Bliv derfor inspireret til, hvordan du kan optimere dine systemer og processer når af nogle af de fremmeste eksperter på ERP-markedet dele deres iagttagelser af det aktuelle marked og vurderinger af, hvad vi har i vente de kommende 3-5 år. Vi sætter også fokus på, hvordan udviklingen kommer til at påvirke din organisation, hvordan du bedst forbereder og planlægger ERP-indsatsen og om, hvilke faldgruber du skal være opmærksom på.

02. maj 2024 | Læs mere