doFilter()
.
Effectivement, fournir à cette méthode la vraie réponse pourrait donner la possibilité aux filtres suivants ou à la servlet finale, d'écrire directement dans le buffer de réponse, et de faire appel à sa méthode
flush()
, ce qui enverrait directement la réponse au navigateur client. On ne pourrait donc plus agir sur le contenu de la réponse.
L'idée consiste donc à fournir à la chaîne un buffer que l'on construit nous-mêmes, et dont on peut contrôler l'écriture dans le vrai buffer de réponse. Comme l'objet réponse que l'on doit passer en paramètre de
doFilter()
est de type
ServletResponse
, il nous faut construire une implémentation de cette classe.
Il ne s'agit bien sûr pas de réécrire l'intégralité de cette classe, juste d'intercepter ce que la servlet pourrait écrire dans le buffer de réponse. Pour cela, on peut surcharger la méthode
getWriter()
de façon à retourner un
PrintWriter
sur notre buffer, plutôt que sur le buffer de réponse.
Écrivons tout d'abord notre implémentation de
ServletResponse
.
Exemple 34. Filtrage avec modification de la réponse - 1
public class CustomServletResponse extends HttpServletResponseWrapper { // création d'un writer sur un buffer en mémoire private Writer writer = new CharArrayWriter() ; public CustomServletResponse(HttpServletResponseWrapper response) { super(response) ; } @Override public PrintWriter getWriter() { // retourne un PrintWriter sur notre buffer plutôt que sur // la vraie réponse return new PrintWriter(writer) ; } public String toString() { return writer.toString() ; } }
Exemple 35. Filtrage avec modification de la réponse - 2
public class PostFilter implements Filter { // méthodes init() et destroy() public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { // construction de notre fausse réponse ServletResponse fakeResponse = new CustomServletResponse(response) ; // appel de la servlet filterChain.doFilter(request, response) ; // récupération de la réponse qu'elle a généré String providedResponse = fakeResponse.toString() ; // on peut modifier cette réponse ici String modifiedResponse = ... ; // puis l'envoyer vers le client // on remet les en-têtes HTTP en fonction de ce qui a été fait response.setContentLength(modifiedResponse.length()) ; // envoi de la réponse modifiée sur le flux de sortie PrintWriter printWriter = response.getWriter() ; printWriter.write(modifiedResponse) ; printWriter.close() ; } }
getOutputStream()
, ou aux méthodes
setContentType()
,
setCharacterEncoding()
, ou encore
sendError()
. Il convient donc de le compléter avant de le mettre en production, ou de ne l'utiliser que dans des cas simples et parfaitement maîtrisés.