Java Server-pagina. Invoering

Zoals we in het vorige artikel hebben gezien, stellen servlets ons in staat verzoeken van een klant te ontvangen, wat werk te doen en de resultaten op het scherm weer te geven. Tot het moment dat het nodig is om output op het scherm weer te geven, werkt de servlet prima. Je kunt er behoorlijk complexe logica in invoegen, de database aanroepen en nog veel meer dat nodig is voor de applicatie. Maar uitvoer naar het scherm in de servlet zelf is erg lastig. In ons voorbeeld hebben we ons beperkt tot extreem eenvoudige oplossing. Wat moet u doen als u met complexe ontwerpideeën komt? Het is onwaarschijnlijk dat een webontwerper kan begrijpen hoe de uitvoer binnen onze servlet moet worden weergegeven. En wanneer hij zijn ontwerpideeën wil implementeren, zal hij naar de programmeur moeten komen en hem moeten vragen de servletcode te wijzigen om het ontwerp te veranderen. Dit zal opnieuw moeten worden samengesteld, het zal moeten worden uitgevonden slimme algoritmen om niet alleen afbeeldingen, maar ook JavaScript weer te geven. Gewoon een nachtmerrie.
Het is voor iedere weldenkende ontwikkelaar duidelijk dat er een andere oplossing gebruikt moet worden. Het meest voor de hand liggende is om een ​​mechanisme te bedenken dat de taak in twee componenten verdeelt: het ene deel verwerkt het verzoek, wijzigt de gegevens, verzamelt de gegevens, stopt het in een bepaald pakket en draagt ​​het over naar het tweede deel, dat dat wel doet. slechts één ding: geeft deze gegevens weer.
Dit is hoe we bij het patroon komen dat we al kennen: Model-View-Controller (MVC). In het geval van webapplicaties wordt de controller een servlet, het datapakket dat we hebben gegenereerd wordt een model. Maar JSP – Java Server Pages – is perfect voor de rol van presentatie (View).
In dit artikel zullen we dat doen algemeen overzicht deze technologie. En in het volgende artikel gaan we verder met 'Human Resources Department', waar we meteen bekende technologieën kunnen gebruiken: servlets en JSP.
Het hoofdidee van JSP is heel eenvoudig: de pagina zelf is een sjabloon met reeds voorbereide HTML-tags, waartussen u de nodige gegevens moet invoegen. Zoiets (dit is maar een diagram)

Hallo wereldvoorbeeld <TITLE> </HEAD> <BODY> <H1>[En hier zijn enkele gegevens]</H1> </BODY> </HTML></p> <p>Om te voorkomen dat je je gaat vervelen en voor de duidelijkheid, gaan we onze allereerste HelloWorldServlet-servlet uit het vorige artikel wijzigen. We zullen de mogelijkheid toevoegen om te werken met een parameter waar we vanaf zullen gaan <a href="https://leally.ru/nl/payment-system/kak-sdelat-stranicu-s-redirektom-redirekt-url-adresov-s-pomoshchyu-javascript/">met behulp van URL</a>. We zien hem wat later. Laten we voorlopig eens kijken naar een licht gewijzigde HelloWorldServlet. Zijn taak is nu heel eenvoudig: de begroeting weergeven "Hallo wereld!" als de naamparameter niet wordt doorgegeven. Als deze wordt verzonden, verandert de begroeting enigszins. Als u bijvoorbeeld de parameternaam=Anton doorgeeft, moet de servlet de tekst 'Hallo wereld.' weergeven. Ik ben Anton." <br>Er is niets ingewikkelds aan het probleem en het kan worden opgelost zonder JSP, maar het is geschikt voor demonstraties.</p> <p>pakket studenten.web; java.io.IOException importeren; javax.servlet.ServletException importeren; javax.servlet.http.HttpServlet importeren; javax.servlet.http.HttpServletRequest importeren; javax.servlet.http.HttpServletResponse importeren; public class HelloWorldServlet breidt HttpServlet uit ( public void doGet(HttpServletRequest req, HttpServletResponse resp) gooit ServletException, IOException ( getServletContext().getRequestDispatcher("/hello.jsp").forward(req, resp); ) )</p> <table class="crayon-table"><tr class="crayon-row"><td class="crayon-nums " data-settings="show"> </td> <td class="crayon-code"><p>pakket studenten. web;</p><p>Javax importeren. servet. ServletException;</p><p>Javax importeren. servet. http. HttpServlet;</p><p>Javax importeren. servet. http. HttpServletRequest;</p><p>Javax importeren. servet. http. HttpServletResponse;</p><p>openbare klasse HelloWorldServlet breidt HttpServlet uit (</p><p>public void doGet(HttpServletRequest req, HttpServletResponse resp) genereert ServletException, IOException(</p><p>getServletContext(). getRequestDispatcher("/hello.jsp"). vooruit(req, resp);</p> </td> </tr></table><p>De meest interessante regel (het is ook de enige tot nu toe) stelt ons in staat een bron te verkrijgen (in ons geval is dit hello.jsp) en onze gegevens aan deze bron door te geven. IN <a href="https://leally.ru/nl/internet/chem-otlichaetsya-apple-id-ot-icloud-raznica-mezhdu-rezervnymi-kopiyami-icloud-i/">in dit geval</a> wij hebben niets veranderd of toegevoegd. Laten we nu eens kijken naar het bestand hello.jsp, dat een pagina aan de gebruiker zou moeten presenteren. In dit geval is het niet erg ingewikkeld, maar toch zullen we er dieper op ingaan.</p> <p><html> <head> <title>Hallo wereldvoorbeeld

<% String name = request.getParameter("name"); if (name == null || name.length() == 0) { %>Hallo wereld!<% } else { %>Hallo wereld! Ik ben<%= name%> <% } %>



< html >

< head >

< title >

Hallo wereldmonster

< / title >

< / head >

< body >

< h1 >

Tekenreeksnaam = verzoek . getParameter("naam");

if (naam == null || naam . lengte () == 0 ) (

Hallo wereld!

<% } else {

Hallo wereld! Ik ben<%= name %>

< / h1 >

< / body >

< / html >

Zoals u kunt zien, is ons HTML-bestand een combinatie van HTML-tags en Java-code. In wezen wordt JSP bij de eerste toegang omgezet in een servlet en werkt het als een servlet. Dit is erg belangrijk om te begrijpen. JSP IS GEEN pagina zoals een HTML-pagina - het is belangrijk dat een nieuwe programmeur duidelijk begrijpt dat het gewoon een andere servlet is - je hoeft alleen de uitvoer ervan niet te programmeren.<%» и здесь вам можно написать любой код, который будет нужен.
Je kunt het eenvoudig tekenen. En plaats de gegevens op de juiste plaatsen. Maar omdat Als een JSP-pagina op de een of andere manier op HTML lijkt, zal het voor de ontwerper uiteraard gemakkelijker zijn. En ik zeg nogmaals STERK tegen beginners: JSP is een SERVLET. De voorbereiding ervan met alle gegevens vindt plaats op de server. Hier worden alle gegevens ingevoegd. En de gebruiker krijgt een kant-en-klare HTML-pagina in de browser, die geen tekenen van JAVA vertoont. Misschien een soort applet, maar dit is een heel andere technologie. Het is gewoon handig om JSP te gebruiken: je doet de logica voor het ontvangen van gegevens in één servlet (die er niet uitziet als JSP) en geeft de gegevens vervolgens door aan een andere servlet (dit keer in de vorm van JSP), wiens taak het is om een HTML-pagina die deze gegevens gebruikt. Je hoeft alleen niet zo veel te tekenen. Bovendien hoeft u de JSP-klassen niet opnieuw te compileren. U kunt de JSP eenvoudig vervangen door een moderner exemplaar en deze wordt automatisch opnieuw gecompileerd. Dat is over het algemeen best handig: u hebt zojuist de vereiste pagina gekopieerd in plaats van de oude. Zoals u kunt zien, staat de Java-code tussen punthaken en een procentteken "
Zoals u kunt zien, controleert onze code op de aanwezigheid van de naamparameter in het verzoek (request.getParameter("name")) en, als deze bestaat, wordt er één bericht weergegeven. Anders zullen we een "verkorte" versie van de inscriptie zien.

Iets meer informatie - JSP heeft verschillende vooraf gedefinieerde objecten. Die. ze moeten worden gezien als kant-en-klare objecten die kunnen worden gebruikt. Dit zijn request, response, out, session, application, config, pageContext en page. Ik zal er een korte samenvatting van geven; het is mogelijk dat het voorlopig niet erg interessant zal zijn, en het is niet duidelijk. Maar voor het geval dat.
Dit is het HttpServletRequest-object dat aan het verzoek is gekoppeld en waarmee u toegang krijgt tot de verzoekparameters (via de getParameter-methode), het verzoektype (GET, POST, HEAD, enz.) en de inkomende HTTP-headers (cookies, Referer, enz.). ). D..). Om preciezer te zijn: request is een subklasse van ServletRequest en kan verschillen van HttpServletRequest als een ander protocol dan HTTP wordt gebruikt, wat in de praktijk vrijwel nooit het geval is. Daarom kun je het zien als een HttpServletRequest.

antwoord
Dit is een HttpServletResponse-object dat is gekoppeld aan een antwoord op een clientverzoek. Houd er rekening mee dat omdat de uitvoerstroom (zie hieronder) wordt gebufferd, het mogelijk is om HTTP-statuscodes en antwoordheaders te wijzigen, ook al zou dit niet zijn toegestaan ​​in een normale servlet, zolang bepaalde uitvoergegevens al naar de client zijn verzonden .

uit
Dit is een PrintWriter-object dat wordt gebruikt om uitvoer naar de client te verzenden. Om het responsobject (zie vorige sectie) echter nuttig te maken, moet u een gebufferde variant van PrintWriter gebruiken, JspWriter. Onthoud dat u de buffergrootte kunt wijzigen en zelfs bufferen kunt uitschakelen door de waarde van het bufferattribuut van de pagina-instructie te wijzigen. Houd er ook rekening mee dat out vrijwel uitsluitend door scriptlets wordt gebruikt, omdat JSP-expressies automatisch in de uitvoerstroom worden geplaatst, waardoor de noodzaak om expliciet aan te roepen wordt geëlimineerd.

sessie
Dit is een HttpSession-object dat aan het verzoek is gekoppeld. Sessies worden automatisch aangemaakt en deze variabele bestaat zelfs als er geen verwijzingen naar inkomende sessies zijn. De enige uitzondering is wanneer u het gebruik van sessies uitschakelt met behulp van het sessiekenmerk van de pagina-instructie. In dit geval leiden verwijzingen naar de sessievariabele tot fouten bij het vertalen van de JSP-pagina naar de servlet.

