- temavalaszt.sql a TemaValaszt adatbázis létrehozásához szüséges dump-file - a projekt NEM tartalmazza a Struts2 használatához szükséges .jar fileokat (töröltem őket, mivel így nem tudtam volna feltölteni otthonról a projektet, a feltölthető állományok méretének korlátozása miatt...) - a szükséges csomagot le lehet tölteni az Apache hivatalos oldaláról: http://struts.apache.org/2.x/index.htm ****** URL: /temeValaszt/login.action ****** Megjegyzések (pozitívumok, illetve negatívumok, és egyéb információ): - a struts.xml konfigurációs állományban megtekinthető, hogy két action van megadva: - login: ennek kétféle eredménye lehet - success (sikeres bejelentkezés esetén a choose action kapja meg a vezérlést) - input (visszairányítás az input.jsp-re, pl. hibás bejelentkezési adatok megadásakor) - choose: ennek is kétféle eredménye lehet - input (ami a temaLista.jsp-re irányít) - error (hiba esetén visszairányítunk a login action-höz) - a login.jsp oldalon az s:form elem submit gombjának attribútum-értékeként megadott "login!verify" szintaxis jelentése: a login nevű action verify metódusa fogja kezelni az illető kérést - a jsp oldalakon szereplő szövegek erőforrás-állományból (TemValaszt.properties) vannak kinyerve. Ennek az erőforrás-állománynak az elérési útja a struts.properties állományban van beállítva ****** A projektben az osztályok elnevezésére használt névkonvenció értelemszerűen: ...BL - üzleti logikát implementáló osztály (az adatbázis-hozzáférési réteg -sajnos- itt nincs különválasztva) ...Action - Action osztály ...Bean - JavaBean - egy-egy action-höz tartozó elemek egy csomagban vannak (lehet természetesen más logikát is alkalmazni, de jó, ha van valamilyen rendszeresség) ****** JDBC: DAO -sajnos- itt nincs, viszont az alkalmazás connection pooling-ban résztvevő kapcsolatobjektumot használ, lásd a context.xml konfigurációs állományban megadottakat, melynek alapján a Tomcat létrehozza a megfelelő DataSource osztályt. (nem, mintha ez a konkrét alkalmazás különösebben ígényelné az ilyen fajta kapcsolatobjektum-készlet használatát, viszont kurzuson megbeszéltük, hogy egy komolyabb web alkalmazás esetén miért fontos.) - a kapcsolat zárása finally blokkban történik, amikor épp nincs szükség már rá ****** A temaLista.jsp oldalon meg lehet figyelni az OGNL-kifejezések használatát: - az OGNL kontextusában (Struts2-ben ez az ActionContext objektumnak felel meg) azokat az objektumokat, amelyek nem az ún. érték-veremben (value-stack) vannak (mint pl. az aktuális Action osztály) a "#" szimbólum segítségével érhetjük el: pl. #session.loggedStudent.userName (a szesszióba loggedStudent néven lementett, bejelentkezett felhasználó felhasználóneve), bár ezt az adatot történetesen a Action osztály session nevű mezőjén keresztül vagy a beállított personBean-ből is elérhettük volna... (lásd lennebb, az interceptorokról szóló leírást) - %{...} közé írjuk az OGNL kifejezést, amennyiben ki szeretnénk azt értékeltetni lásd pl.: Mivel a Struts2 elemkönyvtár set eleme kifejezést vár a value attribútum értékeként, ezért ha egyszerűen annyit írnánk, hogy value="black", akkor a kifejezés kiértékelő elkezdene keresgélni egy black nevű változót az érték-veremben (getBlack()...), így viszont egyértelmű, hogy a 'black' stringről van szó. - Az érték-verem tetején eleinte mindig az Action osztály van. Így pl. a Struts2 elemkönyvtár alábbi elemében a "list" kifejezés segítségével az Action osztály list mezőjének értékét kapjuk meg (meghívódik az Action osztály getList() metódusa). Továbbá az iterator elem ki fogja értékelni a törzsét annyiszor, ahány elem a value értékeként megadott listában van, és minden egyes iteráció alkalmával az érték-verembe helyezi (az Action osztály fölé) a lista aktuális elemét. Ezért pl. a esetén az OGNL kifejezéskiértékelő először az érték-verem tetején levő aktuális lista-elem (ami AssignmentBean típusú) getStudentName metódusát próbálja meghívni (sikeresen), ez pedig visszatéríti a megfelelő diáknevet, ha a téma már ki van választva, különben pedig üres stringet. (megj.: a fent említett, AssignmentBean-eket tartalmazó, listában szerepel az összes téma, illetve a már kiválasztott témák esetén a témát választó diák adatai is. A ChooseAction execute metódusában hívódik meg az üzleti logikát implementáló ChooseBL osztály getList() metódusa, ami feltölti ezt a listát) - esetében pl. az Action osztály (ChooseAction) getIsChosen metódusa hívódik meg ****** pl. előre definiált interceptorok használatára: - a ChooseAction, azon túl, hogy az ActionSupport osztályt terjeszti ki (amely már eleve implementál bizonyos interfészeket, még két interfészt is implementál) - SessionAware interfész: a servletConfig interceptorral működik együtt (mely benne van a choose action-höz rendelt alapértelmezett interceptor-veremben - a struts-default.xml-ben ki lehet keresni a "defaultStack" nevű interceptor-vermet). Hatására meg fog hívódni a setSession metódus, ami session néven elérhetővé teszi a szesszió hatókörbe lementett adatokat (lásd az Action osztály Map típusú "session" mezőjét) - Preparable interfész: ez a prepare interceptorral működik együtt (ez is benne van az alapértelmezett interceptorveremben). Hatására meghívódik az action osztály prepare metódusa. Ez a mi konkrét példánk esetében a szesszióból kinyeri a bejelentkezett felhasználó adatait és azt elmenti ... Ezért, amikor meghívódik az Action osztály execute (vagy más, kérést kezelő) metódusa, akkor ez az információ már hozzáférhető. Ahhoz, hogy ez a mechanizmus működjön, az is fontos, hogy az interceptorveremben a servletConfig interceptor korábban szerepeljen, mint a prepare interceptor (különben a prepare metodus nem férhetne hozzá a szesszióba lementett adatokhoz). Megfigyelhető, hogy a "defaultStack" interceptorveremben ez így is van.