Maison >Java >javaDidacticiel >Pourquoi ma requête de servlet HTTP perd-elle les paramètres du corps POST après une seule lecture ?

Pourquoi ma requête de servlet HTTP perd-elle les paramètres du corps POST après une seule lecture ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-27 18:00:17882parcourir

Why Does My Http Servlet Request Lose POST Body Parameters After a Single Read?

La requête de servlet HTTP perd les paramètres du corps POST après une lecture unique

Dans cette situation, il est crucial de comprendre que lorsqu'on traite une requête POST , les paramètres sont généralement envoyés dans le corps de la requête. Par défaut, les conteneurs Servlet consomment le flux de caractères d'entrée ou le flux binaire lors du premier accès aux paramètres. En conséquence, les tentatives ultérieures pour y accéder dans la chaîne de filtres échouent.

Pour surmonter ce problème, il existe deux approches principales à considérer :

1. Composants d'intercepteur :

Au lieu d'utiliser la chaîne de filtres, vous pouvez utiliser des composants d'intercepteur. Ces composants peuvent être implémentés à l'aide d'aspects et permettent le fonctionnement du corps de la requête analysé sans dépendre de l'InputStream de la requête consommée. Cette approche est généralement plus efficace puisque la requête InputStream n'est analysée qu'une seule fois pour créer votre propre objet modèle.

2. HttpServletRequestWrapper :

Pour les cas où la chaîne de filtres est préférée au niveau de la couche HTTP, l'extension de HttpServletRequestWrapper est une méthode efficace. Cette technique consiste à consommer la requête InputStream et à mettre en cache les octets :

public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
    private ByteArrayOutputStream cachedBytes;

    public MultiReadHttpServletRequest(HttpServletRequest request) {
        super(request);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        if (cachedBytes == null)
            cacheInputStream();

        return new CachedServletInputStream(cachedBytes.toByteArray());
    }

    @Override
    public BufferedReader getReader() throws IOException{
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    private void cacheInputStream() throws IOException {
        /* Cache the inputstream in order to read it multiple times. For
         * convenience, I use apache.commons IOUtils
         */
        cachedBytes = new ByteArrayOutputStream();
        IOUtils.copy(super.getInputStream(), cachedBytes);
    }

    /* An input stream which reads the cached request body */
    private static class CachedServletInputStream extends     ServletInputStream {

        private final ByteArrayInputStream buffer;

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

        @Override
        public int read() {
            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");
        }
    }
}

En encapsulant la requête d'origine avec MultiReadHttpServletRequest avant de la transmettre à travers la chaîne de filtrage, le corps de la requête peut être lu plusieurs fois. Notez que cette solution facilite également les lectures multiples via les méthodes getParameterXXX.

Edit :

Pour les versions plus récentes de l'interface ServletInputStream, des méthodes supplémentaires telles que isReady et setReadListener doivent être mis en œuvre. Reportez-vous à cette question pour plus d'informations.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn