
guide
Tutti i linguaggi per diventare uno sviluppatore di app per Android.
Costruzione di un sistema di votazione, con le classiche stellette, sfruttando AJAX e Java
Negli ultimi articoli abbiamo visto alcuni elementi di design tipici delle Web application più moderne (per esempio la ricerca dinamica). In diverse occasioni abbiamo rimarcato come la sempre più massiccia presenza di tecniche AJAX ha reso le funzionalità dei siti Web più usabili e accattivanti allo stesso tempo.
Attraverso queste tecniche i Web designer si sono cimentati nello sviluppo di elementi (spesso noti come widget) che ricorrono in tutti i più importanti siti Web, in particolare nei siti di social network o di condivisione (foto e video).
Quello che vedremo in questo articolo è un elemento non proprio innovativo, ma che attraverso la tecnica AJAX cambia rendendo l’accesso a questa funzione più fluida rispetto al suo antenato non-AJAX: parliamo di un widget per permettere agli utenti di votare una risorsa.
L’elemento non è innovativo nel senso stretto del termine in quanto negli anni lo si è visto in diverse salse; innovativo è il modo in cui oggi viene proposto utilizzando tecniche AJAX che noi vedremo affiancate alla tecnologia lato server Java.
Per focalizzare l’attenzione sull’elemento di votazione, riutilizzeremo un servizio che abbiamo già sviluppato, la tag cloud in java, estendendolo con la nuova funzionalità, che sarà utilizzabile con qualsiasi progetto adattando i suggerimenti che vedremo nei prossimi paragrafi.
Quello che vogliamo realizzare è un sistema che permetta all’utente di votare la risorsa, in maniera asincrona (quindi, rimanendo all’interno della pagina Web). In più vogliamo rendere accattivante la funzionalità, permettendo all’utente di utilizzare un “sistema a stelline” che gli consenta visivamente di effettuare il voto cliccando sul numero di stelle che desidera. Infine, l’utente ha un suggerimento che cambia a ogni stellina, identificando in maniera testuale il voto.
A dirla tutta si tratta del sistema che oggi troviamo in tutti i siti di condivisione (video, foto, notizie, ecc) più o meno importanti.
Come al solito partiamo dalle modifiche che dovremo apportare alla base di dati. Riprendendo l’articolo citato in precedenza ci preoccuperemo di aggiungere due campi alla tabella che mantiene le informazioni sulla risorsa persistenti. In questo modo ci preoccupiamo di registrare il numero di voti effettuati e il voto totale (e quindi siamo in grado di definire la media).
L’utilizzo di questi campi rende l’impatto della modifica minimale, mantenendo efficacia nel nostro scopo. Applicato al nostro esempio avremo:
Modifica al database
ALTER TABLE ‘tagcloud’.’resource’
ADD COLUMN ‘totalrating’ INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER ‘description’,
ADD COLUMN ‘totalVote’ INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER ‘totalrating’;
A questo punto dobbiamo provvedere a integrare le nuove informazioni. La classe che rappresenta la risorsa è per noi Resource. La classe che gestisce la sua persistenza è DBManager.
Creiamo una classe RatingResource in cui gestiamo i due parametri aggiunti al database.
Listato 1. Estende le funzionalità della precedente con il sistema di voto
// RatingResource.java
package it.html.tagcloud.rating;
import it.html.tagcloud.Resource;
public abstract class RatingResource{
//Le istanze che rappresentano il voto totale e il numero di votanti
protected int totalRating;
protected int totalVotes;
public int getTotalRating(){
return totalRating;
}
public void setTotalRating(int totalRating) {
this.totalRating = totalRating;
}
public int getTotalVotes(){
return totalVotes;
}
public void setTotalVotes(int totalVotes){
this.totalVotes = totalVotes;
}
}
Creiamo un’interfaccia RatingDBManager in cui gestiamo il metodo che effettua l’operazione di voto (aggiunge un voto alla risorsa).
Listato 2. Gestisce il metodo che effettua l’operazione di voto
//RatingDBManager.java
package it.html.tagcloud.rating;
import it.html.tagcloud.Resource;
import it.html.tagcloud.rating.RatingException;
public interface RatingDBManager {
public void rate(Resource res, int vote)throws RatingException;
}
Per mantenere il servizio funzionante, ora, effettuiamo l’estensione di queste classi dalla classe Resource e dalla classe DBManager. Nel costruttore di Resource, aggiungiamo il riferimento ai due nuovi parametri, in questo modo, il tool di sviluppo che stiamo utilizzando ci darà informazioni sulle relazioni che sono cambiate e quindi dove intervenire nelle modifiche.
Listato 3. Estende le classi RatingResource e RatingDBManager
public class Resource extends RatingResource {
..//
public Resource(int id, String title, String description, Collection tags, int totalRating, int totalVotes) {
this.id=id;
this.title=title;
this.description=description;
this.tags=tags;
// Settiamo i campi ereditati
this.totalRating=totalRating;
this.totalVotes=totalVotes;
}
..//
public interface DBManager extends RatingDBManager
..//
Come vediamo dalle segnalazioni di errore, le uniche modifiche sono nella classe DBManagerConcrete (quella che concretamente si occupa di gestire il collegamento con il database). La prima modifica che dobbiamo fare è nell’istanziazione della classe Resource (abbiamo cambiato il costruttore) che modifichiamo come segue:
Listato 4. Modifiche al costruttore
..//
//Aggiunta dei campi per il sistema di rating
int totalRating=rs.getInt(“totalrating”);
int totalVotes=rs.getInt(“totalvote”);
//Creazione dell’istanza da restituire
toRet=new Resource(id,title,description,tags,totalRating,totalVotes);
..//
Ci sono tre riferimenti, che modificheremo allo stesso modo. L’altra modifica da fare riguarda la definizione concreta del metodo utilizzato per settare il voto della risorsa:
Listato 5. Definisce il metodo utilizzato per votare
..//
public void rate(Resource res, int vote) throws RatingException {
if (vote<1 || vote>5)
throw new RatingException(“Voto fuori dai limiti”);
//altrimenti effettuiamo la votazione
try{
openConnection();
String sql=”UPDATE resource set totalrating=totalrating+?,totalvote=totalvote+1 WHERE id=?”;
PreparedStatement pst=connection.prepareStatement(sql);
pst.setInt(1,vote);
pst.setInt(2,res.getId());
pst.execute();
//Chiusura dei flussi aperti
pst.close();
closeConnection();
}catch(Exception e){
e.printStackTrace();
}
}
..//
In pratica ci occupiamo di aumentare di un’unità il contatore e di aggiungere il voto dato (a meno che il voto non vada fuori dai limiti, in quel caso solleviamo l’eccezione).
Dopo aver effettuato qualche test di unità, passiamo a definire la funzione sul controller. Qui ci occuperemo di inoltrare il voto utente verso il layer di persistenza e di definire un controllo sulle risorse da votare attraverso l’utilizzo dei cookie. Avendo mantenuto la struttura invariata, la servlet utilizzata funziona ancora correttamente, quindi dovremo estenderla con la funzione di voto:
Listato 6. Gestisce il meccanismo di votazione del gioco
..//
public class RatingController extends Controller {
..//
private void rateResource(HttpServletRequest request, HttpServletResponse response) throws IOException {
//Recupero il codice
String id=request.getParameter(“id”);
int rate=Integer.parseInt(request.getParameter(“rate”));
//Se non è stato ancora votato
if (!alreadyRated(request,id,rate)){
//Carico la risorsa
Resource res=db.loadResource(Integer.parseInt(id));
try{
//Effettuo l’operazione persistente
db.rate(res,rate);
//marchiamo la risorsa come già votata
setAsRated(response,id,rate);
response.getWriter().println(“Grazie, il tuo voto è stato aggiunto.”);
}catch (RatingException ex) {
response.getWriter().println(ex.getMessage());
}
}else{
response.getWriter().println(“Hai già espresso la preferenza per questa risorsa.”);
}
}
//Il metodo verifica nei cookie se la risorsa è presente
private boolean alreadyRated(HttpServletRequest request, String id, int rate) {
Cookie []list=request.getCookies();
for (int i=0;i<list.length;i++){
if (list[i].getName().equals(id))
return true;
}
return false;
}
//Aggiungiamo il cookie alla lista
private void setAsRated(HttpServletResponse response, String id, int rate) {
//Creo un cookie
Cookie cookie=new Cookie(id,String.valueOf(rate));
//e lo appendo alla lista
response.addCookie(cookie);
}
}
Il metodo che si occupa di gestire il flusso della funzione è il metodo rateResource()
. Il flusso è il seguente:
La gestione dei cookie è affidata ai metodi alreadyRated()
e setAsRated()
, che potete vedere nel codice. La scadenza del cookie è in questo caso lasciata al default (sessione utente) ma può essere estesa in base alle esigenze.
La parte AJAX, come ormai sappiamo, viene nell’interfaccia e ci permetterà di gestire in maniera dinamica gli elementi della pagina, definendo opportunamente le funzioni da utilizzare. Quello che cambierà è la pagina di rappresentazione della risorsa, aggiungendo l’elemento grafico per effettuare la votazione:
Listato 7. Elemento grafico che permette di votare
<p class=”rate”>
<%
String src=null;
int votes=res.getTotalVotes();
double rate=0;
if (votes>0)
rate=res.getTotalRating()/votes;
for (int i=1;i<=5;i++){
if (rate>=i)
src=”./img/fullstar.gif”;
else
src=”./img/emptystar.gif”;
%>
<a ID=”STARLINK<%=i%>” href=”#” onclick=”javascript:setStars(<%=res.getId()%>,<%=i%>); return false;”
onmouseover=”javascript:showStars(<%=i%>);” onmouseout=”javascript:revertStars(<%=(int)rate%>);”>
<img border=”0″ ID=”STAR<%=i%>” src=”<%=src%>”/></a>
<%
}
%>
<span id=”RATETIP”>
</span>
<span id=”RATEMSG”>
<%
if (votes>0)
out.println(“(“+votes+” voti ricevuti)”);
else
out.println(“(ancora nessun voto)”);
%>
</span>
</p>
Identificheremo gli elementi della pagina con un id univoco, in modo da poterli manipolare correttamente; essi sono: STARLINKi
e STARi
che rappresentano la iesima stellina (con i da 1 a 5) e RATETIP
e RATEMSG
. Gli ultimi elementi rappresentano gli elementi contenitore dei messaggi che scambieremo.
Attraverso le funzioni javascript setStars()
, showStars()
e revertStars()
gestiremo la logica di rappresentazione.
Listato 8. Gestisce la logica di rappresentazione
//ajax.js
function showStars(n){
clearStars();
for(i=1;i<=n;i++){
document.getElementById(‘STAR’+i).src=”./img/fullstar.gif”;
}
switch(n){
case 1:
replaceSimpleText(‘RATETIP’,”Poor”);
break;
case 2:
replaceSimpleText(‘RATETIP’,”Nothing special”);
break;
case 3:
replaceSimpleText(‘RATETIP’,”Good”);
break;
case 4:
replaceSimpleText(‘RATETIP’,”Cool”);
break;
case 5:
replaceSimpleText(‘RATETIP’,”Awesome!”);
break;
}
}
..//
function setStars(id,n){
hide(“RATETIP”);
caricaTesto(“RATEMSG”,”./RatingController?op=rate&id=”+id+”&rate=”+n);
revertStars(n);
}
..//
La funzione showStars()
si occupa di evidenziare il numero di stelline puntate dal mouse (con la funzione onmousover) e di mostrare il messaggio (poor, nothing special, good, cool oppure awesome) nell’elemento RATETIP.
La vera funzione asincrona (AJAX) è la funzione setStars()
il cui compito è di inoltrare la funzione sul controller e caricarne il risultato (il testo restituito dalla servlet) all’interno dell’elemento RATEMSG. Tutto quanto in maniera asincrona, con il supporto delle funzioni AJAX, effettuando operazioni lato server ma rimanendo all’interno della stessa pagina Web.
Una volta effettuato il deploy possiamo vedere il risultato di una semplice esecuzione.
Se vuoi aggiornamenti su Sistema di votazioni con AJAX inserisci la tua email nel box qui sotto:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
La tua iscrizione è andata a buon fine. Se vuoi ricevere informazioni personalizzate compila anche i seguenti campi opzionali:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
Molto spesso sulla rete si trovano immagini a cui è stato applicato l’effetto “vetro rotto”, in modo da dare l’impressione […]
Tutti i linguaggi per diventare uno sviluppatore di app per Android.
Come creare applicazioni per il Web con PHP e MySQL per il DBMS.
Tutte le principali tecnologie per diventare uno sviluppatore mobile per iOS.
I fondamentali per lo sviluppo di applicazioni multi piattaforma con Java.
Diventare degli esperti in tema di sicurezza delle applicazioni Java.
Usare Raspberry Pi e Arduino per avvicinarsi al mondo dei Maker e dell’IoT.
Le principali guide di HTML.it per diventare un esperto dei database NoSQL.
Ecco come i professionisti creano applicazioni per il Cloud con PHP.
Lo sviluppo professionale di applicazioni in PHP alla portata di tutti.
Come sviluppare applicazioni Web dinamiche con PHP e JavaScript.
Fare gli e-commerce developer con Magento, Prestashop e WooCommerce.
Realizzare applicazioni per il Web utilizzando i framework PHP.
Creare applicazioni PHP e gestire l’ambiente di sviluppo come un pro.
Percorso base per avvicinarsi al web design con un occhio al mobile.
Realizzare siti Web e Web application con WordPress a livello professionale.
Impariamo ad utilizzare Takamaka, una blockchain Java Full Stack, per scrivere codice Java installabile ed eseguibile su una blockchain
In questo articolo impareremo a gestire gli URL (Uniform Resource Locator) attraverso le API messe a disposizione dal linguaggio di programmazione Java.
Java 13: In questo articolo andiamo a presentare le nuove caratteristiche introdotte dalla release elencandole in base al codice JEP che le identifica.
Impariamo a sviluppare applicazioni Java per i sistemi Embedded, piattaforme che a differenza delle tradizionali soluzioni general purpose vengono progettate per svolgere compiti specifici. Nel corso delle guida verranno fornite le nozioni necessarie per installare Oracle Java SE Embedded, scegliere il profilo e la JVM da utilizzare, configurare una JRE personalizzata, creare una prima App ed effettuarne il deploy