Programmazione Java Avanzata Accesso ai Dati Ing. Giuseppe D'Aquì
Testi Consigliati Eclipse In Action Core J2EE Patterns - DAO [http://java.sun.com/blueprints/corej2eepatterns/patterns/dataaccessobject.html] JDBC API Documentation [http://download.oracle.com/javase/6/docs/technotes/guides/jdbc/]
Accesso ai dati Ogni applicazione ha bisogno di un sottosistema che si occupi di salvare le informazioni Per motivi di integrità e di gestione, le informazioni non possono stare tutte in RAM In genere si utilizzano dei meccanismi che rendono trasparente allo sviluppatore il modo con cui lo stato interno degli oggetti viene salvato Si parla quindi di Persistenza degli oggetti e di Persistence Layer
Accesso ai dati Le modalità di storage, però, variano in modo ampio Database Relazionali Database Non-relazionali (document-based / NoSQL) Database Object-Oriented Flat Files Servizi Vari (LDAP) Inoltre l'implementazione dei singoli accessi può avere le sue complessità
Accesso ai dati Ogni API infatti può essere implementata in modi diversi e avere modalità di accesso differenti Inoltre i dati potrebbero non essere presenti fisicamente sulla macchina Per questo nasce la necessità di usare API universali che astraggano questa complessità
CRUD Ogni sistema di persistenza deve fornire almeno quattro funzionalità: Create Read Update Delete
JDBC Java DataBase Connectivity È una API che definisce l'accesso ad un database Fornisce metodi per effettuare query ed aggiornare i dati JDBC è orientato ai database relazionali Le classi JDBC sono contenute nel package java.sql and javax.sql
JDBC JDBC è una API universale per i Relational DBMS Il linguaggio di interrogazione è SQL...ma come ben sappiamo spesso ogni produttore di DBMS aggiunge le sue estensioni ad SQL, rendendolo incompatibile
JDBC JDBC si compone di due parti: API: l'interfaccia con cui lo sviluppatore accede alle funzionalità Driver: in genere scritto dal produttore del DBMS; lo sviluppatore difficilmente conoscerà il suo funzionamento
JDBC
JDBC Classi fondamentali: DriverManager Connection Statement PreparedStatement ResultSet
JDBC: DriverManager DriverManager si occupa di fornire la connessione più adatta ad un DBMS La connessione, infatti, viene creata specificando una stringa detta URL DriverManager astrae la gestione del singolo driver
JDBC: DriverManager Ogni JDBC Driver, alla prima inizializzazione, si registra presso DriverManager Chiamando getconnection(), DriverManager cerca tra tutti i driver registrati quello che soddisfa la url specificata Url JDBC: jdbc:<driver>:<host_url> jdbc:mysql://localhost:3306/mydb jdbc:microsoft:sqlserver://localhost;databasename=my db;user=youruser;password=yourpwd
JDBC: Connection Connection gestisce una connessione al database Permette di creare due tipi di statement: Statement: normale query, da eseguire una volta PreparedStatement: query parametrizzata È importante chiudere sempre la connessione (con il metodo close() ), perché altrimenti il Garbage Collector non può liberare le risorse
JDBC: Statement In JDBC, uno Statement è un oggetto che permette di inviare una dichiarazione SQL al database Possiede un metodo executequery(string) che restituisce un ResultSet (array di risultati) stmt.executequery( SELECT * FROM Studenti );
JDBC: PreparedStatement I PreparedStatement, invece, hanno dei parametri PreparedStatement ps = conn.preparestatement( "SELECT * FROM STUDENTI WHERE id =?" ); ps.setint(1, 123456); ps.executequery();
DAO Data Access Object (pattern) È un oggetto che fornisce un'interfaccia astratta ad un database Fa da tramite tra l'applicazione e il Persistence Layer Disaccoppia, quindi, l'applicazione dai dettagli implementativi come il tipo di DBMS, lo schema, ecc.
DAO
DAO
DAO: vantaggi Separazione rigorosa tra due parti importanti di ogni applicazione, che in genere evolvono in parallelo Moduli maggiormente riusabili Integrazione semplice con framework che forniscono questa funzionalità
Programmazione Java Avanzata Web Development
HTTP Protocollo alla base del Web Richiesta/Risposta Testuale Stateless: ogni richiesta è indipendente da tutte le altre Pochi metodi di richiesta (GET, POST, altri poco usati) per incanalare tutte le funzionalità Completamente in chiaro
HTTP Request/Response
HTTP Un server, generalmente, si occupa di fornire, a richiesta, il contenuto di file I browser sono in grado di interpretare i file testuali scritti in linguaggio HTML Nella maggior parte dei casi, quindi, la risposta del server sarà contenuto scritto secondo HTML
HTTP Request Se l'utente scrive la URL: http://www.unirc.it/index.html Il browser invierà al server la seguente stringa: GET /index.html HTTP/1.1 HOST www.unirc.it User-Agent: Mozilla/5.0
HTTP Request Se si possono richiedere solo nomi di file, come si può strutturare una applicazione webbased?
HTTP Request Si può scrivere la URL in modo che contenga dei parametri: Http://www.unirc.it/index.html?var1=9&var2=1 oltre a chiedere la pagina index.html passiamo al server le variabili var1 (pari a 9) e var2 (pari ad 1) Si può usare il metodo POST che permette di inviare parametri nello stesso formato ma non immersi nella URL
HTTP Response Il server sta in ascolto sulla porta TCP 80 Quando riceve la richiesta, cerca il file con quel nome e ne invia il contenuto al client Fin qui c'è poco di applicativo!
Web Server I Web Server al giorno d'oggi non sono più semplici fornitori di HTML Moduli di estensione, script e server ad-hoc intercettano le richieste e permettono di manipolare l'input tramite linguaggi di programmazione L'output deve essere sempre HTML, ma i file possono essere generati al volo e non più essere fisicamente presenti sul server
Protocollo Stateless La mancanza di salvataggio dello stato interno è uno dei più grandi pregi e difetti dell'http Pro: Vedi XKCD: [http://www.xkcd.com/869/] Velocità di esecuzione Basse richieste di memoria Contro: Ogni applicazione ha bisogno di sapere cosa ha fatto l'utente in precedenza
Protocollo Stateless: soluzioni Una prima soluzione è stato l'uso dei cookie Piccoli file di testo, salvati sul client, che contengono variabili e i loro valori I cookie vengono inviati al server ad ogni request Esempio: se l'utente fornisce username e password, possono essere salvate in un cookie (insieme ad altri dati); ad ogni richiesta i cookie vengono inviati al server e quindi il server legge lo stato dai cookie
Cookie: Problematiche File di testo non crittografati Chiunque può leggerli sul pc o durante l'invio, quindi non si possono salvare dati sensibili File di testo scrivibili da chiunque Lato server, non possiamo fidarci di quello che abbiamo scritto precedentemente nei cookie Insicuri Un sito B, sfruttando vulnerabilità, potrebbe avere accesso ai cookie del sito A
Variabili di sessione Per risolvere il problema dei cookie si usano le variabili di sessione, lato server Variabili salvate sul server Si assegna ad ogni utente un hash (detto Session ID) Se l'utente fornisce l'hash al server, il server lo identifica e può consultare i dati che lo riguardano
Variabili di sessione vs. Cookie Rimane il problema: come fa il server ad identificare un client come rappresentante di un utente? Se le variabili sono lato server non c'è modo di saperlo Si scrive il Session ID in un cookie Il Session ID è un hash, è molto difficile indovinarlo Anche se il Session ID viene intercettato, ha una durata limitata nel tempo (una sessione o anche meno)
Perché il Web? Con tutti questi problemi da risolvere la domanda sorge spontanea Perché il Web è ovunque Quasi 2 miliardi di persone al mondo usano Internet Perché il Web è semplice HTML non è un linguaggio di programmazione, ma definisce solo come le informazioni vengono presentate Perché il Web è standard Esistono organismi come il W3C che si preoccupano di creare degli standard in modo che ognuno abbia la stessa esperienza sul Web, indipendentemente dal browser, dal sistema operativo e dal dispositivo
Java e HTTP Esistono librerie e classi per gestire le richieste/risposte HTTP direttamente in Java Ma gestire le richieste a questo livello molto basso: È dispendioso (è un problema abbastanza indipendente e non ha senso gestirlo volta per volta) È soggetto ad errori Sottrae tempo lavorativo che potrebbe essere dedicato alla business logic
Servlet Le Servlet sono classi Java che rispondono ad HTTP Request Definiscono delle modalità di risposta (ad esempio, in caso di GET o POST) e poi gestiscono in modo automatico il resto Per esempio, viene mantenuto lo stato nelle variabili di sessione senza che lo sviluppatore debba preoccuparsi
Servlet Una Servlet restituisce, in genere, HTML Anche se può restituire XML o altro Una Servlet viene inizializzata dal server, e, a questo punto, gestisce ogni request in un thread a parte Le Servlet sono definite nella libreria di JavaEE