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!