60 votes

Comment puis-je obtenir le code d'état HTTP d'une ServletResponse dans un ServletFilter ?

J'essaie d'établir un rapport sur chaque code d'état HTTP renvoyé par ma webapp. Cependant, le code d'état ne semble pas être accessible via la ServletResponse, ou même si je le transforme en HttpServletResponse. Existe-t-il un moyen d'accéder à cette valeur dans un ServletFilter ?

87voto

David Rabinowitz Points 14133

Tout d'abord, vous devez enregistrer le code d'état dans un endroit accessible. Le mieux est d'envelopper la réponse dans votre implémentation et de la garder là :

public class StatusExposingServletResponse extends HttpServletResponseWrapper {

    private int httpStatus;

    public StatusExposingServletResponse(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void sendError(int sc) throws IOException {
        httpStatus = sc;
        super.sendError(sc);
    }

    @Override
    public void sendError(int sc, String msg) throws IOException {
        httpStatus = sc;
        super.sendError(sc, msg);
    }

    @Override
    public void setStatus(int sc) {
        httpStatus = sc;
        super.setStatus(sc);
    }

    public int getStatus() {
        return httpStatus;
    }

}

Afin d'utiliser ce wrapper, vous devez ajouter un filtre de servlet, où vous pouvez faire vos rapports :

public class StatusReportingFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        StatusExposingServletResponse response = new StatusExposingServletResponse((HttpServletResponse)res);
        chain.doFilter(req, response);
        int status = response.getStatus();
        // report
    }

    public void init(FilterConfig config) throws ServletException {
        //empty
    }

    public void destroy() {
        // empty
    }

}

64voto

BalusC Points 498232

Depuis la version 3.0 de Servlet, il existe une fonction HttpServletResponse#getStatus() .

Donc, s'il est possible de faire une mise à niveau, passez à Servlet 3.0 (Tomcat 7, Glassfish 3, JBoss AS 6, etc.) et vous n'aurez pas besoin de wrapper.

chain.doFilter(request, response);
int status = ((HttpServletResponse) response).getStatus();

17voto

Joel Hockey Points 111

Il faut également inclure un wrapper pour #sendRedirect, et il serait préférable d'initialiser le statut à '200' plutôt qu'à '0'.

private int httpStatus = SC_OK;

...

@Override
public void sendRedirect(String location) throws IOException {
    httpStatus = SC_MOVED_TEMPORARILY;
    super.sendRedirect(location);
}

12voto

William Rose Points 640

Il manque une chose dans la réponse de David, à savoir que vous devez également remplacer l'autre forme de sendError :

@Override
public void sendError(int sc, String msg) throws IOException {
    httpStatus = sc;
    super.sendError(sc, msg);
}

6voto

Licky Lindsay Points 947

Ecrivez un HttpServletResponseWrapper et surchargez toutes les méthodes setStatus(), sendError(), et sendRedirect() pour tout enregistrer. Ecrivez un filtre qui échange votre wrapper contre l'objet de réponse à chaque requête.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X