首页 > Java > java教程 > 为什么我的 Http Servlet 请求在一次读取后会丢失 POST 正文参数?

为什么我的 Http Servlet 请求在一次读取后会丢失 POST 正文参数?

Susan Sarandon
发布: 2024-11-27 18:00:17
原创
918 人浏览过

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

Http Servlet 请求在读取一次后会丢失 POST 正文中的参数

在这种情况下,在处理 POST 请求时了解这一点至关重要,参数通常在请求正文中发送。默认情况下,Servlet 容器在第一次访问参数时会消耗输入字符流或二进制流。因此,后续尝试在过滤器链中访问它们会失败。

要解决此问题,需要考虑两种主要方法:

1。拦截器组件:

作为使用过滤器链的替代方案,您可以使用拦截器组件。这些组件可以使用方面来实现,并允许对解析的请求正文进行操作,而无需依赖于所使用的请求输入流。这种方法通常更有效,因为请求 InputStream 仅解析一次以创建您自己的模型对象。

2. HttpServletRequestWrapper:

对于 HTTP 层首选过滤器链的情况,扩展 HttpServletRequestWrapper 是一个有效的方法。此技术涉及消耗请求 InputStream 并缓存字节:

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");
        }
    }
}
登录后复制

通过在将原始请求传递到过滤器链之前使用 MultiReadHttpServletRequest 包装原始请求,可以多次读取请求正文。请注意,此解决方案还有助于通过 getParameterXXX 方法进行多次读取。

编辑:

对于较新版本的 ServletInputStream 接口,需要使用 isReady 和 setReadListener 等其他方法实施的。请参阅此问题以获取更多信息。

以上是为什么我的 Http Servlet 请求在一次读取后会丢失 POST 正文参数?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板