sollicitatie
Dit is een object van het type ServletContext, verkregen door het gebruik van de methode getServletConfig().getContext().

configuratie
Dit is een ServletConfig-object voor de huidige pagina.

paginaContext
JSP introduceert een nieuwe PageContext-klasse voor sandbox-serverspecifieke functies, zoals efficiëntere JspWriters. Het idee is dat als u er via deze klasse toegang toe krijgt in plaats van rechtstreeks, uw code op "normale" servlet/JSP-engines kan worden uitgevoerd.

pagina
In wezen een synoniem hiervoor, en niet nodig bij het werken met Java. Deze variabele is gemaakt met het oog op de toekomst, wanneer mogelijk andere scripttalen dan Java beschikbaar komen.

Laten we onze creatie eens in actie bekijken. U kunt onze servlet compileren met het commando

javac –cp .;servlet-api.jar studenten\web\*.java

Laten we daarna onze HelloWorldServlet-klasse in de map plaatsen \webapps\studentenApp\WEB-INF\studenten\web\. En het hello.jsp-bestand in de hoofdmap van onze applicatie is \webapps\studentenApp.
Nu is onze directorystructuur wat eenvoudiger (we gebruiken sommige klassen niet)

WEB-INF klassen studenten web -HelloWorldServlet.class -web.xml -hello.jsp

< strong >WEB-INF

klassen

studenten

Hallo WereldServlet. klas

Web. xml

Hallo. jsp< / strong >

Het reeds bekende web.xml-bestand zal er precies hetzelfde uitzien als in het vorige deel

Hallo Hallo /Hallo

< ! DOCTYPE web - app PUBLIC "-//Sun Microsystems, Inc.//DTD

Webapplicatie 2.3//NL" "http://java.sun.com/dtd/web-app_2_3.dtd">

< web - app >

< servlet >

< servlet - name >Hallo< / servlet - name >

< servlet - class >studenten. web. Hallo WereldServlet< / servlet - class >

< / servlet >

< servlet - mapping >

< servlet - name >Hallo< / servlet - name >

< url - pattern >/Hallo< / url - pattern >

< / servlet - mapping >

< / web - app >

Start Tomcat en probeer vervolgens onze applicatie via URL aan te roepen
http://localhost:8080/studentsApp/hello

Als je mijn naam wilt zien, gebruik dan deze URL
http://localhost:8080/studentsApp/hello?name=Anton
Je kunt je naam later vervangen :)

Aangepaste tag

Nu kunnen we wat dieper in JSP duiken. Zoals je waarschijnlijk al hebt gemerkt, is JSP een combinatie van Java-code en HTML-tags. Naarmate de complexiteit van de presentatielogica toeneemt (en JSP precies als presentatie wordt gebruikt - maar zelfs de presentatie kan behoorlijk geavanceerde logica hebben - kleuren, lettertypen, enz.), verandert de pagina van min of meer begrijpelijke HTML in 'naval-style'. pasta". En de ontwerper zal niets meer kunnen begrijpen. Het is hoogstwaarschijnlijk onmogelijk om de logica in JSP volledig kwijt te raken, maar op de een of andere manier de code "op te schonen" en handiger tools te gebruiken - zo'n oplossing bestaat. En het heet CustomTags. In wezen is dit een vereenvoudiging van JSP-ontwerpen die ik wilde bereiken.

Laten we eens kijken naar een eenvoudig voorbeeld van hoe u uw eigen tag kunt schrijven en gebruiken. Om dit te doen hebben we drie stappen nodig:

  1. Schrijf een TLD-bestand (Tag Library Definition) – een tagbibliotheek-descriptorbestand.
  2. Schrijf een klasse om de tag zelf te implementeren
  3. Correct HTML-bestand

Dus. Het TLD-bestand heeft de extensie .tld en wordt doorgaans geïmplementeerd in de WEB-INF-map in uw toepassingsmap. Hoewel het in een ander kan worden geplaatst. Als u veel van dergelijke bestanden heeft, kunt u er een aparte map voor opgeven. Hier is onze versie van hello.tld.

1.0 1.2 Voorbeeldtagbibliotheek /SimpleTagLibrary Voorbeeld van tag voor HelloWorld Hallo studenten.web.tag.HelloTag leeg Hallo wereldtag voorbeeld naam vals WAAR

< taglib xmlns = "http://java.sun.com/xml/ns/j2ee"

xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"

xsi: schemaLocatie = "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"

versie = "2.0" >

< tlib - version > 1.0 < / tlib - version >

< jsp - version > 1.2 < / jsp - version >

< short - name >Voorbeeldtagbibliotheek< / short - name >

< uri >/SimpleTagLibrary< / uri >

< description >

Voorbeeld van tag voor HelloWorld

< / description >

< tag >

< name >Hallo< / name >

< tag - class >studenten. web. label. HalloTag< / tag - class >

< body - content >leeg< / body - content >

< description >

Hallo wereldtag voorbeeld

< / description >

< attribute >

< name >naam< / name >

< required >vals< / required >

< rtexprvalue >WAAR< / rtexprvalue >

< / attribute >

< / tag >

< / taglib >

Zoals je waarschijnlijk uit de beschrijving hebt opgemerkt, is een tag de HelloTag-klasse. Hij is degene die verantwoordelijk is voor het weergeven van informatie. Laten we het schrijven.

pakket studenten.web.tag; java.io.IOException importeren; javax.servlet.jsp.JspException importeren; javax.servlet.jsp.JspTagException importeren; javax.servlet.jsp.tagext.TagSupport importeren; public final class HelloTag breidt TagSupport uit ( private String naam = null; public int doStartTag() gooit JspException ( try ( if (naam == null) ( pageContext.getOut().write("Hallo, wereld!'); ) else ( pageContext.getOut().write("Hallo wereld! Ik"m " + naam); ) ) catch (IOException ioe) ( throw new JspTagException(ioe.getMessage()); ) return SKIP_BODY; ) public String getName() ( retournaam; ) public void setName(String name) ( this.name = naam; ) public void release() ( super.release(); name = null; ) )

pakket studenten. web. label;

java importeren. io. IOUitzondering;

Javax importeren. servet. jsp. JspException;

Javax importeren. servet. jsp. JspTagException ;

Javax importeren. servet. jsp. tagtekst. TagOndersteuning;

openbare eindklasse HelloTag breidt TagSupport uit (

privé Stringnaam = null;

public int doStartTag() gooit JspException(

poging (

if (naam == null ) (

paginaContext. getOut(). write("Hallo wereld!");

) anders (

paginaContext. getOut(). schrijf ("Hallo wereld! Ik ben " + naam );

) catch (IOException ioe) (

gooi nieuwe JspTagException(ioe. getMessage());

retour SKIP_BODY ;

openbare tekenreeks getName()(

retournaam;

public void setName(Stringnaam) (

dit. naam = naam;

openbare leegtevrijgave() (

super. uitgave();

naam= nul;

}

}

Om onze servlet en nieuwe tag samen te stellen, hebben we een complexere lijn nodig

javac –cp .;servlet-api.jar;jsp-api.jar studenten\web\*.java studenten\web\tag\*.java

De nieuwe jsp-api.jar-bibliotheek kan op dezelfde plaats worden gevonden als servlet_api.jar - in \algemeen\lib. Om onze tag aan de applicatie te koppelen, moeten we onze bibliotheek registreren in het web.xml-bestand

Welkom bij Studentenpersoneel Welkom bij Studentenpersoneel Hallo studenten.web.HelloWorldServlet Hallo /Hallo http://www.someurl.ru /WEB-INF/hallo.tld

xmlversie= "1.0" codering= "ISO-8859-1"?>

< web- app>

< weergave- naam> WelkomnaarStudentenpersoneel< / weergave- naam>

Met servlets kunt u verzoeken van een klant ontvangen, wat werk doen en de resultaten op het scherm weergeven. De servlet werkt prima tot het moment dat het gaat om het verwerken van informatie, d.w.z. voordat informatie op het scherm wordt weergegeven. U kunt vrij complexe logica in een servlet invoegen, de database aanroepen en nog veel meer dat nodig is voor de toepassing. Maar uitvoer naar het scherm in de servlet zelf is erg lastig. Maar hoe zit het met het ontwikkelen van complexe ontwerpideeën en het vervolgens aanbrengen van wijzigingen in de gebruikersinterface? Ontwerptechnologie Java-serverpagina's (JSP) is een van de J2EE-technologieën, een uitbreiding van de servlet-technologie om het werk met webinhoud te vereenvoudigen. JSP-pagina's maken het gemakkelijk om webinhoud in statische en dynamische delen te scheiden, waardoor eerder gedefinieerde componenten opnieuw kunnen worden gebruikt. Ontwikkelaars van Java Server Pages kunnen JavaBeans-componenten gebruiken en hun eigen aangepaste tagbibliotheken maken die complexe dynamische functionaliteit inkapselen. De Java Server Pages-specificatie (http://java.sun.com/products/jsp) neemt de Servlets-specificatie (http://java.sun.com/products/servlets) over en breidt deze uit. Net als servlets zijn JSP-componenten webcomponenten en bevinden ze zich in een webcontainer. JSP-pagina's zijn onafhankelijk van een specifieke webcontainerimplementatie, waardoor ze hergebruikt kunnen worden. Naast klassen en interfaces voor het programmeren van servlets (packages javax.servlet En javax.servlet/http ), in pakketten javax.servlet.jsp

En

javax.servlet.jsp.target
  1. bevat klassen en interfaces gerelateerd aan Java Server Pages-programmering. Een volledige beschrijving van de Java Server Pages-technologie kunt u vinden in de specificatie op (java.sun.com/products/jsp/download.htm) Java Server-pagina's Technologieoverzicht Java Server Pages-technologie bevat vier belangrijke componenten:
  2. Richtlijnen (richtlijn) zijn berichten voor de JSP-container, die het mogelijk maakt paginaparameters te definiëren, andere bronnen te verbinden en uw eigen niet-standaard tagbibliotheken te gebruiken.
  3. Acties (scriptjes) kunt u Java-code in JSP-pagina's invoegen die interactie heeft met pagina-objecten tijdens het verwerken van een verzoek.
  4. Tagbibliotheken (tagbibliotheek) zijn een integraal onderdeel van het tag-extensiemechanisme, waardoor u uw eigen tags kunt ontwikkelen en gebruiken.
De beschikbaarheid van gegevens met een onveranderlijke structuur bepaalt de keuze van de programmeur bij het beslissen welke technologie hij moet gebruiken: servlets of JSP-pagina's. Programmeurs geven er de voorkeur aan om JSP-pagina's te gebruiken wanneer de meeste inhoud die naar de client wordt verzonden onveranderlijke gegevens is en slechts een klein deel van de inhoud dynamisch wordt gegenereerd met behulp van Java-code. Servlets hebben de voorkeur als slechts een klein deel van de inhoud die naar de client wordt verzonden, gegevens met een onveranderlijke structuur zijn. In feite genereren individuele servlets mogelijk helemaal geen inhoud voor de klant, voeren ze een specifieke taak uit ten behoeve van de klant en roepen ze vervolgens andere servlets of JSP-pagina's aan om het antwoord te verzenden. Opgemerkt moet worden dat servlets en JSP-pagina's in veel gevallen uitwisselbaar zijn. Net als servlets draaien JSP-pagina's doorgaans aan de kant van de webserver, ook wel een JSP-container genoemd. Wanneer een voor JSP geschikte webserver het eerste verzoek voor een JSP-pagina ontvangt, vertaalt de JSP-container de JSP-pagina naar een Java-servlet die het huidige verzoek en alle daaropvolgende verzoeken aan die pagina verwerkt. Als er fouten optreden bij het compileren van een nieuwe servlet, resulteren deze fouten in fouten in de compilatiefase. De JSP-container plaatst tijdens de vertaalfase de Java-instructies die het JSP-paginaantwoord implementeert in een methode _jspService. Als de servlet zonder fouten compileert, roept de JSP-container de methode aan _jspService om het verzoek te verwerken. De JSP-pagina kan het verzoek rechtstreeks verwerken of andere webapplicatiecomponenten aanroepen om te helpen bij het verwerken van het verzoek. Eventuele fouten die optreden tijdens de verwerking veroorzaken uitzondering op de webserver in de aanvraagfase. Alle statische HTML-tekst, in de documentatie JSP genoemd HTML-sjabloon (template HTML), wordt onmiddellijk naar de uitvoerstroom verzonden. De pagina-uitvoerstroom wordt gebufferd. Buffering wordt verzorgd door de klas JspWriter <%@ page> . Door de aanwezigheid van een buffer kunnen de antwoordheaders samen met de uitvoertekst in de uitvoerstroom worden opgenomen. In de buffer worden de kopjes vóór de tekst geplaatst. Het is dus voldoende om een ​​JSP-pagina te schrijven en deze op te slaan in een bestand met de extensie jsp
en installeer het bestand in de container, net als een HTML-pagina, zonder dat u zich zorgen hoeft te maken over compilatie. Tijdens de installatie kunt u de initiële JSP-paginaparameters op dezelfde manier instellen als de initiële parameters van de servlet.
1) NetBeans 7.3;
2) Maven;
3) Slaapstand;
4) Veer MVC;
5) JSP+JSTL;
6) Kennis over servlets, sessies, JavaBean, XML, etc.;
7) HTML+CSS (een beetje schoonheid naar jouw smaak, maar het is beter om de verkeerde mensen te betalen - je zult genoeg problemen hebben met de serverkant);
8) Java SE (kennis van collecties, vermogen om met uitzonderingen om te gaan... Over het algemeen een standaardset);
9) Kennis van ontwerppatronen (DAO, Factory);
10) PPV;
11) SVN;

