treasure huntalaiba/pub/absolvire/2016...cultura iașului” am propus o abordare proprie și...

51
1 Universitatea Alexandru Ioan Cuza Iași FACULTATEA DE INFORMATICĂ LUCRARE DE LICENŢĂ Treasure hunt propusă de Adrian-Dumitru Munteanu Sesiunea: Iulie, 2016 Coordonator ştiinţific Asist. Dr. Vasile Alaiba

Upload: others

Post on 22-Feb-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

1

Universitatea Alexandru Ioan Cuza Iași

FACULTATEA DE INFORMATICĂ

LUCRARE DE LICENŢĂ

Treasure hunt

propusă de

Adrian-Dumitru Munteanu

Sesiunea: Iulie, 2016

Coordonator ştiinţific

Asist. Dr. Vasile Alaiba

Page 2: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

2

UNIVERSITATEA ALEXANDRU IOAN CUZA IAŞI

FACULTATEA DE INFORMATICĂ

Treasure hunt: aplicație web

ce promovează cultura Iașului

Adrian-Dumitru Munteanu

Sesiunea: Iulie, 2016

Coordonator ştiinţific

Asist. Dr. Vasile Alaiba

Page 3: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

3

DECLARAŢIE PRIVIND ORIGINALITATE ŞI RESPECTAREA DREPTURILOR

DE AUTOR

Prin prezenta declar că Lucrarea de licenţă cu titlul „Treasure hunt: aplicație web

ce promovează cultura Iașului” este scrisă de mine şi nu a mai fost prezentată niciodată la o

altă facultate sau instituţie de învăţământ superior din ţară sau străinătate. De asemenea,

declar că toate sursele utilizate, inclusiv cele preluate de pe Internet, sunt indicate în lucrare,

cu respectarea regulilor de evitare a plagiatului:

toate fragmentele de text reproduse exact, chiar şi în traducere proprie din altă limbă,

sunt scrise între ghilimele şi deţin referinţa precisă a sursei;

reformularea în cuvinte proprii a textelor scrise de către alţi autori deţine referinţa

precisă;

codul sursă, imaginile etc. preluate din proiecte open-source sau alte surse sunt

utilizate cu respectarea drepturilor de autor şi deţin referinţe precise;

rezumarea ideilor altor autori precizează referinţa precisă la textul original.

Iaşi, data

Absolvent Prenume Nume

_________________________

(semnătura în original)

Page 4: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

4

DECLARAŢIE DE CONSIMŢĂMÂNT

Prin prezenta declar că sunt de acord ca Lucrarea de licență cu titlul „Titlul complet al

lucrării”, codul sursă al programelor şi celelalte conţinuturi (grafice, multimedia, date de test

etc.) care însoţesc această lucrare să fie utilizate în cadrul Facultăţii de Informatică.

De asemenea, sunt de acord ca Facultatea de Informatică de la Universitatea „Alexandru Ioan

Cuza” Iași să utilizeze, modifice, reproducă şi să distribuie în scopuri necomerciale

programele-calculator, format executabil şi sursă, realizate de mine în cadrul prezentei

lucrări de licenţă.

Iaşi, data

Absolvent Prenume Nume

_________________________

(semnătura în original)

Page 5: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

5

Contents

Introducere .................................................................................................................................................7

Contribuții ...................................................................................................................................................9

1. Tehnologii folosite............................................................................................................................. 10

1.1 Java .................................................................................................................................................. 10

1.2 Spring MVC Framework ............................................................................................................... 11

1.3 Apache Tomcat ............................................................................................................................... 12

1.4 Apache Maven ................................................................................................................................ 12

1.5 ORM-ul Hibernate ............................................................................................................................ 13

1.6 JavaServer Pages (JSP).................................................................................................................. 13

1.7 jQuery .............................................................................................................................................. 14

1.8 Materialize CSS .............................................................................................................................. 14

1.9 Apache Tiles ..................................................................................................................................... 14

2. Arhitectura aplicației ....................................................................................................................... 15

2.1 Presentation Layer ......................................................................................................................... 15

2.2 Business Layer .................................................................................................................................. 16

2.3 Data Access Layer ............................................................................................................................ 16

2.4 Baza de date ..................................................................................................................................... 17

3. Implementarea aplicației ................................................................................................................. 18

3.1 web-context.xml .............................................................................................................................. 18

3.2 application-context.xml .................................................................................................................. 18

3.3 pom.xml .......................................................................................................................................... 20

3.3 Maparea unei entități cu baza de date .......................................................................................... 20

3.4 Extragerea informațiilor din baza de date ..................................................................................... 22

3.5 Relația URL - contoller .................................................................................................................... 23

3.6 Autentificarea .................................................................................................................................. 23

3.7 Trimiterea de mail-uri ...................................................................................................................... 24

3.8 Încărcarea de imagini din browser .................................................................................................. 25

3.9 Interceptarea fiecărei cereri ............................................................................................................ 27

3.10 Procesarea și compararea de imagini ........................................................................................... 28

3.11 Afișarea timpului unei știri ............................................................................................................ 32

4. Algoritmii de procesare de imagine ................................................................................................ 34

4.1 Algoritmul ASIFT .............................................................................................................................. 34

Page 6: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

6

4.2 Algoritmul SIFT ................................................................................................................................. 35

5. Strategii de îmbunatățire a performanțelor ................................................................................... 38

5.1 Memorarea locala a unor resurse. .................................................................................................. 38

5.2 Accesarea resurselor doar atunci când sunt cerute ....................................................................... 39

6. Utilizarea aplicației ........................................................................................................................... 41

6.1 Pagina de misiuni ............................................................................................................................. 41

6.2 Accesarea unei misiuni .................................................................................................................... 41

6.3 Pagina de ştiri ............................................................................................................................... 43

6.4 Clasamentul .................................................................................................................................. 44

6.5 Pagina de profil ............................................................................................................................ 44

6.6 Pagina administratorului ........................................................................................................... 45

6.7 Prietenii ......................................................................................................................................... 46

7. Directii viitoare ale aplicatiei ........................................................................................................... 47

7.1 Spring Security ................................................................................................................................. 47

7.2 Chat între utilizatori ......................................................................................................................... 48

7.3 Transformarea aplicației într-un serviciu REST............................................................................... 48

Bibliografie ................................................................................................................................................ 50

Page 7: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

7

Introducere

„Treasure hunt” este un joc pentru una sau mai multe persoane, de toate vârstele, ce

implică găsirea unor locaţii/obiecte şi combină elemente de orientare, artă şi rezolvare a

problemelor pe baza unor indicii. Acest tip de joc a apărut în anul 1956, fiind creat de

comediantul Jan Murray.

Treasure hunt a trecut la un alt nivel, în anul 2000, odată cu apariţia „Geocaching”-ului,

ce presupunea că fiecare participant să dispună de un sistem GPS, cu ajutorul căruia puteau

localiza diverse locaţii. Astfel, a apărut şi aplicaţia mobilă „Geocaching” ce afişează o hartă cu

mai multe marcaje. Utilizatorii trebuiau să găsească cutiile din locaţiile sugerate şi să îşi valideze

poziţia. Aplicaţia este în continuare populară, având peşte 1 milion de descărcări în magazinul

Google Play.

Alte evenimente dedicate acestui tip de joc au avut loc in 2012, unde s-a stabilit un record

mondial ca număr de participanți (466, divizați in 93 de echipe). Tot în acest an, eBay, a

organizat un astfel de joc, cu premii în valoare de $200.000.

Subiectul acestei lucrări îl reprezintă o aplicaţie web, ce susţine cultura oraşului Iaşi.

Motivul realizării aceasteia a fost pentru a susţine campania „Iaşi, Capitală Culturală Europeană

în 2021”. Între timp, Iașul a fost eliminat din cursă pentru acest titlu, lucru ce însă nu împiedică

dezvoltarea aplicaţiei în continuare. Spre deosebire de „Geocaching”, aplicaţia presupune

realizarea unor misiuni mai diferite, mergând pe ideea de gamification.

Gamification este un concept de integrare a mecanismelor de joc, cu scopul de a capta şi

motiva oamenii să-şi atingă ţelurile. Cele mai utilizatate mecanisme de joc sunt: punctele,

insignele, nivelele, clasamentul, provocările, etc. Conceptul a devenit foarte popular cu timpul,

fiind aplicat în site-uri precum: Linkedin, Stack Overflow, Amazon, SAP Community Network,

etc.

Misiunile pot reprezenta găsirea unui punct de interes cultural, edificiu sau răspunderea

la diverse întrebări ce vizează cultura Iaşului. Găsirea edificiului este validată atât prin locaţia

utilizatorului, dar şi prin procesarea imaginii pe care acesta trebuie să o realizeze.

Aşadar, într-un mod interactiv, aplicaţia îndeamnă utlizatorul să iasă din casă, să înveţe

cultura oraşului în care locuieşte şi este recompensat pentru aceasta. Recompensele contribuie la

ideea de gamification a jocului. Odată finalizată o misiune, jucătorul primeşte puncte de

