栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

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

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

顺便说一句,解决此问题的另一种方法是不使用筛选器链,而是使用可以在已解析请求主体上运行的方面来构建自己的拦截器组件。由于您只需将请求

InputStream
转换为自己的模型对象一次,这样做也可能会更有效率。

但是,我仍然认为要多次读取请求正文是合理的,尤其是在请求通过过滤器链移动时。通常,我会将过滤器链用于要保留在

HTTP
层的某些操作,这些操作与服务组件分离。

正如

Will Hartung
所建议的那样,我是通过扩展
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();  }  @Override  public BufferedReader getReader() throws IOException{    return new BufferedReader(new InputStreamReader(getInputStream()));  }  private void cacheInputStream() throws IOException {        cachedBytes = new ByteArrayOutputStream();    IOUtils.copy(super.getInputStream(), cachedBytes);  }    public class CachedServletInputStream extends ServletInputStream {    private ByteArrayInputStream input;    public CachedServletInputStream() {            input = new ByteArrayInputStream(cachedBytes.toByteArray());    }    @Override    public int read() throws IOException {      return input.read();    }  }}

现在,通过在过滤器链中传递原始请求之前,可以包装原始请求多次读取请求主体:

public class MyFilter implements Filter {  @Override  public void doFilter(ServletRequest request, ServletResponse response,        FilterChain chain) throws IOException, ServletException {        MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest((HttpServletRequest) request);        doMyThing(multiReadRequest.getInputStream());    //OR    anotherUsage(multiReadRequest.getReader());    chain.doFilter(multiReadRequest, response);  }}

该解决方案还将允许您通过这些getParameterXXX方法多次读取请求正文,因为底层调用是

getInputStream()
,当然,它将读取缓存的请求
InputStream

编辑

对于较新版本的

ServletInputStream
界面。您需要提供其他一些方法的实现,例如i
sReady
setReadListener
等等。请参考下面的注释中提供的问题。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/374129.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号