I Filter nella programmazione web sono una importante feature introdotta dalle specifiche 2.3 delle Java Servlet. Attraverso i FIltri possiamo manipolare richiesta e risposta prima e dopo l’accesso ad una risorsa (jsp, servlet o statica). Questo offre un infinita serie di possibilità simili all’aggiunta di Aspects nell’AOP (Aspect Oriented Programming).
Ultimamente mi sono trovato nella necessità di parserizzare un XML tramite StAX in risposta a delle servelt e di dover modificare l’XML stesso. La cosa con XML è molto semplice, quale altro linguaggio permette così facilmente di essere parserizzato e di mutare la sua forma? Io non ho utilizzato xslt per cambiarlo, ma ho direttamente aggiunto nuovi eventi fra l’XML già composto.
L’articolo http://java.sun.com/products/servlet/Filters.html mi è stato utilissimo. In esso vengono spiegate tutte le caratteristiche dei filtri in Java e gli esempi coprono tutta la possibile panoramica di utilizzo. Di seguito riporto i punti salienti dell’articolo che ho utilizzato nel mio progetto.
Passo 1. Creazione del filtro
Creare un filtro è facilissimo, basta implementare l’interfaccia Filter e i suo metodi (che possono anche rimanere vuoti al di là del metodo doFilter).
public final class MyFilter implements Filter {
public void init(FilterConfig config){
}
public void destroy() {
}
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//azioni pre passaggio alla risorsa
chain.doFilter(request, response);
//azioni post passaggio alla risorsa
}
}
Il Filter è una vera e propria servlet. Avete accesso quindi e potete modificare tutto quanto è possibile modificare in una web application (Context, Session, Request e Response).
Passo 2. Creazione di un wrapper per salvare la response
Per modificare la response, prendiamo il PrintWriter della response, creiamo una classe che implementa la risposta http e memorizza l’output offerta dalla risorsa chiamata (servelt, jsp) in un buffer e utilizziamo questo wrapper nel chain.do, scriviamo manualmente la risposta con il PrinWriter.
La classe wrapper sarà simile a quella mostrata nell’articolo della Sun (vedi sotto)
public class CharResponseWrapper extends
HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public CharResponseWrapper(HttpServletResponse response){
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter(){
return new PrintWriter(output);
}
}
Mentre il nostro filtro viene modificato nel seguente modo
PrintWriter out = response.getWriter();
CharResponseWrapper wrapper =
new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(request, wrapper);
…
out.write(…);
Come si vede abbiamo il wrapper in cui abbiamo la risposta originale e il PrintWriter su cui scrivere la nostra response (che andrà a modificare l’originale).
Create il vostro filtro a piacimento. l’ultimo passo è attivarlo nel web.xml
Passo 3. Attivazione del Filtro
Il filtro si attiva nel web.xml come una servlet, l’unica differenza è che sarà mappato su un url-pattern di risorse, che da quel momento subiranno le azioni del filtro o, in alternativa, può essere mappato sulle singole servlet. Con i seguenti pezzi tratti dal mio web.xml concludo questo mio post sui filtri.
<filter>
<filter-name>My Filter</filter-name>
<filter-class>MyFilter</filter-class>
</filter>
…
<filter-mapping>
<filter-name>Compression Filter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>