experienţă, cu ajutorul cărora poate creşte în nivel sau rang. În acest sens este realizat şi un

clasament, sporind concurenţa şi motivaţia jucătorilor.

Page 8: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

8

Pe scurt, soluţia acestei idei, o reprezentă o aplicaţie web, realizată în Java, cu ajutorul

bibliotecii Spring MVC, menită pentru a fi utilizată atat de pe calculatorul personal, cât și de pe

telefon. Alte părţi mai interesante: procesarea imaginilor (utlizarea algoritmului ASIFT),

geolocația (suport nativ în HTML5), simularea cache-ului la nivel de server, arhitectura

aplicației, tehnologiile folosite, etc.

Page 9: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

9

Contribuții

O primă contribuție în realizarea lucrării o reprezintă etapă de cercetare în vederea

conceperii unei idei neimplementate, ce poate avea un impact în societate. Sunt de părere că un

joc, cu o idee bună, captează utilizatorul, putând să îl influenţeze într-o anumită direcție.

În realizarea lucrării de licență cu tema „Treasure hunt: aplicație web ce promovează

cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă

automatizarea jocului de Treasure Hunt, particularizandu-l pe subiecte ce vizează istoria, cultura,

arta unei comunități. Scopul lucrării îl reprezintă asimilarea informațiilor culturale ce vizează

orașul în care locuim (Iași). Consider că astfel de informații culturale se asimiliează mult mai

repede printr-un joc competitiv ce interacționează cu realitatea. Jucătorul este practic îndemnat

să se informeze despre cultura orașului în vedearea avansării în joc.

Soluția propusă (automatizarea jocului) nu se bazează pe supervizarea unor coordonatori

pentru validarea unor stagii, cum este prevăzut în jocul clasic de „Treasure Hunt”. În acest scop

am creat o aplicație web ce implementează problema de mai sus, creată folosind tehnologii open-

source, robuste.

Aplicația respectă principiile SOLID şi se bazează pe o structură modularizată,

implementată în așa fel încât adăugarea de noi funcționalități sau orice modificări aduse să nu

afecteze bună funcționare a celorlalte componente.

O parte interesantă a aplicației o reprezintă lipsa dependeței de un supervizor uman care

să valideze misiunile (duse sau nu la bun sfârșit). Validarea unei misiuni, ce presupune

identificarea unui edificiu, prezintă un subiect complex şi de mare interes. Acest lucru implică

identificarea locației jucătorului și validarea pozei pe care acesta trebuie să o realizeze.

În privinţa procesării imaginii, am ales să utilizez algoritmul ASIFT (cu anumite condiții

impuse) ce ajută în extragerea unor trăsături din imagini. Apoi s-au testat diferiţi comparatori de

trăsături pentru a identifica unul ce se potriveşte pe modele arhitecturale, precum clădirile.

O altă contribuție interesantă este redată de adoptarea unor strategii de îmbunătăţire a

performanțelor aplicaţiei. Aceste strategii implică încercarea realizării a câtor mai puţine accesări

la baza de date, precum şi procesări de imagini pe fire de execuţie separate.

Așadar, lucrarea prezintă o idee originală de joc, ce consider că poate avea un impact bun

în rândul ieşenilor. Realizarea cu succes a acesteia se bazează atât pe elemente menţionate mai

sus, cât şi pe conceptele practice şi teoretice dobândite în facultate.

Page 10: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

10

1. Tehnologii folosite

1.1 Java

Limbajul de programare Java este unul dintre cele mai populare limbaje orientate obiect,

având următoarele catacteristici:

Dinamicitate: reține cantităţi substanțiale de infomații la runtime

Simplitatea: sintaxă similară cu cea din C/C++, simplificată

Robustețea: nu permite suprascrierea memoriei prin renunțarea la pointeri, ceea

ce poate preveni coruperi de date. Nu permite moştenirea multiplă iar dealocarea

momeriei reprezintă o sarcină de care se ocupă o procedură ce rulează în fundal

(„Garbage Collector”)

Complet orientat obiect

Portabilitatea: se poate executa pe orice platformă; poate fi transferat și pe web

(appleturi)

Conceptul de pointer nu există în Java, însă se bazează pe referinţe pentru a păstra

adresele de memorie ale obiectelor. Alt concept care lipseşte este acela de destructor, fiind

introdus Garbage Collector-ul. Deși monștenirea multiplă este eliminată, programatorul poate

simula acest lucru prin moștenirea înlănțuită. Spre deosebire de multe limbaje, Java este şi

interpretat şi compilat, caracteristică ce îi redă portabilitatea. În procesul de compilare Java

prezintă doi pași mari. În primul, codul sursă este transformat în bytecode, urmând ca în al doilea

pas, masina virtuală Java (JVM) să interpreteze acest cod intermediar.

Sun Microsystems (achiziţionat ulterior de Oracle) a dezvoltat patru ediţii Java, ţintind

spre diferite medii de dezvoltare :

Java Card, pentru carduri inteligente

Java Micro Edition, pentru medii cu resurse limitate

Java Standard Edition, pentru staţiile de lucru comune

Java Enterprise Edition, pentru aplicaţiile enterprise

Page 11: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

11

Figura 1: Java-portabilitate pe diferite platforme 1

1.2 Spring MVC Framework

Biblioteca Spring MVC este una dedicate Web-ului, oferind o arhitectură Model-View-

Controller şi componente ce ajută în crearea de aplicaţii web flexibile. Şablonul MVC ajută în

separarea diferitelor aspecte ale unei aplicaţii, în timp ce menţine un cuplaj slab între aceste

elemente (nu există dependinţe puternice).

Acestă bibliotecă se bazează pe un servlet, numit DispatcherServlet, care preia toate

cererile şi răspunsurile HTTP. În diagrama de mai jos, se ilustrează cum servletul procesează o

cerere.

Figura 2: Fluxul realizat de DispatcherServlet 2

1 Sursă: http://www.slideshare.net/laxmanpuri71/java-byte-code-virtual-machine 2 Sursă: http://www.tutorialspoint.com/spring/spring_web_mvc_framework.htm

Page 12: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

12

1.3 Apache Tomcat

Apache Tomcat este un server-web și container de servleturi open-source. Acesta

implementează diverse specificații Java Enterprise Edition, precum Java Servlet, Java Servlet

Pages, WebSocket, etc. Prezintă trei componente:

Catalina – este numele containerului de servlet, a cărui funcționalitate este de a

implementa specificaţiile Sun Microsystems pentru servlet şi JSP (Java Server

Pages). Catalina este integrat în orice tip de platformă unde informațiile necesare

autentificării sunt deja create şi menținute

Coyote – Această componentă ascultă pentru conexiuni noi la server pe un port

TCP și trimite cererea către motorul Tomcat pentru a o procesa, clientul

primițând astfel un răspuns. Ca şi server web, suportă protocolul HTTP 1.1, fiind

componenta de conectare. Permie oricărui container JSP să se comporte ca un

server web.

Jasper – cunoscut și ca „Tomcat JSP Engine”, este motorul folosit de Tomcat

pentru fişierele JSP , în sensul că parsează le parsează și le compilează în cod

Java ca şi servleturi ce pot fi folosite de Catalina. Schimbările in JSP-uri sunt

detectate, și salvate automat, ajutând dezvoltatorul, întrucât serverul nu mai

trebuie restartat.

1.4 Apache Maven

Maven este un instrument pentru automatizarea build-ului, utilizat în proiecte Java.

Acesta descrie construcția unei aplicații, adresându-se totodată și asupra dependențelor

(pachetele de care are nevoie proiectul Java). Aplicația este construită pe baza unui fișier XML,

numit POM (Project Object Model), ce specifică dependențele către alte module sau componente

externe. Așadar, la build, toate bibliotecile necesare sunt preluate din cache-ul local iar în cazul

în care acestea lipsesc, sunt descăcate automat.

Spre deosebire de tehnologiile similare (Ant, Gradle), Maven introduce conceptele de

artifact, repository, ceea că ajută mult la depănare, versionare şi documentare a aplicației.

Orice proiect Maven are o structură predefinită, evidențiată mai jos:

Page 13: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

13

Figura 3: Structura unui proiect Maven

1.5 ORM-ul Hibernate

Hibernate este o bibliotecă open-source ce simplifică dezvoltarea aplicaţiilor Java care

interacţionează cu bazele de date. Acesta oferă o soluţie de mapare a unui model orientat obiect

în bazele de date clasice, fiind independent de sistemul de gestiune a bazei de date. Reprezintă o

implementare a interfeţei JPA (Java Persistence API), însemnând că poate fi integrat în orice

sistem ce suportă JPA (aplicaţii pe platformele Java SE, EE, etc).

O caracteristică enețială o reprezintă performanţă, hibernate având diverse strategii de

fetching, precum iniţializarea leneşă (un obiect este extras din baza de date, doar atunci când este

cerut).

Hibernate are de asemenea şi propriul limbaj pentru interogări, numit HQL (Hibernate

Query Language), ce permite scrierea de cod SQL utilizând obiectele Java. În plus, biblioteca

generează majoritatea codului SQL în timpul instanțierii obiectului, nu la runtime.