12) SQL (voor het schrijven van scripts die onze databases vullen).

Laten we beginnen met waar we onze code opslaan en hoe we deze met vrienden kunnen delen. Ik denk dat niet alle beginners kennis hebben van repositories, en dit deel is alleen voor hen bedoeld.

SVN
Er bestaat zoiets als een repository: een externe code-opslagserver.
Als u een testtaak krijgt en deze naar een archief verzendt, wordt u hoogstwaarschijnlijk ook verzonden. Misschien sturen ze je niet, maar ze zullen zeker teleurgesteld in je zijn.

Er zijn verschillende repository's CVS, SVN, Git. Voor beginners denk ik dat SVN optimaal is. Het belangrijkste voor jou is niet om te weten wat het is, maar om het te kunnen toepassen. Voorlopig is dit voldoende, de rest komt met ervaring.

Verwijder vervolgens het project dat u hebt vastgelegd volledig. Ga vervolgens naar de map waar uw projecten zijn opgeslagen en controleer of alles daadwerkelijk is verwijderd. Vervolgens keert u terug naar NetBeans en zoekt u naar het tabblad Groep in de menubalk (in het paneel waar Bestand, Weergave, Bewerken, Ga, Bron...) staat, waar onze Subversion staat. En in het submenu erop staat "Get". Vervolgens moet u in de dialoogvensters een link naar de repository opgeven (dit is de link die u op de site hebt ontvangen op het tabblad "Broncode"). En als u wordt aangeboden om mappen te downloaden, moet u dat doen zoek uw project in de repositoryboom en selecteer het, en aan het einde downloadt u uw project. Dit is hoe code wordt uitgewisseld.
Uw project wordt voortdurend gesynchroniseerd met de repository en markeert bestanden die zijn gewijzigd of nieuw zijn (afhankelijk van welke versie in de repository verschilt). Om bij te werken, moet je het contextmenu oproepen en op het tabblad "Versiebeheer" staat een grote lijst met wat je met het project kunt doen. “Update” betekent het bijwerken van uw bestanden; "Commit" - plaats de code die u hebt geschreven of gewijzigd in de repository; "Reset" - keert terug naar de versie in de repository, en "Vergelijk" - geeft wijzigingen weer in rijen die verschillen van de verwijderde. Dit is een manier van teamcode delen die altijd wordt gebruikt en waar u aan moet wennen.

Je hebt NetBeans al gedownload en met SVN gespeeld - laten we nu aan de slag gaan. Maak een project. Klik op “Een project maken”, selecteer daar Maven-> Webapplicatie. Noem het hoe je wilt, het is allemaal jouw fantasie. We hebben dus een webapplicatie, ons project wordt samengesteld met Maven, we hebben een doel en nu is het tijd om na te denken over hoe we het kunnen implementeren. Dat wil zeggen dat u als ontwikkelaar moet nadenken over hoe uw applicatie eruit zal zien, welke architectuur deze zal hebben, de pakketboom, enzovoort. Het totale aantal coderegels is hier ongeveer 4000 en het is beter om van tevoren voor een mooie architectuur te zorgen, anders begrijp je later gewoon niet wat waar is en hoe het voor je werkt, door welk wonder je bijvoorbeeld geef het laatste gekochte weer, hoe u het totale aantal aankopen berekent. En als je dan wordt gevraagd iets af te maken of toe te voegen, zul je beseffen dat het gemakkelijker is om alles vanaf nul te schrijven.

En natuurlijk moeten we ons plan van aanpak bedenken.

Dus: actieplan
1) beschrijf entiteit(entiteiten) - entiteiten. Dit is een POJO - een klasse die aan de database is gekoppeld met behulp van een annotatie (@Entity) of via XML. We zullen JPA gebruiken, dus we moeten javax.persistence importeren.* Waarom niet de Hibernate Persistence API, want als we deze gebruiken en vervolgens de ORM-bibliotheek willen wijzigen, zullen we onze klassen moeten herschrijven, en JPA is een standaard van zon. Wat betreft wat JPA is, kan ik u dit in mijn eigen woorden vertellen: het is een bibliotheek die een API biedt voor het werken met *langlevende* objecten, dat wil zeggen dat het ons in staat stelt onze objecten gemakkelijk in de database op te slaan. Ik kan je advies geven: maak hier een apart pakket voor, noem het entiteit of domein - wat je maar wilt, het belangrijkste is dat het voor je duidelijk is. Het zou er zo uit kunnen zien: edu.shop.model.domain.Customer.java edu.shop.model.domain.Notebook.java.
Ik zal het direct in meer detail beschrijven als ik dit item beschouw. Nu is het de taak om een ​​actieplan te bedenken.

2) Maak HibernateUtil aan (in het algemeen impliceert het achtervoegsel of voorvoegsel Util dat de code in deze klasse universeel is en door veel klassen wordt gebruikt).
In HibernateUtil plaatsen we dus een SessionFactory. Hij is zwaar. Deze code zou in theorie onafhankelijk moeten zijn van de gehele applicatie, omdat deze bij het opstarten een verbinding met de database tot stand brengt en ons alleen sessies met de database zou moeten geven. Wij registreren ook onze entiteitsklassen in deze klasse. Over deze les vertel ik later meer. Laten we het ook in een apart pakket stoppen, bijvoorbeeld edu.shop.model.hbutil.HibernateUtil.java

3) Schrijf DAO.
Wat moet ik erin schrijven? We schrijven wat we uit de database willen halen, maar we hoeven niet na te denken over hoe deze gegevens zijn verkregen, het resultaat is belangrijk. We definiëren bijvoorbeeld de ProductDAO-interface en schrijven daarin methoden
Lijst > getAllProducts(); dan schrijven we de implementatie ervan ProductDAOImpl.

Wat is het idee? Als jij en ik deze aanvraag zouden schrijven, zouden jullie zeggen: “Micha, ik heb de volgende gegevens uit de database nodig: alle producten die ik in de database heb.” Ik antwoord: “geen vraag.” En dan de volgende ontwikkeling van gebeurtenissen: in uw code schrijft u, waar u ook vragen moet stellen aan de database, het volgende%

*hier is een aanroep van de methode*.getAllProducts(); - en je ziet dat de compiler niet vloekt, en ik heb misschien nog geen tijd gehad om de implementatie van deze interface te schrijven. En wat is het resultaat? Je hebt alles gecompileerd, maar je hebt niet eens werkende code. Hier zullen we Enums en het Factory-patroon gebruiken, en nog iets anders, maar alles heeft zijn tijd. Het is in DAO dat je speciale aandacht moet besteden aan het afhandelen van uitzonderingen, in ieder geval het genereren van foutpagina's. Zodat je snel een stukje kapotte code kunt vinden. Anders wordt u eenvoudigweg gemarteld met foutopsporing.

3) Ons werk met Spring MVC begint hier. Dit is een lang verhaal en er zal een apart artikel aan worden gewijd. Ik zal meteen zeggen dat dit het moeilijkste is in deze toepassing. Maar ik zal je een eenvoudiger optie laten zien: hoe je alles kunt weergeven zonder je al te veel zorgen te maken over het MVC-patroon.
Laten we het eens hebben over het gebruik van scriptlets.

4) Hier zullen we hulpklassen hebben die allerlei soorten goodies aan ons project toevoegen: het berekenen van het totale aantal aankopen; laatste gekochte artikel; hulpvariabelen die voor ons nuttig zullen zijn voor de werking van de methode, die bijvoorbeeld dingen uit de database voor ons niet meer dan 5000 UAH of niet minder dan 500 zullen weergeven; weergave van alle Asus-laptops. Dit punt hangt nauw samen met het vorige.

