Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Java Cookie, implementare un semplice CookieStore

Java: implementare un CookieStore che salvi i cookie su file e li recuperi quando il Cookie Handler è in esecuzione, anche dopo un restart della JVM
Java: implementare un CookieStore che salvi i cookie su file e li recuperi quando il Cookie Handler è in esecuzione, anche dopo un restart della JVM
Link copiato negli appunti

Nel precedente articolo abbiamo visto come il CookieStore di default perda le sue informazioni non appena la JVM termina la sua esecuzione. Vediamo adesso come superare questo problema implementando un nostro CookieStore che salvi i cookie su file e li recuperi ogni volta che il Cookie Handler torni in esecuzione, anche a seguito di un restart della JVM.

Preliminarmente è opportuno evidenziare che la classe HttpCookie è dichiarata final e non è serializzabile. Questa limitazione impedisce di serializzare su disco gli oggetti che rappresentano i cookie. Aggireremo il problema sfruttando la rappresentazione stringa di un cookie.

CookieStore

Iniziamo con il presentare il costruttore della nostra classe di tipo CookiStore:

public class MyCookieStore implements CookieStore, Runnable {
	private HashMap<URI, String> cookies;
	private final static String storePath = "c:\\cookie\\cookies.ser";
	@SuppressWarnings("unchecked")
	public MyCookieStore() throws FileNotFoundException, IOException, ClassNotFoundException {
		File file = new File(storePath);
		if(!file.exists())
			file.createNewFile();
		if(file.length()>0){
			try (FileInputStream fileIn = new FileInputStream(storePath);
					ObjectInputStream in = new ObjectInputStream(fileIn);) {
				cookies = (HashMap<URI, String>) in.readObject();
				for (Map.Entry<URI, String> entry : cookies.entrySet()) {
					List<HttpCookie> cookieList = HttpCookie.parse(entry.getValue());
					cookies.put(entry.getKey(),cookieList.get(0).toString());
				}
			}
		} else {
			cookies = new HashMap<URI,String>();
		}
		Runtime.getRuntime().addShutdownHook(new Thread(this));
	}
	@Override
	public void add(URI uri, HttpCookie cookie) {
		cookies.put(uri, cookie.toString());
	}
..

Come si può notare dal codice, facciamo in modo di serializzare su file una HashMap che tenga traccia delle coppie "URI-Cookie String". Quando il CookieStore è creato per la prima volta il file dello store non è presente. Viene creata quindi una mappa vuota.

Nelle esecuzioni successive alla prima, il rilevamento di un file per lo store porterà alla creazione di una mappa con i dati letti dal file stesso. La costruzione di un HttpCookie, partendo da una stringa che lo rappresenta, è realizzata attraverso il metodo statico parse(). Evidenziamo inoltre la creazione di un Thread da eseguire allo shutdown della JVM.

Sarà questo Thread ad occuparsi della serializzazione su disco della nostra mappa di Cookie:

..
	@Override
	public void run() {
		try {
			clearFile();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		try (FileOutputStream fileOut = new FileOutputStream(storePath);
				ObjectOutputStream out = new ObjectOutputStream(fileOut);) {
			out.writeObject(cookies);
		} catch (FileNotFoundException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	private void clearFile() throws IOException{
		File file = new File(storePath);
		file.delete();
		file.createNewFile();
	}
	..

L'implementazione di un CookieStore richiede la definizione dei metodi per il recupero dei Cookie in esso contenuti. La mappa verrà processata al fine di creare delle liste non modificabili di oggetti HttpCookie non scaduti:

@Override
	public List<HttpCookie> get(URI uri) {
		ArrayList<HttpCookie> cookieList = new ArrayList<HttpCookie>();
		if(cookies.containsKey(uri)) {
			HttpCookie ck = HttpCookie.parse(cookies.get(uri)).get(0);
			if(!ck.hasExpired())
				cookieList.add(ck);
			for (String v : cookies.values()) {
				HttpCookie c = HttpCookie.parse(v).get(0);
				String domain = c.getDomain();
				if (domain!=null && uri.toString().contains(domain)) {
					if (!c.hasExpired())
						cookieList.add(c);
				}
			}
		}
		return Collections.unmodifiableList(cookieList);
	}
	@Override
	public List<HttpCookie> getCookies() {
		ArrayList<HttpCookie> cookiesList = new ArrayList<HttpCookie>();
		for (String c : cookies.values()) {
			HttpCookie c1 = HttpCookie.parse(c).get(0);
			if (!c1.hasExpired())
				cookiesList.add(c1);
		}
		return Collections.unmodifiableList(cookiesList);
	}

Terminata la gestione del recupero dei Cookie, andiamo a definire il metodo necessario per ottenere la lista degli URI contenuti nel nostro CookieStore:

@Override
public List<URI> getURIs() {
	ArrayList<URI> uriList = new ArrayList<URI>();
	for (URI uri : cookies.keySet())
		uriList.add(uri);
	return Collections.unmodifiableList(uriList);
}

Completiamo la classe aggiungendo la logica di rimozione cookie:

@Override
public boolean remove(URI uri, HttpCookie cookie) {
	return cookies.remove(uri, cookie);
}
@Override
public boolean removeAll() {
	cookies.clear();
	return true;
}

Abbiamo terminato il nostro CookieStore personalizzato per il salvataggio su disco dei Cookie, nel successivo articolo termineremo la trattazione con l'implementazione di una policy custom.

Ti consigliamo anche