1.6 JavaServer Pages (JSP)

Jsp este o tehnologie ce rulează pe partea de server şi ajută în crearea dinamică de

conţinut HTML. O particularitate a acestei tehnologii este că permite inserarea de scriplet-uri

(cod Java) prin delimitatorii <%= [...] %>

Un compilator JSP este un program care parsează JSP-urile şi le transformă în servleturi

Java executabile. Randarea codului HTML la nivel de server poate reprezenta un avantaj,

Page 14: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

14

întrucât vă avea aceleaşi performațe indiferent de platforma clientului (dat fiind faptul că pe

mobil, operaţiile DOM sunt mult mai lente).

1.7 jQuery

jQuery este unul dintre cele mai populare biblioteci de JavaScript, conceput pentru a

uşura şi îmbunătăţi procese asupra arborelui DOM, cereri AJAX, animaţii, etc. Javascript este un

limbaj de programare orientat obiect bazat pe conceptul prototipurilor, rulat direct în browser.

Are rol în introducerea unor funcţionalităţi în paginile web.

Motivul alegerii jQuery se datorează faptului că scurtează substanţial atât timpul de

dezvoltare, precum şi lungimea codului JavaScript.

1.8 Materialize CSS

Materialize este o bibliotecă de CSS, ce ajută în crearea de site-uri şi aplicaţii web.

Conţine şabloane bazate pe HTML și CSS pentru tipografie, formulare, butoane navigare şi alte

elemente de interfaţă precum şi extensii opţionale JavaScript. Se bazează pe ideea de „Material

Design”, promovată de Google şi utilizată în majoritatea aplicaţiilor lor.

1.9 Apache Tiles

Apache Tiles este un „templating framework” pentru aplicaţiile Java moderne. Se

bazează pe şablonul de proiectare Composite şi ajută la dezvoltarea paginilor web. Şablonul

Composite sugerează că un grup de obiecte similare să fie tratate ca aceeaşi instanţă a unui

obiect. În cazul paginilor web, în layout (header şi footer) sunt introduse JSP-urile returnate de

Controller.

<tiles:insertAttribute name="body" />

Inserarea de JSP-uri se face prin:

<put-attribute name="body" value="/WEB-INF/views/main/register.jsp" />

Așadar, la schimbarea conținutului paginei web, header-ul si footer-ul nu vor mai fi reîncărcate.

Page 15: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

15

2. Arhitectura aplicației

Aplicația se bazează pe o arhitectură „server-side”. În modulul de server, se remarcă 3 mari

straturi:

Presentation Layer

Business Layer

Data Access Layer

Fiecare strat „ştie” foarte puţin din codul celorlalte, doar cât este suficient pentru a realiza

sarcinile necesare. De menţionat faptul că Presentation Layer nu poate comunica direct cu Data

Acces Layer (şi invers). Comunicarea se realizează strict prin Business Layer.

Figura 4: Arhitectura aplicației 3

2.1 Presentation Layer

Partea de prezentare este organizată pe baza şablonului MVC (Model-View-Controller),

unde este de mare ajutor biblioteca Spring MVC. Cererea HTTP este preluată de controller, care

la rândul său decide dacă trebuie să apeleze stratul de business. Dacă acest lucru nu este necesar,

3 Sursă: http://terasolunaorg.github.io/guideline/1.0.1.RELEASE/en/Overview/SpringMVCOverview.html

Page 16: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

16

controller-ul va returna direct un view. Însă, dacă în caz contrar, va interacţiona cu Business

Layer-ul, care la rândul său va comunica mai departe cu al treilea modul.

Toate controller-ele definite de dezvoltator, în Spring, trebuie să implementeze interfața

Controller (@Controller) sau să extindă AbstractController. Partea de model din layer nu se

referă la entităţile utilizate în DOA, ci la modelul pe care îl poate returna un controller. Acesta

este practic un „map” ce va fi ataşat unui view. În JSP-uri, acest model poate fi accesat prin

sintaxa ${cheieMap}.

2.2 Business Layer

Acest layer conţine funcţionalităţile de bază ale aplicaţiei. Practic, acest modul determină

cum informaţiile sunt create, afişate, stocate şi schimbate, primind comenzi de la Presentation

Layer şi apelând mai departe Data Access Layer.

În acest modul, regăsim clasele adnotate cu @Service, fiind un specific al framework-

ului Spring. Acest lucru indică faptul că o clasă respectă practica DDD (Domain driven design),

unde modelul rămâne încapsulat pe partea de server, fiind reprezentat doar la nivel de servicii şi

repository-uri (persistentă a datelor). Aceste servicii respectă principiul singurei responsabilități.

În cazul aplicaţiei noastre, există câte un serviciu pentru: fluxul jocului, upload-ul imginilor,

procesarea imaginilor, trimitere de mail-uri, etc. Gruparea serviciilor, în aşa fel încât să aibă

fiecare o singură responsabilitate, reduce impactul schimbărilor ulterioare, codul fiind mult mai

uşor de menţinut.

2.3 Data Access Layer

DAO: Data Acces Object este de fapt un şablon de proiectare folosit în separarea API-

urilor low-level de accesare a datelor de serviciile business high-level. În general,

şablonul este asociat cu aplicaţiile Java EE şi bazele de date relaţionare, accesate prin

JDBC, fiind specificat în ghidul de practici bune al „Sun Microsystems”. Acesta

încapsulează toate accesele la baza de date. DAO realizează managementul conexiunii cu

sursa de date pentru a obţine şi pastra informaţii. Este format din 3 componente:

interfaţa DAO (defineşte operaţiile standard ce pot fi realizate pe model),

implementarea interfeţei DAO (implementarea interfeţei de mai sus), obiectele Model

(POJO-uri, conţinând metode set şi get). Mapând apelurile aplicaţiei asupra acestui strat,

DAO oferă operații cu date specifice, însă nu expune informaţii sensibile despre baza de

date.

Avantajele folosirii acestui şablon au impact în separarea a două părţi importante ale

aplicaţiei (Baza de date - Data Access Layer) care ar trebui să se dezvolte independent,

neştiind prea multe una despre cealaltă. Aşadar, modificări asupra logicii de acces a

obiectelor se pot realiza în DAO, însă schimbări în partea de persistenţă nu ar trebui să

influenţeze clasele DAO, în cazul în care interfaţa este corect implementată.

Page 17: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

17

Figura 5 Schema DAO 4

Entitățile: reprezintă obiectele model, menţionate mai sus. Aceasta sunt evidenţiate prin

adnotarea @Entity, fiind mapate cu tabelele din baza de date prin @Table. O coloană

este mapata prin @Column, fiind de fapt un obiect Java, remarcându-se că numele

acesteia nu trebuie să coincidă cu cel al coloanei din tabel.

2.4 Baza de date

Figure 6 Schema bazei de date

4 Sursă: http://www.oracle.com/ocom/groups/public/@otn/documents/digitalasset/146804.jpg

Page 18: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

18

3. Implementarea aplicației

3.1 web-context.xml

Acest fişier conţine detaliile de configurare care ajută serverul Tomcat, oferind mai multe

informaţii (menţionate mai jos).

<beans xmlns="http://www.springframework.org/schema/beans"

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

xmlns:p="http://www.springframework.org/schema/p"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<mvc:annotation-driven />

<mvc:resources mapping="/resources/**" location="/resources/" />

<mvc:interceptors>

<bean class="interceptor.RequestInterceptor" />

</mvc:interceptors>

<bean id="viewResolver"

class="org.springframework.web.servlet.view.UrlBasedViewResolver">

<property name="viewClass"

value="org.springframework.web.servlet.view.tiles3.TilesView" />

</bean>

<bean class="org.springframework.web.servlet.view.tiles3.TilesConfigurer"

id="tilesConfigurer">

<property name="definitions">

<list>

<value>/WEB-INF/views/**/tiles-definitions.xml</value>

</list>

</property>

</bean>

</beans>

Sunt specificate unde sunt plasate resursele aplicaţiei, putand fi accesate doar din această

locaţie. Este menţionat un interceptor care filtrează toate cererile din aplicaţie, fiind utilizat

pentru controlul accesului şi nu numai. De asemenea, web-context.xml specifică (printr-un

pattern) şi locul în care se găsesc definiţiile pentru Apache Tiles.

3.2 application-context.xml

Reprezintă interfaţa centrală dintr-o aplicaţie Spring, ce conţine informaţii de configurare

a acesteia. La run-time este read-only, dar poate fi reîncărcat dacă este necesar.

ApplicationContext poate încărca java beans, la cerere le poate distribui, şi le poate lega

împreună. Prezintă interes deoarece adaugă funcţionalități specifice aplicaţiilor enterprise.

Page 19: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

19

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

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

xmlns:jee="http://www.springframework.org/schema/jee"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/jee

http://www.springframework.org/schema/jee/spring-jee-3.1.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:component-scan base-package="demo" />

<context:annotation-config />

<bean id='entityManagerFactory'

class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'>

<property name="persistenceUnitName" value="Skelet" />

<property name='dataSource' ref='dataSource' />