Laten we het daar voorlopig bij laten. De rest zullen we later wel ontdekken. We hebben dus een plan, laten we beginnen met de uitvoering ervan.

Entiteit

We hebben ons project gemaakt en ons entiteitspakket gemaakt. Laat het edu.shop.entity zijn. Daar maken we de volgende klassen:

Opmerking. De mand waarin onze gekochte goederen worden opgeslagen, zal als een tabel in de database zijn. Ik deed dit omdat ik daarop enkele basisprincipes van het werken met de database zal laten zien. In een reëel geval zou het passender zijn om collecties te gebruiken om onze goederen op te slaan.

1) Product
2) Notitieboekje
3) Camera
4) Boek
5) Kabel
6) Klant
7) Winkelwagen

Laten we het even hebben over wat een entiteitsklasse is.
Entiteit is een POJO-klasse die aan de database is gekoppeld met behulp van een annotatie (@Entity) of via XML. Voor deze klasse gelden de volgende eisen:

Moet een lege constructor hebben (openbaar of beschermd);
- Kan niet worden genest, interface of opsomming;
- Kan niet definitief zijn en kan geen definitieve velden/eigenschappen bevatten;
- Moet minimaal één @Id-veld bevatten.

In dit geval kan de entiteit:

Entiteiten kunnen aan elkaar gerelateerd zijn: één-op-één, één-op-veel, veel-op-één en veel-op-veel.

We zullen annotaties gebruiken. En hier hebben we meteen de mogelijkheid om het op twee manieren te beschrijven. Ofwel schrijven we annotaties direct boven de velden, of boven de getters. Ik zal één ding zeggen: het is correct om bovenstaande getters te schrijven, en je kunt de reden op Google vragen. Ik kan niet absoluut alle onderwerpen hier beschrijven.

Er is nog één ding dat ik wil zeggen. Om dit te doen, moet u twee voorbeelden laten zien van de beschrijving van de entiteitsklasse. Dus het eerste voorbeeld:
Ik heb er commentaar op geschreven in de code zelf:

Importeer java.io.Serializeerbaar; javax.persistence.* importeren; importeer javax.validation.constraints.Size; /** * * @author Mikhail Shumenko */ @Entity //Met deze annotatie geven we aan dat deze klasse een entiteit is. @Table(name = "CART") // Met deze annotatie geven we aan dat een tabel met de naam CART verantwoordelijk is voor deze entiteit in de database // Ik zou willen opmerken dat de case niet belangrijk is, deze annotatie kan dan worden weggelaten Hibernate zal voor ons een database maken met / /name zoals de klasse public class CartEntity implementeert Serializable ( //Hier schrijven we annotaties boven de velden. Correct schrijven boven getters //Beschrijf de ID van de tabel @Id //Geef aan dat deze klasse veld is verantwoordelijk voor een kolom in de tabel met de naam Id //Als we dit niet specificeren, zal hibernate een kolom maken met dezelfde naam als het veld @Column(name = "ID") // U kunt een veel hier)) Waarom heb ik het hier zo geschreven? Over het algemeen kunt u AUTO in //@GeneratedValue(strategy=GenerationType.in plaats van TABLE) schrijven en //wanneer de tabel voor het eerst wordt geladen, wordt Id automatisch gegenereerd van 1 tot de maximale waarde.",allocationSize = 1) @GeneratedValue (strategy = GenerationType.TABLE, generator = "cartid") private Integer id; //Указываем максимальный размер. Это строка из 25 символов. @Size(max = 25) @Column(name = "NAMEITEM") //Если тип нашего поля String, то и создаваться будет столбец с типом VARCHAR(в Derby) //Если Integer, то будет столбец, в который поместить можно только Integer //boolean в Derby - это столбец с типом SMALLINT private String nameItem; @Column(name = "PRICE") private Integer price; public CartEntity() { } public CartEntity(String nameItem, int price) { this.nameItem = nameItem; this.price = price; } public CartEntity(Integer id,String nameItem, int price) { this.id=id; this.nameItem = nameItem; this.price = price; } public CartEntity(Integer id) { this.id = id; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNameItem() { return nameItem; } public void setNameItem(String nameItem) { this.nameItem = nameItem; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } } !}

//Als je 20 dingen in de tabel hebt, worden er 1 tot 20 gegenereerd. //Maar bij daaropvolgende toevoegingen zal de id van het toegevoegde ding ongeveer zo zijn: 345768. //Ik heb alles zo geschreven dat mijn laatste is. id werd in de tabel opgeslagen en vervolgens adequaat gegenereerd met daaropvolgende toevoegingen.

java.io importeren.Serializeerbaar; javax.persistence.* importeren; /** * * @author miha */ @Entity //Zie je, ik heb de @Table-annotatie niet gespecificeerd //Hibernate zal alles voor mij begrijpen. public class Product implementeert Serializable (private Integer id; private String nameProduct; private Integer AvailableProduct; @Id @GeneratedValue(strategie = GenerationType.AUTO) //Ik heb Id boven de getter beschreven, wat betekent dat de rest van de velden zal worden verwerkt getters. public Integer getId() ( return id; ) public void setId(Integer id) ( this.id = id; ) public String getNameProduct() ( return nameProduct; ) public void setNameProduct(String nameProduct) ( this.nameProduct = naamProduct ; ) public Integer getAvailableProduct() (retourneren beschikbaarProduct; ) public void setAvailableProduct(Integer beschikbaarProduct) ( this.availableProduct = beschikbaarProduct; ) )

Je hebt dus twee voorbeelden van entiteitsklassen. Maak de rest met behulp van deze voorbeelden. Velden zoals: model, jaar van uitgave, naam, kosten - alles is aan uw verbeelding. Zorg ervoor dat u het veld Beschikbaar opneemt. Het zal later nuttig voor u zijn. Je kunt er een Booleaanse waarde van maken en een kolom met de naam hoeveelheid toevoegen. Dit zal allemaal nuttig voor ons zijn.

Laten we nu een voorbeeld geven van onze HibernateUtil

/* * Om deze sjabloon te wijzigen, kiest u Extra | Sjablonen * en open het sjabloon in de editor.

*/ pakket edu.shumenko.hibernate; importeer edu.shumenko.entity.BookEntity; importeer edu.shumenko.entity.CableEntity; importeer edu.shumenko.entity.CameraEntity; importeer edu.shumenko.entity.CartEntity; importeer edu.shumenko.entity.CustomerEntity; importeer edu.shumenko.entity.NotebookEntity; importeer edu.shumenko.entity.ProductEntity; importeer org.hibernate.cfg.AnnotationConfiguration; importeer org.hibernate.SessionFactory; /** * Hibernate Utility-klasse met een handige methode om het Session Factory *-object op te halen.

* * @author Mikhail Shumenko */ public class HibernateUtil ( //Maak onze SessionFactory. private static final SessionFactory sessionFactory; static ( try ( //Maak een nieuw exemplaar van AnnotationConfiguration AnnotationConfiguration ac = new AnnotationConfiguration(); //We hebben dit nodig in zodat we al onze entiteitsklassen toevoegen. // elk van uw entiteiten moet hier worden geregistreerd. Als u het niet registreert, werkt het niet. CustomerEntity.class); //Dus we hebben eigenlijk onze Session Factory gemaakt //Het is nodig omdat we met de database werken via sessies / /Details komen later, we weten nu hoe we het moeten maken en hoe we ermee moeten werken sessionFactory = ac.configure().buildSessionFactory(); catch (Throwable ex) ( // Registreer de uitzondering. System.err.println("Initiële creatie van SessionFactory mislukt." + ex);

gooi nieuwe ExceptionInInitializerError(ex);
) ) openbare statische SessionFactory getSessionFactory() ( return sessionFactory; ) )
DAO
Laten we verder gaan met het volgende deel. Wat is DAO. Dit is een ontwerppatroon.
De betekenis ervan:
- DAO handelt geen transacties, sessies of verbindingen af. Dit gebeurt buiten de DAO om flexibiliteit te bieden.
Google vertelt je altijd meer.

We schrijven voorlopig een DAO voor onze producten.
Laten we dus eens nadenken over wat we eigenlijk nodig hebben. De Producttabel heeft 4 velden Id,nameProduct,available+amount+actionForServlet. We hebben het nodig om categorieën op onze website te maken. Over het laatste veld zijn we nog niet bezig. Het enige dat we nodig hebben, is een lijst met producten.

