web-dev-qa-db-fra.com

HttpServletRequestWrapper, exemple d'implémentation pour setReadListener / isFinished / isReady?

J'essaie d'adapter un HttpServletRequestWrapper (voir Comment lire plusieurs fois InputStream ) pour pouvoir lire le corps de la publication HTTP après l'avoir consommé dans un filtre. Maintenant, je rencontre un défi sur la façon d'implémenter le ServletInputStream. Depuis la spécification 3.1, de nouvelles méthodes doivent être implémentées.

  • est fini
  • est prêt
  • setReadListener

Je cherche des exemples ou du code sur la façon dont ces méthodes peuvent être implémentées. Des indices?

25
Marco

Exemple d'implémentation:

import com.google.common.primitives.Bytes;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import Java.io.ByteArrayInputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.util.Arrays;

public class AuthenticationRequestWrapper extends HttpServletRequestWrapper {

    // tag::variables[]
    private byte[] requestBody = new byte[0];
    private boolean bufferFilled = false;
    // end::variables[]

    /**
     - Constructs a request object wrapping the given request.
     *
     - @param request The request to wrap
     - @throws IllegalArgumentException if the request is null
     */
    public AuthenticationRequestWrapper(HttpServletRequest request) {
        super(request);
    }


    // tag::getRequestBody[]
    public byte[] getRequestBody() throws IOException {
        if (bufferFilled) {
            return Arrays.copyOf(requestBody, requestBody.length);
        }

        InputStream inputStream = super.getInputStream();

        byte[] buffer = new byte[102400]; // 100kb buffer

        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            requestBody = Bytes.concat(this.requestBody, Arrays.copyOfRange(buffer, 0, bytesRead)); // <1>
        }

        bufferFilled = true;

        return requestBody;
    }
    // end::getRequestBody[]

    // tag::getInputStream[]
    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new CustomServletInputStream(getRequestBody()); // <1>
    }
    // end::getInputStream[]

    private static class CustomServletInputStream extends ServletInputStream {

        private ByteArrayInputStream buffer;

        public CustomServletInputStream(byte[] contents) {
            this.buffer = new ByteArrayInputStream(contents);
        }

        @Override
        public int read() throws IOException {
            return buffer.read();
        }

        @Override
        public boolean isFinished() {
            return buffer.available() == 0;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener listener) {
            throw new RuntimeException("Not implemented");
        }
    }
}
22
Marco

vous pouvez vérifier MockHttpServletRequest dans le framework Spring

Le code source a pu être trouvé ici

Étant donné que Spring est open source avec une licence Apache2, vous pouvez commencer à partir du code et créer votre propre version.

4
Giovanni