<property name="jpaVendorAdapter">

<bean id="jpaAdapter"

class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

<property name="databasePlatform"

value="org.hibernate.dialect.PostgreSQLDialect" />

<property name="generateDdl" value="true" />

<property name="showSql" value="true" />

<property name="format_sql" value="true"></property>

</bean>

</property>

</bean>

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">

<property name="entityManagerFactory" ref="entityManagerFactory" />

</bean>

<tx:annotation-driven transaction-manager="txManager" />

</beans>

În acest fișier este specificat:

Locul unde se găsesc toate clasesle ce conţin adnotările @Controller, @Repository,

@Service, etc (base-package="demo"). În cazul în care aceste clase sunt găsite, Spring le

va înregistra în „bean-factory”

beanul entityManagerFactory, este cel care se ocupă de proprietăţile JPA (Java

Persistence API), făcând referire la proprietatea 'dataSource'. Aceasta conţine

informaţii ce ajută la stabilirea conexiunii cu baza de date.

Beanul txManager: este menţionată clasa JpaTransactionManager care este responsabilă

de realizarea tranzacţiilor de informaţii între baza de date şi aplicaţie. Având aceste

configurări, în implementările DAO putem injecta entityManagerul:

@PersistenceContext

private EntityManager em;

Page 20: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

20

3.3 pom.xml

Project Oriented Mode reprezintă fişierul de configuraţie a bibliotecii Maven. Conține

informaţiile necesare bibliotecii să construiască un proiect. Printre elemente se numără

dependenţele proiectului, versiunea proiectului, numele dezvoltatorilor, descriera, etc.

Un astfel de fişier trebuie să conţină groupId (id-ul grupului proiectului, de regulă fiind

unic pe companie), artifactId (id-ul proiectului), version (versiunea proiectului).

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

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

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>demo</groupId>

<artifactId>demo</artifactId>

<version>1.0</version>

<packaging>war</packaging>

<name>Skelet</name>

<description>Skelet POM</description>

<repositories>

<repository>

<id>OpenIMAJ maven releases repository</id>

<url>http://maven.openimaj.org</url>

</repository>

<repository>

</repositories>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-core</artifactId>

<version>2.3.0</version>

</dependency>

În pom-ul proiectului avem specificat goupId-ul şi artifactId-ul ca fiind „demo”, cu

versiunea 1.0. De asemenea este menţionat modul de împachetare al proiectului, în acest caz

fiind war (web application archive). Elementul „repository” marchează (în acest caz) un

repository remote. Acest lucru este folositor în momentul în care Maven nu găseşte dependenţele

în repository-ul central. Cum biblioteca OpenIMAJ nu se regăsește acolo, Maven va căuta în url

precizat mai sus.

Pentru exemplu, este specificată şi o dependenţă, în cazul nostru, biblioteca Jackson

(responsabilă de conversia automată din obiecte Java în obiecte JSON). La momentul build-ului,

dacă această bibliotecă nu se găseşte în cache-ul local, Maven o va descărca şi o va injecta la

dependenţele proiectului.

3.3 Maparea unei entități cu baza de date

Acest lucru se realizează cu ajutorul bibliotecii de persistenţă Hibernate. O clasă

(entitate) va corespunde unui tabel din baza de date.

@Entity

@Table(name = "Quest")

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

Page 21: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

21

@DiscriminatorColumn(name = "type", discriminatorType =

DiscriminatorType.STRING)

@DiscriminatorValue(value = "quest")