Een interface schrijven
openbare interface ProductDAO ( ProductDAO INSTANCE_PRODUCT= new ProductDAOImpl(); Lijst GetProducts();

//en de methode waarmee we zullen werken)
Implementatie van onze interface. Zie de code voor uitleg. /* * Om deze sjabloon te wijzigen, kiest u Extra | Sjablonen * en open het sjabloon in de editor. */ pakket edu.shop.model.dao; java.util.List importeren; importeer org.hibernate.Criteria; importeer org.hibernate.Session; /** * * @author Mikhail Shumenko */ public class ProductDAOImpl implementeert ProductDAO (@Override public List GetProducts() (Lijst

Resultaat = nul; // Maak een sessie aan, het is nodig om transacties te gebruiken // Grof gezegd is een transactie als een herstelpunt als het niet helemaal lukt, dan worden alle wijzigingen teruggedraaid.

Categorieën

try ( session.beginTransaction().begin(); // Criteria worden gebruikt voor een query om gegevens uit de database te verkrijgen // Deze formulering zal, denk ik, voorlopig voldoende voor je zijn // Als parameter geven we de entiteit door klasse die we gebruiken. Als de gegevens uit de Cart-tabel worden ontvangen, moeten deze worden doorgegeven //Cart.class Criteria criteria = session.createCriteria(Product.class) result = (List);<% for (Product product:ProductDAO.INSTANCE_PRODUCT.getProducts()) {%> <%}%> <% for (Product product: ProductDAO.INSTANCE_PRODUCT.getProducts()) {%> <%}%>
Sessiesessie = HibernateUtil.getSessionFactory().openSession();"><%=product.getName()%>
) criteria.lijst();<%=product.getAvailable()%>

Maar dit is de eerste keer, en over het algemeen is het slecht om dit te doen. Dit doorbreekt ons MVC-patroon. Hoe je het correct moet doen, zal ik in de volgende les uitleggen, als ze me een uitnodiging geven. In de tweede les gaan we in op de Lente, in de derde gaan we in op het Fabriekspatroon en gaan we dieper in op Hibernate. Voor degenen die bijzonder ongeduldig zijn, zal ik je laten zien hoe je uit de database kunt verwijderen, in de database kunt opslaan en alles volledig uit de database kunt verwijderen. Laten we een gedetailleerde discussie voor later achterlaten over hoe we dit allemaal als één geheel kunnen laten communiceren met onze applicatie.

Opslaan in DB

public void addItemToCart(CartEntity winkelwagen) ( Sessiesessie = HibernateUtil.getSessionFactory().openSession(); try ( session.beginTransaction().begin(); session.save(winkelwagen); session.getTransaction().commit(); ) catch (Uitzondering ex) ( ex.printStackTrace(); ) eindelijk ( if (sessie != null) ( session.close(); ) ) )

Verwijderen uit de database op basis van ID

public void deleteItemFromCart(Integer id) ( Sessiesessie = HibernateUtil.getSessionFactory().openSession(); try ( session.beginTransaction().begin(); CartEntity itemDelete = (CartEntity) session.get(CartEntity.class, id); session.delete(itemDelete); session.getTransaction().commit(); catch (Exception ex) ( ex.printStackTrace(); ) tenslotte ( if (sessie != null) ( session.close(); ) )

Groeps-ID uit de database verwijderen.

public void deleteAllItemToCart(List idAllItemsInCart) ( Sessie sessie = HibernateUtil.getSessionFactory().openSession(); try ( session.beginTransaction().begin(); for(Geheel getal id:idAllItemsInCart)( CartEntity itemDelete = (CartEntity) session.get(CartEntity.class, id); session.delete(itemDelete); session.getTransaction().commit() catch (Exception ex) ( ex.printStackTrace(); ) tenslotte ( if (sessie != null) ( session.close() ;)))

U hebt ook een Hibernate-configuratiebestand nodig. Creëer een winkeldatabase in Derby. Gebruikersnaam en wachtwoord zijn respectievelijk root en pass. Als het niet lukt, wees dan niet boos, ik geef het nog wat tijd.

org.hibernate.dialect.DerbyDialect org.apache.derby.jdbc.ClientDriver jdbc:derby://localhost:1527/shop wortel doorgang UTF-8 update

We zullen later praten over het invullen van onze databases. U kunt ze handmatig invullen. Of wacht op de volgende les.

Ik ga verder met het beschrijven van het proces van het maken van een webapplicatie met behulp van servlets, jsp, Maven en Tomcat. , indien nodig.

Wij creëren entiteiten.
Laten we een User-klasse maken in het entiteitenpakket, waarin we de naam en het wachtwoord van twee privéreeksvariabelen zullen maken. Laten we constructors maken (standaard en één die beide waarden accepteert), getters/setters, en voor de zekerheid de methode toString() overschrijven, evenals de methoden equals() en hashCode().
Een model maken.
Vervolgens maken we een klasse (en implementeren de singleton-sjabloon daarin) in het modelpakket, en we noemen het ook behoorlijk kleurrijk Model. Laten we er een privégebruikerslijstobject in maken en twee methoden maken: één zodat u een gebruiker kunt toevoegen, en de tweede - laat het eenvoudigweg een lijst met tekenreeksen (gebruikersnamen) retourneren. Omdat ons gebruikersobject uit een naam en wachtwoord bestaat, willen we gebruikerswachtwoorden niet 'openbaar maken', dus sturen we alleen een lijst met hun namen terug.<>public class Model ( private static Model instance = new Model(); private List model; public static Model getInstance() ( return instance; ) private Model() ( model = new ArrayList
();
) public void add(Gebruiker gebruiker) ( model.add(gebruiker); ) public List list() ( return model.stream() .map(Gebruiker::getName) .collect(Collectors.toList()); ) ) Iets over mvc. Omdat je over singleton hebt gehoord, betekent dit dat je waarschijnlijk ook over een ander ontwerppatroon hebt gehoord: MVC (model-view-controller, of in het Russisch model-view-controller, of net als in het Engels model-view-controller). De essentie ervan is om bedrijfslogica te scheiden van presentatie. Dat wil zeggen: scheid de code die definieert wat te doen van de code die definieert Iets over mvc. hoe weergeven
  • . De View (view of gewoon views) is verantwoordelijk voor de vorm waarin sommige gegevens worden gepresenteerd. In ons geval zijn weergaven onze JSP-pagina's. Daarom heb ik ze in een map met de naam views geplaatst. Het model zijn de feitelijke gegevens waarmee het programma werkt. In ons geval zijn dit gebruikers (lijst met gebruikers). Welnu, controllers vormen de verbindende schakel daartussen. Ze halen gegevens uit het model en dragen deze over naar weergaven, of ze ontvangen bepaalde gegevens van Tomcat, verwerken deze en dragen deze over naar het model. Bedrijfslogica (bijv.
  • ) moet daarin worden beschreven, en niet in het model of de weergave. Zo doet iedereen zijn eigen ding:
  • model slaat gegevens op
Weergaven vormen een prachtige weergave van gegevens verwerkingsverantwoordelijken verwerken gegevens! :) Laten we terugkeren naar onze mening.
Maak een formulier voor het toevoegen van een gebruiker.
Laten we een formulier toevoegen aan het add.jsp-bestand, bestaande uit twee tekstinvoer (de ene normaal, de andere een wachtwoordtype) en een knop voor het verzenden van gegevens naar de server.
Naam: Wachtwoord: Verzenden Hier heeft het formulier een methode-attribuut met de waarde post. Dit betekent dat de gegevens uit dit formulier in de vorm van een POST-verzoek naar de server worden verzonden. Het action attribuut is niet gespecificeerd, wat betekent dat dit verzoek naar hetzelfde adres gaat als waar we naar deze pagina zijn gegaan (/add). Onze servlet, die aan dit adres is gebonden, retourneert dus bij ontvangst van een GET-verzoek deze jsp met het formulier voor het toevoegen van gebruikers, en als hij een POST-verzoek ontvangt, heeft dit formulier zijn gegevens daarheen gestuurd (die we eruit zullen halen van het request-object in de doPost()-methode, verwerk het en breng het over naar het model om op te slaan). Het is vermeldenswaard dat invoer hier een naamparameter heeft (voor een veld met een naam heeft het de waarde naam, en voor een veld met een wachtwoord heeft het de waarde pass). Dit is een behoorlijk belangrijk punt. Omdat we, om deze gegevens (naam en wachtwoord die worden ingevoerd) uit het verzoek (al in de servlet) te halen, precies deze naam en pas zullen gebruiken. Maar daarover later meer. De knop voor het versturen van data zelf is wederom gemaakt in de vorm van een knop, en niet als input, zoals doorgaans gebruikelijk is. Ik weet niet hoe universeel deze optie is, maar het werkt voor mij in Chrome :)
Een POST-verzoek verwerken met een servlet.
Laten we terugkeren naar de AddServlet-servlet. We weten al dat we, om ervoor te zorgen dat onze servlet GET-verzoeken kan "vangen", de methode doGet() uit de klasse HttpServlet overschrijven. Om onze servlet te leren ook POST-verzoeken op te vangen, overschrijven we ook de methode doPost(). Het ontvangt soortgelijke verzoek- en antwoordobjecten van Tomcat, waarmee we zullen werken. Laten we eerst uit het verzoek de naam halen en de parameters doorgeven die het formulier heeft verzonden (als u ze in het formulier een andere naam hebt gegeven, dan zijn dit de namen die u schrijft). Vervolgens zullen we ons gebruikersobject maken met behulp van de ontvangen gegevens. Vervolgens halen we het modelobject op en voegen we de gemaakte gebruiker aan het model toe.
Laten we nu verder gaan met de ListServlet-servlet. We hebben de doGet()-methode al geïmplementeerd, die eenvoudigweg de controle overdraagt ​​aan de list.jsp-weergave. Als je dit nog niet hebt, doe het dan naar analogie met dezelfde methode uit de AddServlet-servlet. Nu zou het leuk zijn om een ​​lijst met gebruikersnamen van het model te krijgen en deze door te geven aan de weergave, die ze daar zal ontvangen en mooi zal weergeven. Hiervoor gebruiken we opnieuw het verzoekobject dat we van Tomcat hebben ontvangen. We kunnen een attribuut aan dit object toevoegen, het een naam geven en, in feite, het object zelf dat we naar de weergave willen overbrengen. Vanwege het feit dat we bij het overbrengen van het uitvoeringsproces van een servlet naar een weergave daar dezelfde verzoek- en antwoordobjecten doorgeven die de servlet zelf heeft ontvangen, en door onze lijst met namen aan het verzoekobject toe te voegen, kunnen we dan vanaf dit verzoek object in de weergave, maak onze lijst met gebruikersnamen en ontvang. We zijn klaar met de ListServlet-klasse, dus hier is de code voor het hele pakket app.servlets-klasse; app.model.Model importeren; javax.servlet.RequestDispatcher importeren; javax.servlet.ServletException importeren; javax.servlet.http.HttpServlet importeren; javax.servlet.http.HttpServletRequest importeren; javax.servlet.http.HttpServletResponse importeren; java.io.IOException importeren; java.util.List importeren; public class ListServlet breidt HttpServlet uit ( @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) gooit ServletException, IOException ( Modelmodel = Model.getInstance(); Lijstnamen = model.list(); req.setAttribute("userNames", namen ); RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/list.jsp"); requestDispatcher.forward(req, resp));
Java-code uitvoeren in jsp-bestanden.
Laten we nu verder gaan met het list.jsp-bestand. Dit bestand wordt alleen uitgevoerd als de ListServlet het uitvoeringsproces hier doorstaat. Bovendien hebben we in die servlet al een lijst met gebruikersnamen uit het model opgesteld en deze hier in het verzoekobject doorgegeven. Gegeven een lijst met namen, kunnen we er een for-lus doorheen halen en elke naam afdrukken. Zoals ik al zei, kunnen jsp-bestanden Java-code uitvoeren (in principe is dit wat ze anders maakt dan statische HTML-pagina's). Om code uit te voeren, volstaat het om de constructie op de plaats te plaatsen die we nodig hebben<% // java код %>Binnen deze constructie krijgen we toegang tot verschillende variabelen: request - ons request-object, dat we hebben doorgegeven van de servlet, waar het eenvoudigweg req response werd genoemd - het responsobject, in de servlet heette het resp out - een object van het type JspWriter (overgenomen van de gebruikelijke Writer), waarmee we iets rechtstreeks in de HTML-pagina zelf kunnen “schrijven”. Schrijf uit.println(" Hallo wereld!") lijkt erg op de invoer System.out.println("Hallo wereld!"), maar verwar ze niet! out.println() "schrijft" naar de html-pagina, en System.out.println - naar de systeemuitvoer Als je de System.out.println() -methode aanroept in de sectie met de jsp-code - dan zie je de resultaten in de Tomcat-console, en niet op de pagina, zoals je misschien leuk vindt :) Je kunt naar andere zoeken. beschikbare objecten binnen jsp Met behulp van het request-object kunnen we een lijst met namen verkrijgen die door de servlet zijn doorgegeven (we hebben het corresponderende attribuut aan dit object toegevoegd), en met behulp van het out-object kunnen we deze namen voorlopig eenvoudig weergeven in de vorm van een html-lijst:<% List names = (List) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { for (String s: names) { out.println("" + s + ""); } } %>Als we de lijst alleen willen weergeven als er gebruikers zijn, en anders een waarschuwing willen weergeven dat er nog geen gebruikers zijn, kunnen we deze sectie een beetje herschrijven:<% List names = (List) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(""); for (String s: names) { out.println("" + s + ""); } out.println(""); } else out.println("There are no users yet!"); %>Nu we weten hoe we gegevens van servlets naar views kunnen overbrengen, kunnen we onze AddServlet iets verbeteren, zodat er een melding wordt weergegeven over de succesvolle toevoeging van een gebruiker. Om dit te doen, kunnen we in de doPost()-methode, nadat we een nieuwe gebruiker aan het model hebben toegevoegd, de naam van deze gebruiker toevoegen aan de attributen van het req-object en de controle teruggeven aan de add.jsp-weergave. En maak daarin al een sectie met Java-code, waar u kunt controleren of een dergelijk kenmerk in het verzoek staat, en zo ja, dan een bericht weergeven dat de gebruiker met succes is toegevoegd. Na deze wijzigingen zal de volledige AddServlet-servletcode er ongeveer zo uitzien: package app.servlets; app.entities.Gebruiker importeren; app.model.Model importeren; javax.servlet.RequestDispatcher importeren; javax.servlet.ServletException importeren; javax.servlet.http.HttpServlet importeren; javax.servlet.http.HttpServletRequest importeren; javax.servlet.http.HttpServletResponse importeren; java.io.IOException importeren; public class AddServlet breidt HttpServlet uit ( @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) gooit ServletException, IOException ( RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp"); requestDispatcher.forward(req, resp); ) @ Overschrijf beschermde ongeldige doPost(HttpServletRequest req, HttpServletResponse resp) gooit ServletException, IOException ( String naam = req.getParameter("naam"); ​​String wachtwoord = req.getParameter("pass"); Gebruiker gebruiker = nieuwe gebruiker(naam, wachtwoord) ; req.setAttribute("userName", name); Hier aan het einde van de doPost()-methode stellen we het attribuut in met de naam van het toegevoegde attribuut. in het gebruikersmodel, waarna we de methode doGet() aanroepen, waaraan we het huidige verzoek en antwoord doorgeven. En de doGet()-methode draagt ​​de controle al over aan de weergave, waar deze een verzoekobject verzendt met de naam van de toegevoegde gebruiker als attribuut. Het blijft nodig om add.jsp zelf te corrigeren, zodat het een dergelijke melding weergeeft als een dergelijk attribuut aanwezig is. Laatste add.jsp<%@ page contentType="text/html;charset=UTF-8" language="java" %>Nieuwe gebruiker toevoegen Super-app!<% if (request.getAttribute("userName") != null) { out.println("User "" + request.getAttribute("userName") + "" added!"); } %>Voeg gebruikersnaam toe: Wachtwoord: Verzenden Terug naar hoofdpagina De body van de pagina bestaat uit een div met een header, waarna er een div-container is voor de inhoud, deze controleert of een attribuut met de gebruikersnaam bestaat, vervolgens een div met een formulier voor het toevoegen van gebruikers, en aan het einde is er een voettekst met een knop om terug te keren naar de hoofdpagina. Het lijkt misschien alsof er te veel div's zijn, maar we zullen ze later gebruiken als we stijlen toevoegen :) En de definitieve versie is list.jsp<%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %>Gebruikers Super-app!<% List names = (List) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(""); for (String s: names) { out.println("" + s + ""); } out.println(""); } else out.println("There are no users yet!"); %>Terug naar het hoofdmenu We hebben dus een volledig werkende webapplicatie die gebruikers kan opslaan en toevoegen, en een lijst met hun namen kan weergeven. Het enige dat overblijft is om het te verfraaien... :)
Stijlen toevoegen. We gebruiken het W3.CSS-framework.
Op dit moment werkt onze applicatie, maar absoluut gek :) We moeten een achtergrond, tekst en knopkleuren toevoegen, lijsten stileren, uitlijnen, inspringingen toevoegen, in het algemeen een heleboel dingen. Als u stijlen handmatig schrijft, kan dit veel tijd en zenuwen kosten. Daarom stel ik voor om het CSS-framework W3.CSS te gebruiken. Het heeft al kant-en-klare klassen met stijlen; het enige dat overblijft is om de CSS-klassen die we op deze plaatsen willen toepassen op de juiste plaatsen te plaatsen. Om ze aan onze pagina's toe te voegen, moeten we eerst een bestand met stijlen toevoegen. Dit kan op twee manieren: 1. blader door onze pagina's en plaats in het hoofdgedeelte een directe link naar het bestand met stijlen. Deze optie is geschikt als u een constante internetverbinding heeft. Wanneer u vervolgens uw pagina's op een lokale server opent, worden de stijlen van internet gehaald. 2. Als u alle stijlen lokaal wilt hebben en niet afhankelijk wilt zijn van een internetverbinding, kunt u eenvoudig het bestand met stijlen downloaden en ergens in de webmap plaatsen (bijvoorbeeld web/styles/w3.css), en vervolgens ga door al onze pagina's (index.html, add.jsp, list.jsp) en voer een link in naar dit bestand met stijlen in de head-sectie. Ga daarna gewoon door de tags en tag ze met de stijlen die je leuk vindt . Ik zal hier niet in detail op ingaan, maar zal meteen mijn kant-en-klare versies geven van mijn drie bestanden met gearrangeerde stijlklassen. index.html Super-app!<%@ page contentType="text/html;charset=UTF-8" language="java" %>Nieuwe gebruiker toevoegen Super-app!<% if (request.getAttribute("userName") != null) { out.println("\n" + " ×\n" + " User "" + request.getAttribute("userName") + "" added!\n" + ""); } %>Super-app!<%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %>Lijst met gebruikers Voeg gebruiker add.jsp toe<% List names = (List) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(""); for (String s: names) { out.println("" + s + ""); } out.println(""); } else out.println("\n" + " ×\n" + " There are no users yet!\n" + ""); %>Voeg gebruikersnaam toe: Wachtwoord: Verzenden Terug naar hoofdlijst.jsp

Gebruikerslijst Super app!
  • Gebruikers
  • Terug naar het hoofdmenu Dat is alles :) Als je nog vragen hebt of opmerkingen hebt, of, integendeel, iets niet lukt, laat dan een reactie achter. Nou, ik zal een paar screenshots bijvoegen van wat er allemaal uitkwam.
