9. gyakorlat¶
Java Server Pages (JSP)¶
A JSP technológia csakúgy, mint a Servletek azért hivatottak, hogy a webes alkalmazásokat készíthessünk. Gondoljunk rájuk úgy, mint a szervleteket kiegészítő technológiára. A JSP ténylegesen maga is egy Servlet, a Servletből származik. Minden funkciót, amit a servletek kapcsán tanultunk itt is használni tudunk. A JSP oldalakra tekintsünk úgy, mint egyszerű HTML oldalakra, azonban azok dinamikus voltát az biztosítja, hogy beágyazhatunk beléjük Java kódot, mellyel a tartalmat generálhatjuk (dinamikussá tehetjük). Az előző órán látottak alapján mindenki azt mondhatja, hogy a komplex HTML válasz előállítása a servleten belül nem csak hogy macerás, de magas hibahajlammal bír.
A JSP oldalak megértését nagyban segíti az alábbi ábra áttanulmányozása:
Az egyik kulcslépés a JSP-k servletekké alakítása. Ezt az átalakítást az alkalmazás szerver végzi el. Ezután a megszokott folyamat zajlik.
A JSP oldalak, HTML-szerűen tagekkel írhatóak le, de benne Java kódot is írhatunk. Hozzunk létre egy új Maven webapp-os projektet, ahogy azt a szervleteknél is tettük és adjuk, hozzá a dependency-khez a servlet-api-t. Ezután a generált projekt index.jsp oldalán a következő kódot írjuk be, majd indítsunk el a Tomcat Servert (beállítás ugyanaz, mint a servleteknél):
1 2 3 4 5 |
|
Ez a 10-es eredményt írja ki. Később megnézzük, hogy pontosan mi történik.
A JSP oldalakat a projektünkön belül a webapp mappába kell helyezni, de fontos, hogy ne a WEB-INF
mappába rakjuk, mert az zárt az alkalmazásszerveren belül, azokat a fájlokat a kliens nem éri el direkt módon (web.xml-ben kell ilyen esetben megadni).
Jobb klikk webapp -> New -> JSP/JSPX Page -> JSP Page
Tipp
A JSP oldalakat használjuk megjelenítésre, a controller logikát szervezzük Servletekbe!
Amint azt láttuk a servleteket az alkalmazásszerverünk Servlet konténere menedzseli. A JSP oldalakat a JSP konténer kezeli. JSP fejlesztés során ajánlott a maven dependency-k közé felvenni a következőt:
1 2 3 4 5 |
|
Feladat
Adjunk hozzá egy új JSP oldalt a projektünkhöz és az első oldalra helyezzünk el egy linket, ami átvisz a másik oldalra!
Megoldás
index.jsp:
1 2 3 4 5 6 |
|
second.jsp:
1 2 3 4 5 6 7 8 9 |
|
A second.jsp
-ben található első sort az IntelliJ generálja. Később megismerkedünk ezekkel az elemekkel is.
JSP életciklusok¶
A JSP oldalak az alábbi életciklussal rendelkeznek. Egy részüket már láthattuk korábban:
- Transzformálás: A JSP oldalak szervletté alakítása. Pl.:
index.jsp
->index_jsp.java
- Fordítás: A legenerált szervleteket lefordítjuk, amennyiben az átalakítás sikeres volt
- Osztálybetöltés: Memóriába töltés
- Példányosítás: A JSP konténer létrehoz egy példányt a JSP oldalból (már szervletként gondolhatunk rá)
- Inicializálás: ServletConfig és ServletContext elérhetővé válik az oldal számára
- Kérés feldolgozás: Minden kérést külön szálon szolgálnak ki a JSP oldalak is, mint ahogyan a szervleteknél is
- Megsemmisítés: Hasonlóan, mint a szervleteknél a JSP oldalak is megsemmisülnek életük végén (pl.: szerver leállítás)
Életciklus metódusok¶
Ahogy a szervleteknél is jelen voltak az életciklusokat támogató metódusok (init, service, destroy), itt is megtalálhatóak:
- jspInit(): a JspPage interface-ben van megadva
- _jspService(HttpServletRequest request, HttpServletResponse response): HttpJspPage interface tartalmazza
- jspDestroy(): a JspPage interface-ben van megadva
A JspPage
és a HttpJspPage
interfészeket nem kell megadnunk direktben, ezeket az interface-eket automatikusan implementálja minden JSP oldal.
Ezeket a metódusokat a JSP oldalon belül tudjuk felüldefiniálni, amennyiben az szükséges (általában nem az) a declaration tag-ek használatával (lásd lentebb).
JSP scripting¶
A JSP oldalakon belül használhatunk úgynevezett scripting tageket (<%...%>
).
Ezeken belül java kódokat és kifejezéseket adhatunk meg.
3 típusát különböztetjük meg:
- scriptlet tag:
<% java source code %>
- expression tag:
<%= expresison %>
- declaration tag:
<%! declaration %>
Példa egy paraméter kiírására:
index.html
1 2 3 4 5 6 7 8 |
|
welcome.jsp
1 2 3 4 5 6 7 8 |
|
Ez kiírja az index.html form-jában megadott felhasználói nevet a JSP oldalon.
Vegyük észre az out.print
sort, melyben kérdezhetnénk, hogy miért nincs a System
az out eléírva.
A JSP oldalakon használható néhány előre definiált, úgynevezett implicit objektum, mint például az out
, melynek típusa JspWriter
, működését tekintve pedig a servletekben használt PrintWriter
-hez hasonlít.
Egy másik implicit objektum is szerepel, mégpedig a request
.
Ez a HttpServletRequest
objektumunkat jelöli és automatikusan megkapja a JSP oldal.
A scriptletek mindig java utasításokat tartalmaznak, így az utasítások végére pontosvesszőt kell írnunk!
A servletekben HTML kódot írtunk Java kódba, most pedig HTML-be írunk Java-t. Nem úgy tűnik, hogy sokkal jobb volna a JSP... Valóban a scriptletek eléggé el tudják csúfítani a JSP oldalak forráskódját, ezért is találták ki az Expression Language technológiát, melyet a későbbiekben tárgyalunk.
A JSP tartalmára tekinthetünk, úgy mintha a service metódusban lennénk és ott írnánk ki a HTML-es tartalmat (végső soron tényleg ez történik).
A scriptlet-ként írt kód, így ebbe a metódusba kerül, melynek következményeként a scriptletben nem definiálhatunk metódusokat vagy adattagokat.
Erre ad megoldást a declaration tag (ez <%! ... %>
), mivel az ezek közé a tag-ek közé írt kódot a service() metóduson kívülre generálja az alkalmazás szerver JSP translator motorja.
Példa.
1 2 3 4 5 6 7 8 9 10 11 |
|
A 3. tag az expression tag, melybe írt kód a response output stream-jére íródik. Nem kell out.print-et írni! Főként változók vagy metódushívások értékének kiírására használható.
Példa:
1 2 3 4 5 |
|
Implicit-objektumok¶
A JSP oldalakon implicit objektumokat is kapunk, melyet a web konténer inicializál.
Ezek közül már láttuk is az out
és a request
implicit objektumokat, melyek rendre a servlet-nél látott PrintWriter
-hez hasonló (JspWriter
típusú) output stream írója, illetve a HttpServletRequest
objektumunk.
A következő implicit objektumok közül válogathatunk (zárójelben a típusukat láthatjuk):
- application (
ServletContext
) - config (
ServletConfig
) - jspContext (
JspContext
) - out (
JspWriter
) - page (
Object
) - pageContext (
PageContext
) - request (
HttpServletRequest
) - response (
HttpServletResponse
) - session (
HttpSession
) - exception (
Throwable
)
A fenti implicit objektumokat a scriptletekben bárhol használhatjuk, mivel az olyan, mintha a _jspService()
metódusban írnánk kódot.
Ezt továbbgondolva, adódik, hogy ezeket az implicit objektumokat nem használhatjuk a declaration tag-ek között, mivel az magához a servlet osztályhoz fog tartozni (adattagokat és metódusokat definiálhatok).
Most nézzük meg a fontosabb implicit objektumokat részletesebben!
Request implicit objektum¶
A request implicit objektumot a szervlet service(HttpServletRequest req, ...)
metódusában paraméterként megkapott request
objektummal azonosítható (ténylegesen ugyanaz az objektum), típusa HttpServletRequest
.
Funkcionalitását tekintve is megegyezik a servletekben megismert request
objektummal, attribútumokat állíthatunk be, kérhetünk le, ugyanígy a paramétereket is elérhetjük.
Response implicit objektum¶
A response implicit objektumot a szervlet service(..., HttpServletResponse resp)
metódusában paraméterként megkapott response objektummal azonosítható, típusa HttpServletResponse
.
Hasonlóan használható mint a szervleteknél.
Példa jsp oldalon belüli redirect-re:
1 2 3 |
|
Config implicit objektum¶
Amennyiben a jsp oldalunknak szeretnénk init paramétereket beállítani, akkor azt nem tudjuk megtenni olyan annotációs formában, csak a web.xml-ben. Nézzünk egy példát, hogy hogyan lehet JSP oldalakat megadni a web.xml-ben!
index.jsp
1 2 3 4 5 |
|
web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
A JSP oldalon kiírjuk a web.xml-ben megadott name
init paraméter értékét.
A web.xml-es megadás arra is megfelelő, hogy elrejtsük az url-ből, hogy jsp oldalakkal játszunk a háttérben.
Mivel a JSP oldalak servletekké alakulnak a háttérben, ezért a web.xml-ben is ugyanúgy adjuk meg őket, mint ahogyan az a hagyományos servleteknél történt, viszont vegyük észre, hogy itt megadjuk a jsp-file
elemet is, melyben megadjuk azt, hogy itt egy jsp fájlról van szó.
Application implicit objektum¶
Hasonlóan a ServletConfig
objektumhoz, a ServletContext-hez is hozzáférhetünk implicit objektum formájában.
A ServletContext
objektumnak megfelelő implicit objektum az application
.
Példa context param kiolvasására:
web.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
welcome.jsp:
1 2 3 4 |
|
Session implicit objektum¶
A request-től elkérhető HttpSession
típusú objektum megfelelője.
Példa session használatára.
index.html
1 2 3 4 5 6 7 8 |
|
welcome.jsp:
1 2 3 4 5 6 7 8 9 |
|
session.getAttribute("user")
hívással kérhetjük le.
Mivel a session-kezelés eléggé költséges, így ha nincs rá szükség, akkor megmondhatjuk a JSP oldalnak, hogy ne készítsen session objektumot az adott oldalhoz.
A session például felesleges lehet a login oldalon.
Ehhez a <%@ page session="false" %>
kódrészletet illesszük az oldal tetejére.
A pontos viselkedést később tisztázzuk a direktíváknál.
pageContext implicit objektum¶
A pageContext objektum a javax.servlet.jsp.PageContext
osztály egy példánya, melyen keresztül elérhetőek a különböző scope-okban lévő attribútumok (session scope, request scope, application scope).
A pageContext-en keresztül a többi implicit objektumot is el tudjuk érni.
Példa:
1 2 3 4 5 6 7 8 9 10 |
|
A pageContext implicit objektumot ritkábban használjuk, mivel helyette használhatjuk az implicit objektumokat közvetlenül.
Feladat
Készítsünk JSP oldalt, melyen egy gomb megnyomásakor egy számláló értékét növeljük eggyel! A számlálót nem kell kell külön szervletben növelni. Csináljunk mindent egyetlen JSP oldalon!
Megoldás
index.jsp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
A form-on belül a gombnak a name
attribútumát fontos submit-re állítani, mert a request paraméterei között ilyen néven fogjuk elérni azt. Az eredmény az, hogy csak akkor növeljük a counter értékét, ha a postban megtalálható volt a submit paraméter (bármi is legyen az értéke).
Feladat
Készítsünk egy form-ot, melyen bekérjük a felhasználó adatait: név, email, születési év! A form megnyomásakor kerüljünk át egy másik jsp oldalra, ahol kiírjuk ezeket a paramétereket, de előtte a kapott értékeket (ha vannak) beletesszük a session-be. A kiírás is a session-ből történjen!
Megoldás
index.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
details.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
JSP direktívák¶
A direktívák az alkalmazásszervernek szóló üzenetek, melyekkel megmondhatjuk, hogy a JSP oldalt milyen módon alakítsa szervletté a konténer, illetve módosítani tudjuk, hogy milyen képességű szervletünk keletkezik a transzformálás után. 3 típusa van:
- page direktíva
- include direktíva
- taglib direktíva
Ezek szintaxisa
<%@ directive attribute="value" %>
, ahol a directive
maga a page
, include
, vagy taglib
.
page direktíva¶
Az egész oldalra vonatkozó attribútumok megadására szolgál.
Egy page
direktívához megadhatóak attribútumok, melyeket egy vagy akár több page
direktívában helyezhetünk el a hatás ugyanaz.
Használata:
<%@ page attribute="value" %>
Nézzük milyen attribútumokkal találkozhatunk a leggyakrabban.
import: Hasonlóan a java-s import-hoz itt is pontosan egy java osztályt húzhatunk be vele.
Példa:
1 2 3 4 5 6 |
|
Date
osztályt, ameddig nem húztuk be.
contentType: Ahogyan a servleteknél a response.setContentType("text/html")
beállította a response mime típusát, itt ezt a következőképpen tehetjük meg.
1 2 3 4 5 6 7 8 |
|
errorPage: Ebben az attribútumban megadhatjuk, hogy amennyiben az oldalunk egy hibát dob, akkor azt melyik hibaoldal kezelje le. Itt bármilyen URI-t megadhatunk.
isErrorPage: Ezt akkor adjuk meg, amikor az adott jsp oldal egy hibakezelő oldal.
Az implicit objektumok között szerepelt az exception
, amiről nem beszéltünk még.
Ez az implicit objektum csak az olyan oldalakon érhető el, melyeknél az isErrorPage
attribútumot igazra állítottuk.
session: Ahogy azt korábban már láttuk a session objektum létrehozását tilthatjuk le. Alapértelmezetten engedélyezve van.
include direktíva¶
Az include direktíva segítségével behúzhatjuk más erőforrások (jsp, hmtl, text fájlok) tartalmát.
Igen hasznos lehet akkor, amikor az oldalainkat logikailag fel akarjuk osztani pl: header, main, footer részekre.
Az include
-ot a következő formában használjuk:
<%@ include file="test.jsp" %>
ahol a test.jsp egy relatív útvonalmegadás az aktuális jsp oldalhoz képest.
Például egy header behúzása:
1 2 3 4 5 6 7 |
|
taglib direktíva¶
A taglib direktíva tag library-k behúzására alkalmazható, melyek custom tag-eket tartalmaznak.
Később majd látjuk, hogy hogyan csinálhatunk saját tageket.
Pl.: a <%= java.util.Calendar.getInstance().getTime() %>
scriptlet helyett, csinálhatunk egy saját <currentTime>
tag-et, mely kiírja az aktuális időt és ilyen módon nem "koszolja" össze a forráskódot.
Expression Language¶
Az Expression Language vagy röviden EL, egy olyan bővítés, mely sokkal egyszerűbbé teszi az objektumokkal való munkát, mint például a request, application, response, stb. Mint korábban láttuk, nem igazán jó, hogy a JSP-ben alapvetően HTML kód van, mely teli van tűzdelve Java kódokkal. Az Expression Language ebben is segít.
Szintaxisa:
${ expression }
Az ilyen kifejezéseket a JSP oldalon belül akárhol használhatjuk.
Ahogy a scriptletekben is rendelkezünk implicit objektumokkal, így az Expression Language-ben is elérjük ezeket.
Implicit objektumok listája:
- pageScope (csak az ezen oldalhoz tárolt attribútumok map-je)
- requestScope (a request-ben tárolt attribútumok map-je)
- sessionScope (a session-ben tárolt attribútumok map-je)
- applicationScope (a ServletContext-ben tárolt attribútumok map-je)
- param (request paraméterek lekérdezéséhez)
- paramValues (a request paraméterek listája)
- header (a kérés header-je)
- headerValues (az összes request header lekérdezése)
- cookie (cookie-k lekérdezéséhez)
- initParam (a context init paraméterek lekérdezéséhez, amit a web.xml-ben adtunk meg, servlet init paramhoz nem használható)
Figyelem
A fenti implicit objektumokat ne keverjük össze a JSP implicit objektumokkal!
Az Expression Language igazi ereje abban van, hogy nem kell folyamatosan váltanunk HTML és java code között.
Vegyük a következő példát:
index.html
1 2 3 4 5 6 7 8 |
|
welcome.jsp:
1 2 3 4 5 6 7 8 |
|
Expression Language használatával a welcome.jsp a következőképpen is írható:
1 2 3 4 5 |
|
Az EL-el írt kód sokkal rövidebb, sokkal tisztább, könnyebben érthető, így mindenképpen ajánlatos a használata.
Segítség!!! Nem működik az EL!
Ennek több oka lehet. A legvalószínűbb az, hogy a web.xml rosszul van megírva. Mivel a 2.4-es servlet specifikációtól kezdődően támogatott az EL, így a Maven által generált webapp nem igazán jó, mivel abban 2.3-as DTD specifikáció van megadva, ami igencsak helytelen.
1 2 3 4 5 6 7 8 |
|
A legegyszerűbb megoldás, hogy a <!DOCTYPE ...
megadást kitöröljük.
EL operátorok¶
A legtöbb EL implicit objektum egy map amiből értékeket kérdezhetünk le. Erre használható a property access operátor (.), amivel a mapből lekérhetjük a megfelelő értéket. Például:
${requestScope.person.name}
Ez lekéri a requestScope-ban definiált person attribútumot, melynek aztán lekéri a name attribútumát. A person itt már nem egy map, hanem egy Bean objektum. Az ilyen Bean objektumokon is használhatjuk a property access operátort. A Bean alatt az általunk már megismert Bean-eket értjük (publikus konstruktor, getter/setter, szerializálható). Fontos, hogy Bean-en és java.util.Map objektumokon használhatjuk ezt az operátort.
A következő fontos operátor a collection access operátor. Tömbök vagy listák elemeihez kapunk hozzáférést a használatukkal. Példák:
${myList[1]} // a myList lista 1 elemét adja vissza
${myList[“1”]} // nem csak számmal, hanem string-el is megadhatjuk az indexet
${myMap[expr]} // ha az index nem string akkor a paraméter EL kifejezésként kiértékelődik
${myMap[myList[1]]} // akár többszörösen is egymásba lehet ágyazni
Az EL kifejezéseken belül használhatjuk a további megszokott egyszerű operátorokat is:
- aritmetikai operátorok (
+
,-
,*
,/
,%
) - logikai operátorok (
&&
,||
,!
) - relációs operátorok (
<
,>
,==
,!=
,<=
,>=
)
Fontos
Fontos észben tartani a következőket, amikor EL-t használunk:
- Az EL kifejezések mindig a következő formában szerepelnek:
${...}
- Egy oldalon a EL feldolgozást letilthatjuk a
<%@ page isELIgnored="true" %>
page direktíva használatával - Az EL segítségével lekérdezhetünk attribútumokat, header-öket, cookie-kat, viszont nem állíthatunk be értéket
- Az EL implicit objektumai különböznek a JSP implicit objektumaitól, kivéve a pageContext
- Az EL NULL-barát: nem dobál exception, ha nincs meg valamilyen attribútum
JSP action tag-ek¶
A jsp action tag-ek halmaza sokat segíthet, hogy ne kelljen átváltani java kódra, helyette jsp-t írhatunk továbbra is. Itt csak a legfontosabbakat action tag-eket mutatjuk be.
jsp:useBean¶
Akkor használjuk, ha egy Java Bean-t le szeretnénk kérni egy adott scope-ból, vagy egy új objektumot létrehozni egy adott scope-ban. Példa:
1 |
|
Ebben az esetben a JSP konténer megkeresi a person nevű bejegyzést a session-ben.
Amennyiben ilyet nem talál, akkor létrehoz egy új Person objektumot és person néven be is állítja azt a session-ben.
Miután definiáltuk a Bean-t a JSP oldalon, onnantól kezdve lekérhetjük a property-jeit egy másik jsp action tag-gel, melyet getProperty
-nek hívnak:
1 |
|
Ezt viszont nem igazán szoktuk használni, mivel már ismerjük az EL képességeit, tehát a fenti megfelelője:
1 |
|
A get mellett van egy setProperty jsp action tag, amit viszont már sokkal inkább használunk, mivel az EL segítségével nem tudunk értékeket beállítani.
1 |
|
Ha a name property-t csak akkor akarjuk beállítani, ha új objektumot kellett létrehozni (azaz nem volt még benne a sessionben), akkor a setProperty-t a useBean tag gyerekeként adjuk meg!
1 2 3 |
|
Néhány tudnivaló:
- Amennyiben a useBean-ek nem adunk meg scope-ot akkor a
page
az alapértelmezett. - Ha a request paraméterek alapján akarom beállítani a property-t, akkor a setProperty
param
attribútumában adhatom meg, hogy milyen nevű request paraméter értékét akarom a bean-nek odaadni. Ha a property neve megegyezik a request paraméter nevével, akkor elhagyhatom a param attribútumot. - Amennyiben a bean összes property-jét be akarom állítani és azok neve rendre megegyezik a request paraméterek neveivel, akkor írhatom a következőt:
<jsp:setProperty name="person" property="*" />
jsp:forward¶
A szervleteknél megismert RequestDispatcher forward
metódusa helyett használható.
Az alábbi kódrészletek ekvivalensek:
1 |
|
Ugyanez a servlet doGet, doPost, stb metódusokban:
1 2 |
|
jsp:include¶
A szervleteknél megismert RequestDispatcher include
metódusával megegyező.
Az alábbi kódrészletek ekvivalensek:
1 |
|
Ugyanez a servlet doGet, doPost, stb metódusokban:
1 2 |
|
Egy fontos különbség azonban van: include direktíva használatakor az include a transzformáláskor történik (azaz része lesz a lefordított servlet-nek), míg jelen esetben futási időben.
Ez azt jelenti, hogy abban az esetben ha erősen dinamikus JSP oldalunk van, akkor az include direktíva csődöt mondhat, így ilyenkor érdemes lehet a jsp:include
-ot használni.
JSTL¶
A JSTL (JSP Standard Tag Library) egy adag egyedi tag-et ad a kezünkbe, melyekkel sokkal könnyebb a fejlesztés, illetve az EL mellett, a JSTL használatával is sokkal szebb kódot írhatunk a JSP oldalban, anélkül, hogy váltanunk kéne scriptlet-re. A JSTL szolgáltat néhány bejárással és elágazással kapcsolatos tag-et. A JSTL-ben több csoport található meg, de mi csak a core library-t fogjuk használni. Ennek használatához először a pom.xml-be fel kell vennünk a következő dependency-t:
1 2 3 4 5 |
|
Majd azon az oldalon, ahol használni szeretnénk a jstl-t ott a következőt kell, beillesztenünk.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
c:out¶
A c:out hasonlít a <%= ... %>
expression scriptlet-hez, viszont itt EL-el használhatjuk.
Példa:
1 2 3 4 5 6 |
|
A fenti kód a session-ből kiszedné a beállított user bean objektumot, melynek a kiírja a name fieldjét.
c:import¶
Hasonló a <jsp:include>
action tag-hez, viszont képes külső url-ekről is behúzni a tartalmat.
c:set¶
A <c:set>
változók beállítására használható, melynek megadhatjuk a scope-ot is (requestScope, sessionScope, applicationScope).
Példa:
1 |
|
Fontos, hogy a scope megadásánál nem kell megadni a teljes implicit objektumot, azaz nem sessionScope-ot írunk, hanem szimplán session-t.
c:remove¶
A c:set
ellenkezője, eltávolíthatunk a megadott scope-ból változókat.
Fő a takarítás magunk után, ha már nincs szükségünk valamire.
c:if¶
A válaszba feltételesen helyezhetünk el tartalmat.
Példa:
1 2 3 |
|
A fenti példában csak akkor írjuk ki a jövedelmet, ha az nagyobb mint 8000.
c:choose¶
A Java-s switch megfelelője.
Példa:
1 2 3 4 5 6 7 8 9 10 11 |
|
A case ágaknak megfeleltethető a when, illetve a default ágnak az otherwise.
c:forEach¶
Iterációhoz használható a c:forEach tag, melyben index alapú, illetve a tényleges foreach iteráció is megadható.
Példa:
1 2 3 |
|
Egy másik példa során, ha adott mondjuk a sessionben egy List1
2
3
<c:forEach items="${sessionScope.texts}" var="text">
<c:out value="${text}"/>
</c:forEach>
c:redirect¶
A szervleteknél látott response.sendRedirect("welcome.jsp")
mintájára használható, de megint csak nem kell átváltanunk scriptlet-be.
Az url-ben megadható külső erőforrás is.
Feladatok¶
Feladat
Készítsünk egy képek feltöltésére alkalmas JSP alkalmazást, mely Base64-be alakítja át a képet!
Megoldás
index.jsp:
1 2 3 4 5 6 7 8 9 10 11 |
|
ImageUpload.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
Fontos, hogy a form-ban megadjuk, hogy multipart data-t küldünk majd.
A szervletben a MultipartConfig
annotációban jelezhetjük, hogy mekkora mennyiségű adatot hajlandó fogadni a szervletünk.
Ezután az adatrészeket a request-től a getParts()
-al kérhetjük le, és minden part-tól elkérhetünk egy InputStream-et.
Mivel nekünk a kép egyben kell, ezért ezeket a Streameket össze kell fűznünk.
Erre alkalmas a SequenceInputStream
, melynek van egy konstruktora, mely EnumerationVector
-ba összegyűjtjük az InputStreameket, melyre az elements()
hívás pontosan egy ilyen enumeration-t ad vissza.
Ebből a SequenceInputStream
-ből már kinyerhetjük a byte tömböt, melyet aztán a Base64 encoderrel tudunk kódolni String-gé.
A kinyert String-et lementhetjük akár adatbázisba is. Most csak kiírjuk a konzolra. Teszteléskor használhatunk egy online decodert, hogy visszanyerjük az eredeti képet. Pl.: https://codebeautify.org/base64-to-image-converter
Feladat
Készítsük el a contacts
projektünket JSP oldalak és servletek használatával!
Első körben elegendő a listázást és a hozzáadást implementálni.
Megoldás
A megoldást lásd a pub-on!