public class Quest {

@Id

private String id;

@Column(name = "difficulty")

private String difficulty;

@Column(name = "description")

private String description;

@OneToOne

@JoinColumn(name = "hint_id")

@Cascade(CascadeType.ALL)

private Hint hint;

@Column(name = "info")

private String info;

@Column(name = "next_quest")

private String nextQuest;

@Column(name = "available")

private boolean available;

@Column(name = "date")

private Date date = new Date();

Prin adnotarea @Entity marcăm clasa „Quest” ca fiind un bean, fiind mapată de tabelul

„Quest” prin @Table (name = "Quest"). O regulă a Hibernate-ului este ca orice entitate să aibă o

cheie primară, specificată prin @Id. @Column se foloseşte pentru a face maparea dintre

proprietatea clasei şi coloanele tabelului. De menţionat faptul că numele tabelului, coloanei nu

trebuie să corespundă cu numele clasei, respectiv proprietăţii, aceste putând să difere prin

(name = „nume tabel/coloană”).

Entitatea de mai sus reprezintă un caz mai special, deoarece toate clasele care o vor

extinde, nu vor avea un tabel separat. Valorile acestora vor fi păstrate tot în acest tabel, fiind

adăugate doar noi coloane (@Inheritance (strategy = InheritanceType. SINGLE_TABLE)).

@DiscriminatorColumn va introduce o nouă coloană în tabel (nu şi o nouă variabila java), ce va

avea valoarea sugerată de @DiscrimatorValue. Aşadar, subclasele nu vor mai avea adnotarea

@Table, însă obligatoriu este să conţină valoarea discriminatorului.

@Entity @DiscriminatorValue ("localization_quest") Public class LocalizationQuest extends Quest {[..]}

Evident, vor exista coloane cu valori nule, corespunzătoare unei anumite subclase. Însă,

un avantaj semnificativ îl reprezintă faptul că la extragerea unei subclase, join-ul nu mai este

necesar pentru a obţine informaţii din superclasă.

Page 22: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

22

3.4 Extragerea informațiilor din baza de date @PersistenceContext private EntityManager em;

@Override public List<User> getAdmins() { Query query = em.createQuery("from User user where user.access='admin'"); try { return(query.getResultList()); } catch (NoResultException e) { e.printStackTrace(); } return null; }

Acesta este un fragment de cod din implentarea unui DAO, reprezentând extragerea

utilizatorilor care au accesul de admin. EntityManager este o interfaţă cu metode pentru

interacţionarea cu contextul de persistenţă. Funcţia createQuery primeşte ca parametru un String

în formal HQL (Hibernate Query Language). Diferenţa dintre SQL şi HQL este ca ultimul

menţionat face referire la obiecte Java şi nu la elemente specifice bazei de date.

Un DAO este injectat într-un serviciu/controller prin adnotarea @Autowired. Practic, în

acest fel, rolul instantierii clasei DAO este preluat de Spring şi nu de dezvoltator. O sintaxă

precum cea de mai jos este suficientă pentru a avea un bean Spring intializat. @Autowired UserDAO userDAO;

Adnotarea se bazează pe conceptul de „Dependency Injection”, fiind un şablon de

proiectare ce implementează „Inversion of Control”. O dependenţă este un obiect de cerut (în

cazul nsotru, un serviciu sau DAO). O injecţie presupune pasarea dependenţei la un obiect

dependent care ar avea nevoie de ea. Practic, în loc de a avea obiecte care creează dependenţe,

acestea sunt pasate în constructor sau printr-un set.

„’Dependency Injection’ is a 25-dollar term for a 5-cent concept. [...] Dependency injection

means giving an object its instance variables” – James Shore5.

5 Sursă: http://www.jamesshore.com/Blog/Dependency-Injection-Demystified.html

Page 23: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

23

3.5 Relația URL - contoller

Maparea dintre controller și url se realizează astfel:

@Controller

@RequestMapping(value = "/account")

public class AccountController {

@RequestMapping(value="/userProfile", method = RequestMethod.GET)

public String displayUserProfile( @RequestParam String id){

[...]}

}

Această metodă mapează adrese de genul: „/account/userProfile? Id= [idUser]”. În cazul

în care nu există o mapare pentru URL-ul tastat în browser, utilizatorul va fi direcţionat pe o

pagină 404, fiindui specificat că pagina căutată nu există. Prinderea erorii HTTP 404 se realizeză

prin codul de mai jos (din web.xml), fiind făcută redirectarea către o pagină proprie.

<error-page>

<error-code>404</error-code>

<location>/WEB-INF/views/error/404.jsp</location>

</error-page>

3.6 Autentificarea

Utlizatorul are posibilitatea să se autentifice printr-un formular clasic, dar mai interesantă

este cea prin reţelele sociale (Facebook, Twitter, Google+). Acest lucru se realizează cu ajutorul

servleturilor. Un servlet este o clasă Java care extinde capabilităţile unui server. Acesta preia de

regulă cereri http, putând şi să răspundă la ele. Este practic, o componentă web, deploy-ată pe

server cu scopul de a crea pagini web dinamice.

În primul rând avem un buton ce apelează servletul:

<form action="facebookLogin" method="post"> <button name="subject" type="submit" class="myButton facebookButton"> <img src="http://techulus.com/buttons/fb.png" /> </button> </form>

Acțiunea „facebookLogin” este asociată unui servlet in web.xml, astfel:

<servlet> <servlet-name>FBLoginServlet</servlet-name> <servlet-class>facebook.login.domain.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FBLoginServlet</servlet-name> <url-pattern>/facebookLogin</url-pattern> </servlet-mapping>

Mai sus este declarat servletul „FbLoginServlet”, mapat cu clasa

facebook.login.domain.LoginServlet, având ca acţiune „/facebookLogin”. Odată apăsat butonul

de autentificare, acţiunea se mută în metoda doGet a servletului. În acest moment se apelează un

serviciu oferit de biblioteca OAuth ce securizează tranzacţia de informaţii dintre serverul

Page 24: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

24

aplicaţiei şi serverele Facebook. Dacă utlizatorul acceptă să ofere informaţiile personale,

aplicaţia va dispune de numele, email-ul, id-ul şi poza de profil ale acestuia. După efectuarea

tranzacţiei, dacă id-ul utilizatorului nu se regăseşte în baza de date, acesta este salvat, trimiţându-

se şi un mail de bun venit.

3.7 Trimiterea de mail-uri

Spring contribuie cu un API de nivel înalt pentru simplificarea procesului de trimis

mailuri. Este Bazat pe JavaMail(un API independent de platformă și protocol ce ajută în

construirea de mail-uri).

Figura 7 Diagrama JavaMail 6

Pentru a trimite mesaje, este folosită clasa JavaMailSenderImpl. Aceasta necesită

urmatoarea declarație in application-context.xml:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="smtp.gmail.com" /> <property name="port" value="587" /> <property name="protocol" value="smtp" /> <property name="username" value="[email protected]" /> <property name="password" value=" iasi.treasureHunt " /> <property name="javaMailProperties"> <props> <prop key="mail.smtp.auth">true</prop> <prop key="mail.smtp.starttls.enable">true</prop>

6 Sursă: http://www.codejava.net/frameworks/spring/sending-e-mail-with-spring-mvc

Page 25: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

25

<prop key="mail.smtp.quitwait">false</prop> </props> </property> </bean>

În acest sens, s-a creat un serviciu care se ocupă de email-uri (mesaj de bun venit, mesaj

de resetare a parolei).

@Service public class MailService {

@Autowired JavaMailSender mailSender;

public void sendHelloEmail(String to, String firstname) { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom("[email protected]"); message.setTo(to); message.setSubject("Bine ai venit"); message.setText("Salutare "+firstname+"\n\n Ne bucuram ca te-ai inregistrat!" ); mailSender.send(message); }

În această clasă putem injecta JavaMailSender-ul prin adnotarea @Autowired, trimiterea

mesajului realizându-se foarte uşor prin mailSender. Send (message). La rândul său, serviciul

MailService, va fi injectat în controller. Astfel, se realizează separarea dintre Business Layer şi

Presentation Layer.

3.8 Încărcarea de imagini din browser

Încărcarea se poate realiza atât din varianta desktop (file picker), cât şi din varianta

mobilă (cu ajutorul camerei). Acest lucru este implementat în următorul cod HTML:

<input type="file" name="image" id="file_uploader" accept="image/*; capture=camera"/>

Atributul „accept” specifică tipul de fişiere care pot fi acceptate la upload. Pentru a se

realiza transferul care server, este necesară o secvenţă de cod JavaScript:

function sendFileToServer(e){

file = e.target.files[0]; […] url=”/demo/upload/photo/user”; if (checkFile(file)){ data = new FormData(); data.append("image",file);

jQuery.ajax({ url: url, data: data, cache: false, contentType: false, processData: false, type: 'POST',

complete: function(data){}

})

}

}

Page 26: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

26

Odată selectată imaginea, funcţia de mai sus este apelată. Este extrasă imaginea din

e.target.files[0] urmând să fie validată. Funcţia checkFile() verifică dacă dimensiunea imaginii

nu depăşeşte 5Mb şi dacă aceasta are într-adevăr o extensie corespunzătoare unei imaginii. În

cazul în care condiţiile sunt îndeplinite, se realizează o cerere Ajax care url-ul specificat.

AJAX (Asynchronous JavaScript and XML) reprezintă o nouă modalitate de a folosi

împreună tehnologii precum (X) HTML, CSS, JavaScript, DOM, XML, XSLT,

XMLHttpRequest, prin intermediul căreia aplicaţiile web devin capabile să realizeze actualizări

mai rapide de interfaţă, fără încărcarea întreagă a paginii.

Cererea ajax din codul de mai sus va apela o metodă din controller-ul responsabil de

încărcarea de imagini. Salvarea imaginii se realizează prin : imageService.saveImage(), a cărei

implementare este urmatoarea:

public void saveImage(String fileName,MultipartFile image, String type){ String photoPath; switch (type) { case "forUser": photoPath = DIRECTORY_PATH + fileName + "." + getImageExtension(image); break; case "forQuest": photoPath = QUEST_DIRECTORY_PATH + fileName + "." + getImageExtension(image); break; default: photoPath = HINT_DIRECTORY_PATH + fileName + "." + getImageExtension(image); File file = new File(photoPath); try { image.transferTo(file); } catch (IOException e) { e.printStackTrace(); } }

După cum se poate observa, imaginea nu este păstrată în baza de date că tip BLOB, ci

este păstrată pe o partiţie a maşinii server. După ce imaginea a fost salvată, obiectului căruia îi

este asignată imaginea (un utilizator, o misiunea sau un hint), îi este setată proprietate

„photoUrl” după modelul: „/demo/upload/getPhoto/tip/id”. Astfel putem face referire la imagini

după cum este arătat mai jos:

<img src="${user.photoUrl}" alt="profile image"/>

În momentul construirii dinamice a codului HTML, pentru a afișa imaginea de mai sus,

se va face apel la urmatoarea metoda:

@RequestMapping(value = "/getPhoto/{type}/{fileName}/{extension}", method = RequestMethod.GET) @ResponseBody public byte[] sendProfilePhoto(@PathVariable String type, @PathVariable String fileName, @PathVariable String extension) { ImageService imageService = new ImageService(); String path; switch (type) { case "user": path = ImageService.DIRECTORY_PATH + fileName + "." + extension; break; case "quest": path = ImageService.QUEST_DIRECTORY_PATH + fileName + "." + extension; break;

Page 27: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

27

default: //hint path = ImageService.HINT_DIRECTORY_PATH + fileName + "." + extension; break; } return imageService.getImageFromPath(path); }

Calculând calea adevarată a imaginii, se va face apelul la funcția getImageFromPath() ce

va citi imaginea într-un flux de bytes și o va returna.

Concluzii

S-a ales salvarea imaginilor ca path-uri în baza de date din următoarele motive:

stocarea în baza de date este de obicei mai costisitoare

serverul nu are nevoie de procedee speciale pentru a accesa imaginile din sistem (funcţia

getImageFromPath)

bazele de date au spaţiu de stocare limitat.

Desigur, şi a doua variantă de stocare ar fi avut avantajele ei, precum păstrarea integrităţii

datelor, ceea ce sistemul de fişiere nu garantează. Însă cumulând avantajele şi dezavantejele,

stocarea în sitemul de fişiere a fost soluţia aleasă.

3.9 Interceptarea fiecărei cereri

Acest lucru se realizează extinzând clasa HandlerInterceptorAdapter din pachetul

org.springframework.web.servlet.handler. O parte restrănsă din metodă este prezentă mai jos.

@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(request.getRequestURI()); if(request.getRequestURI().contains("/demo/account/") || request.getRequestURI().contains("/demo/game") || request.getRequestURI().contains("/demo/log")) if(!request.getRequestURI().contains("findEmail")){ User u = (User) request.getSession().getAttribute("user"); if(u == null ){ response.sendRedirect("/demo/"); return false; } }

return true;

}

Extinzând metoda preHandle() putem realiza o anumită acţiune inante ca browser-ul să

primească răspunsul. În cazul nostru, cu această tehnică realizăm controlul accesului. Cum

utilizatorul logat se află în sesiune, dacă atributul „user” este null atunci cererea spre o anumită

resursă/pagină va sfârşi prin redirectarea spre pagina de logare. În caz contrar, utilizatorul va

acces la resursa dorită.

Page 28: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

28

De menţionat faptul că pentru a fi recunoscut acest interceptor, trebuie declarat în web-

context.xml

<mvc:interceptors> <bean class="interceptor.RequestInterceptor" /> </mvc:interceptors>

3.10 Procesarea și compararea de imagini

Procesarea unei imagini se realizează prin intermediul algoritmului ASIFT, din cadrul

bibliotecii OpenIMAJ, a cărei funcţionalitate este explicată în unul din capitolele de mai jos.

Întreaga parte de procesare este în sarcina serviciului ImageProcessorService. O primă

funcţionalitate este cea de transforma imaginea din format MultiPartFile în format Fimage.

public static FImage multipartToFImage(MultipartFile multipartFile){

try {

return ImageUtilities.readF(ImageProcessor

.multipartToFile(multipartFile));

} catch (IOException e) {

e.printStackTrace();

return null;

}

}

Foarte important, înainte de a extrage trăsăturile unei imagini, aceasta trebuie redimensionată,

pentru a nu pune jucatorul să aștepte foarte mult procesarea propriei imagini. S-a remarcat faptul că

algoritmul dă rezultate bune și la rezoluții de 400x600. Astfel, în implementare se află minimul dintre

înalțimea si lățimea imaginii, după care se setează pe 400 pixeli, păstrând proporțiile imaginii.

După care urmează extragerea trăsăturilor. Implementarea standard a algoritmului ASIFT

în OpenIMAJ se regăseşte în clasa ASIFTEngine, fiind instanțiată mai jos în obiectul engine.

public static LocalFeatureList<Keypoint> extractFeatures(FImage image){

LocalFeatureList<Keypoint> inputFeats = engine.findKeypoints(image);

System.out.println("Extracted : " + inputFeats.size());

return inputFeats;

}

Trăsăturile sunt păstrate într-o structură de date (LocalFeatureList<Keypoint>), fiind de

fapt o listă de puncte cheie extrase din imagine. Acestea sunt procesate în momentul în care

administratorul adaugă o nouă misiune şi sunt stocate la nivel de server, fiind serializate la

închiderea acestuia. În momentul în care administratorul introduce o misiune de localizare, un

nou fir de execuție porneşte, având ca sarcină extragerea trăsăturilor imaginii. Când utilizatorul

realizează o imagine pentru a rezolva misiunea, trăsăturile sunt extrase, apoi comparate cu cele

de pe server cu scopul de a valida misiunea.

Ultima funcţionalitate a serviciului o reprezintă compararea a două imagini. Aflarea mai

precisă a potrivirilor presupune filtrarea acestora, bazată pe un model geometric dat. Un mod de

a reuşi acest lucru reprezintă utilizarea clasei ConsistentLocalFeatureMatcher, care primeşte un

„matcher” intern (FastBasicKeypointMatcher în cazul nostru) şi un estimator

(RobustAffineTransformEstimator). Estimatorul se potriveşte pe un anumit model geometric

(transformările afine7). Numărul de potriviri este dat de metoda findMatches ().

7 Model ce păstrează colinearitatea și ponderea distanțelor la diferite transformări http://mathworld.wolfram.com/AffineTransformation.html

Page 29: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

29

public static int getMatches(LocalFeatureList<Keypoint> firstFeats,

LocalFeatureList<Keypoint> secondFeats){

LocalFeatureMatcher<Keypoint> matcher;

RobustAffineTransformEstimator modelFitter = new

RobustAffineTransformEstimator(5.0, 1500,

new RANSAC.PercentageInliersStoppingCondition(0.5));

matcher = new ConsistentLocalFeatureMatcher2d<Keypoint>(

new FastBasicKeypointMatcher<Keypoint>(8), modelFitter);

matcher.setModelFeatures(firstFeats);

matcher.findMatches(secondFeats);

final List<Pair<Keypoint>> matches = matcher.getMatches();

System.out.println("Matches found: " + matches.size());

return matches.size();

}

După mai multe teste se remarcă faptul că RobustHomographyEstimator întoarce

rezultate mai bune decât RobustAffineTransformEstimator. Primul menţionat face referire la

„planar homographies”8, ce sunt mai generale ca transformările afine, mapând patrulatere la

patrulatere. Totuşi, codul suferă schimbări minore:

RobustHomographyEstimator modelFitter2 = new RobustHomographyEstimator(5.0,

1500, new RANSAC.PercentageInliersStoppingCondition(0.5),

HomographyRefinement.SYMMETRIC_TRANSFER);

Unde SYMMETRIC_TRANSFER semnifică faptul că punctele din prima imagine sunt

proiectate de o „homography matrix” pentru a produce noi estimări ale celei de a două imagini şi

viceversa.

Teste:

Palatul Culturii

Figura 8 RobustAffineTransformEstimator, 7 potriviri

8 http://www.cse.psu.edu/~rtc12/CSE486/lecture16.pdf

Page 30: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

30

Figura 9 RobustHomographyEstimator, 52 potriviri

Casa Dosoftei

Figura 10 RobustAffineTransformEstimator, 12 potriviri

Figura 11 RobustHomographyEstimator, 75 potriviri

Page 31: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

31

Imagini cu obiective diferite

Figura 12 RobustAffineTransformEstimator, 9 potriviri

Figura 13 RobustHomographyEstimator, 0 potriviri

Concluzii

procesarea unei imagini prin algoritmul ASIFT este una costisitoare, atât ca timp,

dar şi ca memorie, motiv pentru care toate imaginile sunt redimensionate. Pentru

o imagine de 400x600 pixeli o astfel de procesare durează în jur de 10 secunde.

potrivirile extrase nu sunt întotdeauna perfecte. Pot exista cazuri în care nu se

găsesc potriviri, deşi imaginile conţin acelaşi obiectiv. Un astfel de caz este

reprezentat de efectul puternic de relief, spre exemplu:

Page 32: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

32

Figura 14 0 potriviri, indiferent de estimator

estimatorul afin, produce în medie mai puţine potriviri, acestea putând fi şi

eronate în cazul imaginilor ce conţin obiecte total diferite, cum este evidenţiat în

ultimul test.

3.11 Afișarea timpului unei știri

În pagina de newsfeed, este vizibil timpul trecut din momentul apariţiei unei ştiri. Acest

lucru se realizează cu ajutorul bibliotecii open-source numită Timeago9, al cărei autor este Ryan

McGeary. Interesant în implementare este faptul că biblioteca poate primi ca parametru chiar

java.util.Date, astfel:

<time class="timeago" datetime="${newsfeed.endDate}"></time> .

La momentul încărcării codului HTML, este apelată biblioteca cu următorul cod

JavaScript:

jQuery(document).ready(function() {

jQuery("time.timeago").timeago();

});

9 Biblioteca Timeago: http://timeago.yarp.com/

Page 33: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

33

Extinderea bibliotecii Timeago pentru a returna timpul calculat, cu termeni în limba

romană, este urmatoarea:

strings: {

prefixAgo: "Acum",

prefixFromNow: null,

suffixAgo: null,

suffixFromNow: null,

inPast: 'Orice moment',

seconds: "",

minute: "1 min",

minutes: "%d min",

hour: "1 ora",

hours: "%d ore",

day: "1 zi",

days: "%d zile",

month: "1 luna",

months: "%d luni",

year: "1 an",

years: "%d ani",

wordSeparator: " ",

numbers: []

}

Page 34: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

34

4. Algoritmii de procesare de imagine

4.1 Algoritmul ASIFT

Acronimul provine de la Affine Scale-Invariant Feature Transform, ASIFT fiind practic o

îmbunătăţire a algoritmului SIFT, care va fi detaliat mai jos.

Problemă: Conţin imaginile acelaşi obiect?

Soluţie: DA, deşi pozele sunt realizate din unghiuri diferite

Figura 15 ASIFT - Potrivirile găsite

Utlizand acest algoritm, este posibilă recunoaşterea obiectelor solide într-o imagine digitală,

indiferent de unghi, distanţă, atât timp cât rezoluția permite acest lucru. Dacă un obiect fizic are

margini netede, imaginea realizată de orice cameră digitală din diferite poziţii va prezenta aceste

margini tot netede, dar deformate. Aceste deformaţii sunt aproximate de transformările afine.

Algoritmul simulează imaginea iniţială, obţinută prin modificarea orientării camerei, simulare ce

nu este tratată de algoritmul SIFT, apoi aplică SIFT.

Un algoritm de potrivire a imaginilor afine invariante trebuie să acopere cei 6 parametri afini.

Metoda SIFT tratează doar 4 dintre aceştia, normalizând rotaţiile, translaţiile şi simulând zoom-

urile.

Page 35: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

35

Figura 16 ASIFT - privire de ansamblu 10

După cum este ilustrat în imagine, ASIFT completează SIFT, simulând doi parametri care

modelează axa de direcţie a unei camere foto: scala și unghiurile de latitudine şi longitudine ale

camerei, normalizând translaţia şi rotaţia.

Paşii algoritmului:

imaginea este transformată prin simularea tuturor distorsionărilor afine cauzate de

modificiarea axei de orientare a camerei. Distorsionările depind de longitudine (φ) şi

latitudine (θ).

distorsionările sunt apoi rotite la unghiul φ, urmate de înclinări cu parametrul

t = 1/| cos θ|. Aceste rotaţii şi înclinări sunt realizate pentru un număr mic, finit de

unghiuri de latitudine şi longitudine.

toate imaginile simulate sunt comparate de SIFT

4.2 Algoritmul SIFT

Acest algoritm prezintă 2 mari stagii:

Detecţia punctelor de interes

Generarea descriptorilor

Pentru a explica ce reprezintă un punct de interes vom folosi un exemplu: Este dată poza unei

uşi. Aceasta are 4 colţuri, fiind de asemenea şi punctele de interes ale imaginii. Apoi imaginea

este rotită, fiind alterată şi dimensiunea acesteia. Imaginea iniţială poate fi comparată cu cea

modificată prin aceste 4 puncte, deoarece la scalare/rotaţie punctele nu se schimbă; uşa tot va

avea 4 colţuri. Aşadar, pe acestea le numim puncte de interes.

10 Sursă: http://www.ipol.im/pub/art/2011/my-asift/

Page 36: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

36

Figura 17 SIFT - puncte de interes 11

În pasul următor, se filtrează punctele de interes, fiind eliminate muchiile sau

zonele cu contrast scăzut. Apoi se asignează fiecărui punct o orientare. Acest lucru,

practic, anulează orice efect de orientare al imaginii, făcând-o invariantă la rotaţii.

Figura 18 SIFT - puncte de interes cu orientare 12

11 Sursă: http://www.cc.gatech.edu/~hays/compvision/results/proj2/jting8/index.html 12 Sursă: http://www.codeproject.com/Articles/619039/Bag-of-Features-Descriptor-on-SIFT-Features-with-O

Page 37: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

37

Pentru generarea punctelor de interes sift, numite şi descriptori, algoritmul calculează

gradientul imaginii. Apoi va forma histograme ale orientărilor. Aceste histograme măsoară

puterea gradientului în fiecare direcţie. Formând mai multe histograme şi concatenandu-le se

obţine o histogramă (Histograma gradienților orientați13) finală ce va reprezenta descriptorii

(utilizaţi în găsirea similarităţilor dintre două imagini).

Figura 19 Puncte de interes, gradienți, descriptori 14

13 https://en.wikipedia.org/wiki/Histogram_of_oriented_gradients 14 Sursă: http://www.codeproject.com/Articles/619039/Bag-of-Features-Descriptor-on-SIFT-Features-with-O

Page 38: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

38

5. Strategii de îmbunatățire a performanțelor

Adoptând unele tehnici de îmbunătățire a performanţelor, s-a ajuns ca unele pagini să se

încarce şi de două ori mai rapid.

5.1 Memorarea locala a unor resurse.

Încărcarea paginilor depinde foarte mult de timpul de execuţie a metodei din controller,

corespunzătoare unei rute. S-a remarcat faptul că accesul multiplu la baza de date generează

timpi suplimentari de execuţie. Aşadar, o soluţie găsită este de a simula cache-ul la nivel de

server.

În serviciul CachedData avem stocaţi toţi utilizatorii şi misiunile deoarece aceste resurse au

fost cele mai acesate din baza de date.

@Service

public class CachedDataImpl implements CachedData {

private Map<String, User> users ;

private Map<String, Quest> quests ;

Pe lângă setteri şi getteri, această clasă conţine metode utilitare, ce ajută în realizarea

operaţiilor CRUD15 pe resursele stocate.

CachedData poate fi injectată în controller, accesul la resurse realizându-se mult mai rapid

după cum arată şi următorul caz de test:

Accesul la resurse doar prin baza de date:

@RequestMapping("/test1")

@ResponseBody

public double test1(){

double start, finish;

start = System.currentTimeMillis();

List<User> users = cachedData.getUsers();

List<Quest> quests = cachedData.getQuests();

questDAO.getQuest("213edba8-ac55-40f5-b9c7-c1d292096fab");

questDAO.getQuest("06f8e1c4-af2b-4d03-ab12-b43565b21c4a");

userDAO.findUser("1");

userDAO.findUser("2");

finish = System.currentTimeMillis();

return finish - start;

}

Rezultat (in functie de strategia de performanta pe care o adopta

calculatorul pe care serverul ruleaza)

o 360ms in medie (putere scazuta)

o 140ms in medie (putere mare)

Accesul la resurse prin datele stocate pe server.

15 Create, Read, Update, Delete

Page 39: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

39

@RequestMapping("/test2")

@ResponseBody

public double test2(){

double start, finish;

start = System.currentTimeMillis();

List<User> users = cachedData.getUsers();

List<Quest> quests = cachedData.getQuests();

cachedData.getQuest("213edba8-ac55-40f5-b9c7-c1d292096fab");

cachedData.getQuest("06f8e1c4-af2b-4d03-ab12-b43565b21c4a");

cachedData.getUser("1");

cachedData.getUser("2");

finish = System.currentTimeMillis();

return finish - start;

} Rezultat:

o 0ms (putere scazuta)

o 0ms (putere mare)

Desigur, pagina nu se va incărca instant nici prin a doua metoda, acest lucru fiind dependent

și resursele CSS, JS și viteza de internet a utilizatorului.

5.2 Accesarea resurselor doar atunci când sunt cerute

După cum s-a mai menționat, JSP-uri pot primi din controller un model la care are acces prin

${numeModel}.

Se evită accesarea resurselor şi popularea modelului cu informaţii pe care clientul nu le

observă la încărcarea paginii, accesul acestora fiind făcut ulterior, dacă este cerut.

Spre exemplu, în pagina de profil, utilizatorul poate vedea relaţia cu ceilalţi jucători

Figura 20 Relatia dintre jucatori

Page 40: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

40

Dacă acesta nu este interesat de cine îl urmăreşte, nu se va mai realiza o interogare inutilă

pe bază de date. În schimb, dacă doreşte să vadă, în momentul apăsării pe fila „Urmărit de”, se

efectuează următorul apel Ajax:

function showFollowers() {

if (notLoaded) {

notLoaded = false;

$.ajax({

url : "/demo/account/getFollowers?userId=" + userId

})

.then(

function(data) {

for (index in data) {

user = data[index];

$('#followers').append(

'<div class="row"><a id="navbarImg"

href="/demo/account/userProfile?id='

+ user.id + '" ><img class="circle responsive-img small" '+

'src=" '+ user.photoUrl +'" /> '

+ user.firstName + " " + user.lastName + ' </div>')

}

})

}

}

„notLoaded” este o variabilă care indică dacă interogarea de mai sus a mai fost realizată sau

nu. În caz afirmativ, cererea Ajax nu mai este făcută. În secvenţa „for”, este populat elementul

HTML cu id-ul „followers”.

Executând metoda de mai sus, se ajunge la urmatorul rezultat:

Figura 21 Exemplu de resurse cerute prin AJAX

Page 41: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

41

6. Utilizarea aplicației

6.1 Pagina de misiuni

Odată logat, utilizatorul (indiferent de gradul de acces) poate vedea pagina de misiuni.

Aceste misiuni sunt sortate pe 3 categori:

misiuni noi: cele proaspăt adăugate de administratori, pe care utilizatorul încă nu

le-a accesat.

misiuni începute: cele care au fost accesate în trecut.

misiuni terminate: cele pentru care s-a oferit deja un răspuns, fie el corect sau nu.

Figure 22 Pagina de misiuni

6.2 Accesarea unei misiuni

Misiunile sunt împărţite pe doua categorii: cele de localizare a unui edificiu şi întrebările

de cultură generală. Mai jos este pagina de accesare a unei misiuni de localizare. Aceasta

prezintă informaţii specifice, precum dificultatea, descrierea şi indicaţii de realizare a pozei. De

asemenea, în partea dreaptă este afişat numărul de hint-uri disponibile. Un hint poate fi folosit

dacă misiunea are unul asignat.

Page 42: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

42

Figura 23 Misiunea de localizare

În momentul realizării pozei, locaţia utilizatorului este preluată şi comparată cu cea a

edificiului. Dacă distanţa este mai mică de 50 metri (se ia în calcul şi eroarea localizării), atunci

se trece la pasul ce vizează procesarea imaginii. Pentru ca procesarea să nu dureze exagerat de

mult imaginea este redimensionată (minimului dintre înălţime şi lăţime i se atribuie valoarea de

400 pixeli, păstrând proporţiile dintre cele două dimensiuni). Având trăsăturile imaginii din baza

de date încărcate în memoria serverului, acestea sunt comparate cu cele extrase din poza realizată

de jucător. Dacă numărul de potriviri depăşeşte 20, înseamnă ca jucătorul a finalizat cu succes

misiunea. Ambele sunt acoperite mai jos.

Figura 24 Rezultatul terminării unei misiuni

De asemenea următoarea imagine prezintă o întrebare de cultură generală, cu informaţii

aferente acesteia.

Page 43: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

43

Figura 25 Intrebare de cultură generală

Realizarea unei misiuni este recompensată cu puncte de experienţă în funcţie de

dificultatea acesteia. Acumularea de puncte experienţă conduce la creşterea în nivel şi în rank.

Jucătorul beneficiază de un hint în plus la fiecare creştere de nivel.

6.3 Pagina de ştiri

În această pagină utlizatorul poate regăsi informaţii ce au legătură cu jucătorii pe care îi

urmăreşte. Informaţiile au scop motivaţional, acestea făcând referire la terminarea unei misiuni,

creşterea în nivel, rank, etc.

Figura 26 Pagina de știri

Page 44: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

44

6.4 Clasamentul

În clasament se regăsesc utlizatorii sortaţi în ordinea rankului, nivelului şi a punctelor de

experienţă. Pagina reprezintă unul din punctele cheie al conceptului de gamification.

Figura 27 Pagina de clasament

6.5 Pagina de profil

Pagina de profil afişează toate informaţiile asociate unui cont. Aici, jucătorul poate

observa cine îl urmăreşte şi pe cine urmăreşte el, având posibilitatea şi să îşi editeze profilul.

Figura 28 Pagina de profil

Page 45: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

45

6.6 Pagina administratorului

Această pagină presupune accesul autorizat. Prezintă ceilalți administratori, utilizatorii şi

misiunile, administratorul autentificat, având posibilitatea să modifice aceste date. De asemenea,

tot din această pagină se pot adauga misiunile.

Trebuie menţionat faptul că datele afişate sunt paginate. Cererea de date corespunzătoare

unei pagini se realizează printr-un apel AJAX către server, acesta returnând o listă de obiecte.

Orice ştergere din listă va actualiza automat pagina, fără a o mai încarca din nou. Înainte de

efectuarea unei ștergeri, administratorul este nevoit să își confirme acțiunea printr-o fereastra

modală.

Figura 29 Pagina administratorului

Un caz mai interesant îl reprezintă adăugarea misiunii de localizare. Aceasta specifică

posibilitatea încărcării unei imagini, setarea descrierii/dificultăţii/informaţiilor adiţionale, precum

şi alegerea coordonatelor. În momentul poziţionării unui marcaj pe hartă, automat sunt extrase

latitudinea şi longitudinea. Infomaţiile adiţionale sunt afişate jucatorului după ce acesta a

terminat cu succes misiunea. Acestea au fost introduse din scop pur informativ, pentru a oferi

detalii despre locaţia identificată.

Page 46: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

46

Figura 30 Adăugarea unei misiuni de localizare

6.7 Prietenii

În pagina dedicată acestui subiect, jucătorul poate vedea toţi prietenii săi (persoanele pe

care le urmăreşte), împreună cu detalii aferente progresului lor (rangul, nivelul şi punctele de

experiență). De asemenea este disponibilă căutarea de utilizatori noi. Aceasta beneficiază de

autocompletare. Căutarea se realizează pentru minim 2 caractere, având totodată şi o intârziere,

pentru a nu face cereri inutile către server.

Page 47: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

47

Figure 31 Pagina prietenilor

7. Directii viitoare ale aplicatiei

7.1 Spring Security

În momentul de faţă, controlul accesului se realizează prin rutare, fiecare cerere fiind

verificată de un interceptor (a se vedea capitolul 3.8). O altă soluţie ar fi utilizarea pachetului

Security din cadrul bibliotecii Spring. Aceasta asigură autentificarea şi autorizarea în aplicaţiile

Java. Puterea acestei biblioteci constă în uşurinţa cu care poate fi extinsă pentru a satisface

cerinţe particulare.

Avantajele ar fi:

ușurința cu care se realizează controlul accesului. Spre exemplu:

@PreAuthorize("hasRole('ROLE_ADMIN')")

public void deleteUser(String username);

vine cu pachete pentru criptarea parolei precum (Md5PasswordEncoder,

BaseDigestPasswordEncoder, etc)

are suport pentru controlul accesului chiar şi în JSP-uri

<%@ taglib prefix="sec"

uri="http://www.springframework.org/security/tags" %>

<sec:authorize access="hasRole('ROLE_ADMIN')">

Acest mesaj va fi vizibil doar pentru admini.

</sec:authorize>

Page 48: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

48

poate expirma condiţia ca autentificarea să se realizeze doar prin HTTPS astfel în fişierul

de configurare

<http auto-config="true" use-expressions="true">

<intercept-url pattern="/login" requires-channel="https"/>

<!-- Other attributes and elements omitted -->

</https>

7.2 Chat între utilizatori

Dat fiind faptul că utilizatorii primesc ştiri (news feed) de la prietenii lor, o

funcţionalitate bună de adăugat ar fi aceea de a da posibilitatea jucătorilor să comunice live.

Acest lucru se poate realiza prin intermediul Web Socket-urilor.

Websocket-urile sunt o tehnologie modernă ce face posibilă comunicarea interactivă între

browser şi server, utilizând o singură conexiune TCP. Cu acest API se pot trimite mesaje la

server şi primi răspunsuri fără a fi aşteptate sau cerute.

Desigur, pentru a păstra mesajele, este nevoie de un model pentru baza de date. Cel de

mai jos este inspirat din structura Facebook-ului de stocare de mesaje:

Figura 32 Model de stocare a mesajelor

7.3 Transformarea aplicației într-un serviciu REST

Într-o arhiterctura REST, totul reprezintă resurse. O astfel de arhitectură ajută foarte mult

în minimizarea cuplajului dintre client şi componentele serverului.

Trecerea pe o arhitectură REST implică schimbări majore, însă ar aduce avantaje

notabile, precum posibilitatea utlizarii aceluiaşi server pe diferite tipuri de clienţi (browser,

Page 49: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

49

aplicaţii mobile). Deoarece JSP-uri nu pot fi folosite în aplicaţii pure REST, o sugestie pentru a

realiza clientul de tip browser ar fi utilizarea bibliotecii AngularJS. Aceasta, folosită de regulă în

dezvoltarea aplicaţiilor web cu o singură pagină, se bazează pe o arhitectură MVC şi MVVM

(Model View-View Model). Avantajele ar fi ca AngularJS extinde HTML-ul, oferă suport pentru

legarea de date („data-binding”), permite testare la nivel enterprise, etc.

O altă direcţie a clientului o reprezintă aplicaţiile native pe diferite platforme (Android,

iOS, windows). Acestea pot profita de avantajele oferite de sistemul de operare, precum diferiţi

senzori, performanţă ridicată, etc. Spre exemplu, intr-o aplicație Android, aplicație ar rula mai

fluent decât in browser, localizarea s-ar face mai eficient, procesarea imaginilor s-ar putea realiza

direct pe client pentru a evita suprasolicitarea serverului, etc.

Page 50: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

50

Concluzii

Aplicația descrisă în această lucrare propune o altă abordare a jocului de

Treasure Hunt, una automatizată, cu orientare spre obiective culturale. Consider că

este foarte important ca un ieșean să cunoască istoria și cultura propriului oraș, așa

că am decis dezvoltarea unei aplicații ce îmbină utlilul (asimilarea de noi

cunoștințe) cu plăcutul (jocul propriu-zis).

Jucătorul poate afla noi informații prin intermediul misiunilor disponibile.

Am considerat că terminarea acestor misiuni nu reprezintă o sursă de motivație

suficientă, așa că am adoptat conceptul de gamification. Practic, orice reușită este

recompensată cu puncte de experiență. Se poate spune că jucătorii sunt într-o

oarecare competiție, fiind realizat un clasament în acest sens. O problemă pe care

am ridicat-o (în misiunile de localizare) a fost necesitatea deplasării jucatorului la

edificiul sugerat. Acest lucru se bazează pe faptul că am observat cum tot mai

multă lume preferă să-și petreacă mare parte din timp izolați, în fața calculatorului

din casă. Pe lângă acest lucru, sunt de părere ca vizionarea pozei unui edificiu nu

este la fel de memorabilă precum analizarea acestuia „la fața locului”. În acest

scop, misiunile pot fi extinse pentru a realiza chiar un tur de prezentare al orașului.

În implementarea aplicației m-am orientat spre tehnologii robuste, de

actualitate. Așadar am decis dezvoltarea unei aplicații web în limbajul Java, cu

ajutorul bibliotecii Spring MVC. Am preferat o aplicație web deorece este

independentă de platforma clientului, fiind necesar doar un browser. S-au adoptat

diferite strategii de îmbunătățire a timpului de încarcare a paginii precum

solicitarea deasă a memoriei Heap16, procesarea asincronă a imaginilor, etc.

Așadar, subiectul acestei lucrări prezintă o idee nouă, ce consider ca poate

avea un impact bun în randul ieșenilor. Aplicația (ce poate avea și caracter turistic)

îndeamnă utilizatorul să iasă din casă și să se distreze în timp ce învață cultura

orașului.

16 heap – spațiul de stocare al obiectelor Java

Page 51: Treasure huntalaiba/pub/absolvire/2016...cultura Iașului” am propus o abordare proprie și originală a realizării unui joc. Ideea reprezintă automatizarea jocului de Treasure

51

Bibliografie

[1] Craig, Walls. Spring in Action. Manning, 2014.

[2] Pivotal Software. Spring Framework -

https://spring.io/docs

[3] Cameron McKenzie. Hibernate made easy. PulpJava, 2008.

[4] Apache Software Foundation. Maven -

http://maven.apache.org/guides

[5] Apache Software Foundation. Tomcat -

https://tomcat.apache.org/tomcat-7.0-doc/index.html

[6] Materialize CSS -

http://materializecss.com/about.html

[7] jQuery - http://api.jquery.com/

[8] Cristian, Frăsinaru. Curs practic de Java

http://web.info.uvt.ro/~iordan/P_III/Cristian_Frasinaru-Curs_practic_de_Java.pdf

[9] Guoshen Yu, Jean-Michel Morel. ASIFT: An algorithm for Fully Affine Invariant Comparison

http://www.ipol.im/pub/art/2011/my-asift/article_lr.pdf

[10] Brian, Burke. Gamify: How Gamification Motivates People to Do Extraordinary Things. Hardcover,

2014.

[11]Robert, Martin. Clean Code: A Handbook of Agile Software Craftmanship. Prentice Hall, 2009.

[12] StackOverflow – http://stackoverflow.com/