En tot slot. Als je met dit project wilt oefenen, kun je het volgende proberen:

JavaServer Pages (JSP) is een standaard Java-extensie die bovenop servletextensies wordt gedefinieerd. Het doel van JSP is om het eenvoudiger te maken om dynamische webpagina's te maken en te beheren.

Zoals eerder vermeld ondersteunt de gratis Tomcat-implementatie van jakarta.apache.org automatisch JSP.

Met JSP kunt u HTML-webpagina's combineren met stukjes Java-code in één document. Java-code is omgeven door speciale tags die de JSP-container vertellen dat deze de code moet gebruiken om een ​​enkel document of een deel ervan te genereren. Het voordeel van JSP is dat u één enkel document kunt bevatten dat zowel de pagina als de Java-code vertegenwoordigt die daarin is opgenomen.

Het nadeel is dat degene die de JSP-pagina onderhoudt ervaring moet hebben met zowel HTML als Java (de verwachting is echter dat visuele JSP-paginabouwers in de loop van de tijd beschikbaar zullen komen).

Wanneer de JSP voor het eerst wordt geladen, wordt deze geladen door de JSP-container (die gewoonlijk wordt geassocieerd met of deel uitmaakt van een webserver). Vervolgens wordt de servletcode, die noodzakelijkerwijs wordt gemarkeerd met JSP-tags, automatisch gegenereerd, gecompileerd en in de servletcontainer geladen. Het statische deel van de HTML-pagina wordt gedaan door een statisch object van het type String door te geven aan de write() -methode. Het dynamische gedeelte wordt direct in de servlet opgenomen.

Vanaf dit punt, totdat de oorspronkelijke JSP-pagina wordt gewijzigd, gedraagt ​​deze zich alsof het een statische HTML-pagina is die aan de servlet is gekoppeld (alle HTML-code wordt echter feitelijk door de servlet gegenereerd). Als u de broncode voor de JSP wijzigt, wordt deze automatisch opnieuw gecompileerd en opnieuw geladen de volgende keer dat u die pagina opvraagt. Vanwege deze dynamiek zult u uiteraard een trage reactie zien bij de eerste JSP-toegang. Omdat JSP doorgaans echter veel vaker wordt gebruikt dan gewijzigd, zult u de gevolgen van deze vertraging doorgaans niet voelen.

De structuur van een JSP-pagina houdt het midden tussen een servlet en een HTML-pagina. JSP-tags beginnen en eindigen met een hoekhaakje, net als HTML-code, maar de tags bevatten ook procenttekens, dus alle JSP-tags worden als volgt geschreven:

Het leidende procentteken kan worden gevolgd door andere tekens die het exacte type JSP-code in de tag identificeren.<%=), результат вычислений преобразуется в строку, а затем поместится в сгенерированную Web страницу:

//:! c15:jsp:ShowSeconds.jsp< html >< body > < H1 >De tijd in seconden is:<%= System . currentTimeMillis ()/ 1000 %> ///:~

In de JSP-voorbeelden in dit boek betekent een uitroepteken in de eerste "commentaarregel" dat de eerste en laatste regel niet zullen worden opgenomen in het daadwerkelijke codebestand dat in de broncodeboom van dit boek wordt geplaatst.

Wanneer een client een verzoek indient bij een JSP-pagina, moet de webserver worden geconfigureerd om het verzoek door te sturen naar de JSP-container, die vervolgens de pagina bevat. Zoals eerder vermeld, worden de op de pagina gespecificeerde componenten de eerste keer dat een pagina wordt geopend gegenereerd en worden een of meer servlets gecompileerd door de JSP-container. In het bovenstaande voorbeeld zou de servlet code bevatten om het HTTPServletResponse-object te configureren, een PrintWriter-object te produceren (dat altijd wordt aangeroepen) en vervolgens de timing mogelijk te maken met een zeer korte verklaring, maar de gemiddelde HTML-programmeur/webontwerper heeft geen ervaring met schrijven zo'n code.

Impliciete objecten

Servlets omvatten klassen die handige hulpprogramma's bieden, zoals HttpServletRequest, HttpServletResponse, Session, enz. Objecten van deze klassen zijn ingebouwd in de JSP-specificatie en zijn automatisch beschikbaar voor gebruik in uw JSP zonder extra coderegels te schrijven. Impliciete JSP-objecten worden gedetailleerd weergegeven in de onderstaande tabel.

Impliciete variabelen Type (javax.servlet) Beschrijving Domein
Iets meer informatie - JSP heeft verschillende vooraf gedefinieerde objecten. Die. ze moeten worden gezien als kant-en-klare objecten die kunnen worden gebruikt. Dit zijn request, response, out, session, application, config, pageContext en page. Ik zal er een korte samenvatting van geven; het is mogelijk dat het voorlopig niet erg interessant zal zijn, en het is niet duidelijk. Maar voor het geval dat. Protocolafhankelijk subtype van HttpServletRequest Het verzoek waarmee de serviceaanvraag is gedaan. Iets meer informatie - JSP heeft verschillende vooraf gedefinieerde objecten. Die. ze moeten worden gezien als kant-en-klare objecten die kunnen worden gebruikt. Dit zijn request, response, out, session, application, config, pageContext en page. Ik zal er een korte samenvatting van geven; het is mogelijk dat het voorlopig niet erg interessant zal zijn, en het is niet duidelijk. Maar voor het geval dat.
antwoord Protocolafhankelijk subtype van HttpServletResponse Reactie op verzoek. pagina
paginaContext jsp.PageContext Een paginacontext die implementatie-afhankelijke mogelijkheden omvat en gemakkelijke methoden en naamruimtetoegang tot deze JSP biedt. pagina
sessie Protocolafhankelijk subtype http.HttpSession Een sessieobject dat is gemaakt voor het clientverzoek. sessie
Zie Sessieobject voor servlet. sollicitatie ServletContext app
De servletcontext die is verkregen uit het servletconfiguratieobject (bijvoorbeeld getServletConfig(), getContext(). uit jsp.JspWriter pagina
Een object dat naar de uitvoerstroom schrijft. configuratie ServletConfig pagina
pagina ServletConfig voor deze JSP. java.lang.Object pagina

Het zichtgebied van elk object kan aanzienlijk variëren.

Een sessieobject heeft bijvoorbeeld een bereik dat groter is dan een pagina, omdat het meerdere clientverzoeken en pagina's kan omvatten. Een applicatieobject kan service verlenen aan een groep JSP-pagina's die samen een webapplicatie vertegenwoordigen.

JSP-richtlijnen

<% @ directive { attr = "value" }* %>

Richtlijnen zijn berichten naar de JSP-container en worden aangegeven met het "@"-symbool:

<% @ page language = "java" %>

Richtlijnen sturen niets naar de uitvoerstroom, maar zijn belangrijk voor het instellen van de kenmerken van uw JSP-pagina en de afhankelijkheden van de JSP-container. De regel is bijvoorbeeld:

meldt dat de scripttaal die op de JSP-pagina wordt gebruikt Java is.

<% @ page session = "true" import =" java . util .*" %>

In feite beschrijft de JSP-specificatie alleen scriptsemantiek voor taalkenmerken die gelijkwaardig zijn aan "Java". Het doel van deze richtlijn is om flexibiliteit in de JSP-technologie in te bouwen. Als je in de toekomst een andere taal kiest, bijvoorbeeld Python (een goede keuze voor scripting), dan zou die taal ondersteuning moeten hebben voor de Java Runtime Environment, waardoor het Java-technologieobjectmodel voor de scriptomgeving zichtbaar wordt, vooral voor de impliciete variabelen hierboven gedefinieerd, JavaBeans-eigenschappen en openbare methoden.

De belangrijkste richtlijnen zijn paginarichtlijnen. Ze definiëren verschillende paginakenmerken en hoe deze kenmerken samenwerken met de JSP-container. Deze kenmerken omvatten: taal, uitbreidingen, import, sessie, buffer, autoFlush, isThreadSafe, info en errorPage.

Bijvoorbeeld:

Nadat u richtlijnen hebt gebruikt om een ​​scriptomgeving in te richten, kunt u scriptelementen gebruiken. JSP 1.1 heeft drie scripttaalelementen: declaratie, scriptlet en expressie. Verklaringen declareren elementen, scriptlets zijn instructiefragmenten en expressies zijn volledige taaluitdrukkingen. In JSP begint elk scriptelement met "<%". Синтаксис каждого из них:

<%! declaration %> <% scriptlet %> <%= expression %>

Spaties na "<%!", "<%", "<%=" и перед "%>" zijn niet vereist.

Al deze tags zijn gebaseerd op XML; je kunt zelfs zeggen dat een JSP-pagina kan worden weerspiegeld in een XML-document. De equivalente syntaxis voor de bovenstaande scriptelementen zou kunnen zijn:

< jsp : declaration >verklaring < jsp : scriptlet >scriptje < jsp : expression >uitdrukking

Daarnaast zijn er twee soorten opmerkingen:

<%-- jsp comment --%>

Met het eerste formulier kunt u opmerkingen toevoegen aan de JSP-broncode die in geen enkele vorm verschijnen op de HTML-pagina die naar de client wordt verzonden. Uiteraard is de tweede vorm van commentaar niet JSP-specifiek; het is een gewone HTML-commentaar. Het interessante is dat je JSP-code in een HTML-opmerking kunt invoegen en het resultaat wordt op de resulterende pagina weergegeven.

Declaraties worden gebruikt om variabelen en methoden te declareren in een scripttaal (momenteel alleen in Java) die op een JSP-pagina wordt gebruikt.

De declaratie moet een volledige Java-expressie zijn en mag geen uitvoer naar de uitvoerstroom produceren. In het Hello.jsp-voorbeeld hieronder zijn de declaraties voor de variabelen loadTime, loadDate en hitCount volledige Java-expressies die nieuwe variabelen declareren en initialiseren.<%-- //:! c15:jsp:Hallo.jsp%> <%-- Deze JSP-opmerking verschijnt niet in de gegenereerde html --%> <%@ page import="java.util.*" %> <%-- Dit is de JSP-richtlijn: --%> <% ! long loadTime = System.currentTimeMillis (); Date loadDate = new Date (); int hitCount = 0 ; %> <%-- Deze verklaring: --%>

De volgende paar regels zijn het resultaat van JSP-expressies die in de gegenereerde html zijn ingevoegd; Het teken "= geeft een JSP-expressie aan --<%= loadDate %>

Deze pagina is geladen<%= new Date () %>

Hallo wereld! Zijn<%= new Object () %>

Hier is een voorwerp:<%= (System.currentTimeMillis ()- loadTime )/ 1000 %>Deze pagina is verschenen

seconden<%= ++ hitCount %>Pagina is geopend<%= loadDate %>

<%-- tijden sindsdien%> <% System.out.println ("Goodbye" ); out.println ("Cheerio" ); %> ///:~

“Skriplet”, geschreven op de serverconsole en op de clientpagina. Houd er rekening mee dat u ";" moet invoeren: --

Aan het einde van het voorbeeld staat een scriptlet dat "Goodbye" naar de webserverconsole en "Cheerio" naar het impliciete JspWriter-uitvoerobject schrijft. Een scriptlet kan alle codefragmenten bevatten die geldige Java-instructies zijn. Scriptlets worden uitgevoerd tijdens de verwerking van verzoeken. Wanneer alle scriptletfragmenten in een bepaalde JSP worden gecombineerd in de volgorde waarin ze op de JSP-pagina verschijnen, moeten ze een geldige instructie produceren die specifiek is voor de Java-programmeertaal. Of het scriptlet wel of niet uitvoer naar de uitvoerstroom zal produceren, hangt alleen af ​​van de scriptletcode. Houd er rekening mee dat een scriptlet objecten kan beïnvloeden die voor het scriptlet zichtbaar zijn.

JSP-expressies zijn gemengd met HTML te vinden in het middelste gedeelte van Hello.jsp.

Expressies moeten volledige Java-instructies zijn die worden geëvalueerd, geconverteerd naar een tekenreeks en naar uitvoer worden verzonden. Als het resultaat van de instructie niet kan worden geconverteerd naar een String, wordt er een ClassCastException gegenereerd.

Velden en waarden extraheren

Het volgende voorbeeld is vergelijkbaar met het voorbeeld dat eerder in het gedeelte over servlets is gegeven. Wanneer u de pagina voor het eerst weergeeft, detecteert deze dat u geen velden heeft en retourneert een pagina met het formulier met dezelfde code als in het servletvoorbeeld, maar dan in JSP-indeling. Wanneer u een formulier met ingevulde velden verzendt naar dezelfde JSP-URL, detecteert de pagina de velden en geeft deze weer. Dit is een handige techniek omdat u hierdoor twee pagina's kunt hebben, waarvan één het formulier bevat dat de gebruiker moet invullen, en de andere bevat de responscode van deze pagina in één bestand, waardoor het gemakkelijker wordt om deze aan te maken en te onderhouden.<%-- //:! c15:jsp:DisplayFormData.jsp%> <%-- Gegevens extraheren uit een HTML-formulier. --%> <%@ page import="java.util.*" %>

Deze JSP genereert ook het formulier. --

<% Enumeration flds = request.getParameterNames (); if (! flds.hasMoreElements ()) { // Нет полей %>
<% for (int i = 0 ; i < 10 ; i ++) { %>Formuliergegevens weergeven<%= i %> :
<% } %>
<% } else { while (flds.hasMoreElements ()) { String field = (String ) flds.nextElement (); String value = request.getParameter (field ); %>
  • <%= field %> = <%= value %>
  • <% } } %>



    ///:~

    Indienen

    Het interessantere aan dit voorbeeld is dat het laat zien hoe scriptletcode kan worden gemengd met HTML-code, zelfs op het punt waar HTML wordt gegenereerd in een Java-lus. Dit is vooral handig voor het maken van formulieren van welke aard dan ook waarvoor u anders dubbele HTML-code zou moeten invoegen.

    Kenmerken en bereik van JSP-pagina

    Als u de HTML-documentatie voor servlets en JSP's doorzoekt, vindt u een mogelijkheid die informatie rapporteert over de momenteel actieve servlet of JSP.<%-- In het volgende voorbeeld worden enkele van deze gegevens weergegeven.%> <%-- //:! c15:jsp:PaginaContext.jsp%> <%@ page import="java.util.*" %> Servletnaam:<%= config.getServletName () %>
    Servletcontainer ondersteunt servletversie:<% out.print (application.getMajorVersion () + "." + application.getMinorVersion ()); %>
    <% session.setAttribute ("My dog" , "Ralph" ); for (int scope = 1 ; scope <= 4 ; scope ++) { %>

    Domein:<%= scope %>

    <% Enumeration e = pageContext.getAttributeNamesInScope(domein); while (e.hasMoreElements()) ( out.println("\t
  • " + e.nextElement() + "
  • " ); } } %>

    ///:~

    Dit voorbeeld toont ook het gebruik van inline HTML en schrijven naar buiten om als resultaat een HTML-pagina te produceren.

    Het eerste stukje informatie levert de servletnaam op, die hoogstwaarschijnlijk gewoon "JSP" zal zijn, maar dit hangt af van uw implementatie.

    U kunt ook de huidige versie van de servletcontainer bepalen met behulp van het applicatieobject. Ten slotte worden, na het instellen van het sessieattribuut, de "attribuutnamen" weergegeven in het normale bereik. Normaal gesproken gebruikt u geen scope in de meeste JSP's; ze worden hier eenvoudigweg weergegeven om dit voorbeeld interessanter te maken.

    Er zijn drie bereikkenmerken: paginabereik (bereik 1), verzoekbereik (bereik 2), sessiebereik (bereik 3 - hier is slechts één element beschikbaar is "Mijn hond", toegevoegd vlak voor de lus) en bereiktoepassing (bereik 4) , gebaseerd op het ServletContext-object. Er is één ServletContext per "webapplicatie" op elke Java-machine. (Een "webtoepassing" is een verzameling servlets en inhoud die is geïnstalleerd onder een specifieke subset van server-URL's, zoals /catalog. Deze worden geïnstalleerd met behulp van een configuratiebestand.) In het toepassingsbereik ziet u objecten die de paden vertegenwoordigen voor de werkmap en de tijdelijke mapcatalogus.

    Sessiemanipulatie in JSP<%-- Sessies zijn geïntroduceerd in de vorige sectie over servlets en zijn ook beschikbaar in JSP. In de volgende voorbeelden worden sessieobjecten onderzocht en kunt u de tijdsduur manipuleren voordat een sessie ongeldig wordt.%>

    //:! c15:jsp:SessionObject.jsp<%= session.getId () %>

  • Sessieobjectwaarden ophalen en instellen --<%= session.getCreationTime () %>
  • Sessie-ID:<%= () %>
  • <% Deze sessie is gemaakt op(5 ); %>
  • Oud MaxInactiveInterval =<%= session.setMaxInactiveInterval() %>
  • Nieuw MaxInactiveInterval=

  • session.getMaxInactiveInterval<%= session.getAttribute ("My dog" ) %>
  • <%-- Als het sessieobject "Mijn hond" nog steeds aanwezig is, is deze waarde niet nul:%> <% session.setAttribute ("My dog" , new String ("Ralph" )); %>

    Sessiewaarde voor "Mijn hond" =<%= session.getAttribute ("My dog" ) %>

    <%-- Laten we nu het sessieobject "Mijn hond" toevoegen --%>
    < /FORM>


    ///:~

    Ongeldig maken

    Wanneer u deze sessie voor het eerst krijgt, ziet u dat het MaxInactiveInterval bijvoorbeeld 1800 seconden (30 minuten) is. Het hangt af van uw JSP/servlet-containerconfiguratie. MaxInactiveInterval wordt teruggebracht tot 5 seconden om het interessanter te maken.

    Als u de pagina opnieuw laadt voordat de 5 seconden zijn verstreken, ziet u het volgende:

    Sessiewaarde voor "Mijn hond" = Ralph

    Maar als je langer wacht, wordt "Ralph" nul.

    Om te zien hoe sessie-informatie wordt overgedragen naar andere pagina's, en om het effect te zien van het ongeldig maken van een sessieobject in vergelijking met het simpelweg laten verlopen ervan, worden twee nieuwe pagina's gemaakt. De eerste (beschikbaar door op de knop "ongeldig maken" in SessionObject.jsp te klikken) leest de sessie-informatie en maakt vervolgens de sessie expliciet ongeldig:<%-- //:! c15:jsp:SessieObject2.jsp%>

    //:! c15:jsp:SessionObject.jsp<%= session.getId () %>

    Het sessieobject wordt overgedragen --<%= session.getValue ("My dog" ) %>

    <% session.invalidate (); %>

    ///:~

    Sessiewaarde voor 'Mijn hond'

    Om hiermee te experimenteren, update je SessionObject.jsp en klik je vervolgens onmiddellijk op de knop "ongeldig maken" om naar de pagina SessionObject2.jsp te gaan. Op dit punt ziet u nog steeds "Ralph" en onmiddellijk daarna (voordat het interval van 5 seconden verstrijkt), update SessionObject2.jsp om te zien dat de sessie met succes ongeldig is gemaakt en dat "Ralph" is verdwenen.

    Als u terugkeert naar SessionObject.jsp, vernieuwt u de pagina zodat u opnieuw een interval van 5 seconden heeft en klikt u vervolgens op de knop "Keep Around". U wordt naar de volgende SessionObject3.jsp-pagina geleid, die de sessie niet ongeldig maakt:<%-- //:! c15:jsp:SessieObject3.jsp%>

    //:! c15:jsp:SessionObject.jsp<%= session.getId () %>

    Het sessieobject wordt overgedragen --<%= session.getValue ("My dog" ) %>



    ///:~

    Opbrengst

    Aangezien deze pagina de sessie niet ongeldig maakt, blijft "Ralph" aanwezig tijdens elke paginavernieuwing totdat het interval van 5 seconden tussen de vernieuwingen is verstreken. Het verschilt niet veel van het Tomagotchi-speelgoed: zolang je met Ralph speelt, zal hij daar zijn, anders zal hij verdwijnen.

    Cookies aanmaken en wijzigen

    Cookies zijn geïntroduceerd in het vorige gedeelte over servlets. Nogmaals, de beknoptheid van JSP maakt het omgaan met cookies eenvoudiger dan het gebruik van servlets. Het volgende voorbeeld laat dit zien door de cookies op te halen die in het verzoek zijn opgenomen, de maximale leeftijd (vervaldatum) te lezen en te wijzigen en de nieuwe cookie aan het antwoordverzoek te koppelen:<%-- //:! c15:jsp:Cookies.jsp%>

    //:! c15:jsp:SessionObject.jsp<%= session.getId () %>

    <% Cookie cookies = request.getCookies (); for (int i = 0 ; i < cookies.length ; i ++) { %>Dit programma gedraagt ​​zich anders in verschillende browsers! --<%= cookies [ i ]. getName () %>
    Cookienaam:<%= cookies [ i ]. getValue () %>
    waarde:<%= cookies [ i ]. getMaxAge () %>
    <% cookies [ i ]. setMaxAge (5 ); %>Maximale leeftijd in seconden:<%= cookies [ i ]. getMaxAge () %>
    <% } %> <% ! int count = 0 ; int dcount = 0 ; %> <% response.addCookie (new Cookie ("Bob" + count ++, "Dog" + dcount ++)); %>

    ///:~

    Omdat elke browser cookies anders opslaat, ziet u mogelijk verschillend gedrag in verschillende browsers (niet overtuigd, maar dit kan een bug zijn die mogelijk is opgelost tegen de tijd dat u dit leest). Mogelijk krijgt u ook andere resultaten als u uw browser afsluit en start, dan als u een andere pagina bezoekt en vervolgens terugkeert naar Cookies.jsp. Houd er rekening mee dat het gebruik van een sessieobject geschikter lijkt dan het rechtstreeks gebruiken van cookies.

    Na het weergeven van de sessie-ID wordt elke cookie in de cookies-array die bij het verzoekobject is geleverd, samen met de maximale leeftijd op de pagina weergegeven. De maximale leeftijd wordt gewijzigd en opnieuw weergegeven om de nieuwe waarde te testen, waarna de nieuwe cookie aan het antwoord wordt toegevoegd. Het is echter mogelijk dat uw browser deze maximumleeftijd negeert; Het is de moeite waard om met dit programma te spelen en de maximale leeftijdswaarde te wijzigen om het gedrag onder verschillende browsers te zien.

    Conclusie over JSP

    Dit gedeelte is slechts een kort overzicht van JSP, en zelfs met wat hier wordt behandeld (samen met wat u in de rest van het boek over Java zult leren, en samen met uw kennis van HTML), kunt u beginnen met het schrijven van ingewikkelde webpagina's met behulp van JSP. Het is niet de bedoeling dat de JSP-syntaxis mysterieus of ingewikkeld is, dus als u begrijpt wat er in deze sectie wordt gepresenteerd, bent u klaar om productief te zijn met JSP. Meer informatie kunt u vinden in de meeste beschikbare servletboeken of op java.sun.com.

    Het is vooral handig om toegang te hebben tot JSP, zelfs als uw doel alleen maar het maken van servlets is. U zult merken dat als u een vraag heeft over het gedrag van een servletfunctie, het veel gemakkelijker en sneller is om een ​​testprogramma in JSP te schrijven om het antwoord te krijgen dan om een ​​servlet te schrijven. Een deel van het gemak is dat u minder code hoeft te schrijven en gerenderde HTML kunt combineren met Java-code, maar dit voordeel wordt vooral duidelijk als u ziet dat de JSP-container alle hercompilatie en herladen van de JSP voor u afhandelt wanneer de broncode wordt geopend. veranderingen.

    Het vreselijke aan JSP is echter dat je er rekening mee moet houden dat het maken van JSP een hoger vaardigheidsniveau vereist dan simpelweg programmeren in Java of simpelweg webpagina's maken. Bovendien is het debuggen van een kapotte JSP niet zo eenvoudig als bij een Java-programma, omdat (tegenwoordig) de foutmeldingen onduidelijker zijn. Dit zou moeten veranderen naarmate ontwikkelingssystemen verbeteren, maar we zouden ook andere technologieën kunnen zien die gebaseerd zijn op Java en het web en die beter geschikt zijn voor de vaardigheden van websiteontwerpers.

    Oefeningen

    1. Maak een JSP-pagina die een reeks tekst afdrukt met behulp van de tag

      .

    2. Stel de kleur van deze tekst willekeurig in met behulp van de code die is ingesloten in de JSP-pagina. Als u geen bestaande JSP-container heeft, moet u Tomcat downloaden, installeren en uitvoeren vanaf jakarta.apache.org
    3. Wijzig de maximale leeftijdswaarde in Cookies.jsp en observeer het gedrag in verschillende browsers. Let ook op het verschil tussen het opnieuw bezoeken van een pagina en het uploaden/downloaden via de browser. Als u geen bestaande JSP-container heeft, moet u Tomcat downloaden, installeren en uitvoeren vanaf jakarta.apache.org om JSP te kunnen uitvoeren.