request.getInputStream()只有读一次的解决办法

问题描述:

我们在基于http做接口间调用时,服务端通过request.getInputStream()获取客户端的请求,如果我们需要在这个请求真正到达方法前做一些数据的校验以及内容的判断时,我们会通过一个filter进行处理,但是在filter执行通过后,我们方法再次获取请求参数时值却为空。

产生原因:

request.getInputStream()只有读一次

解决方法:

我们使用HttpServletRequestWrapper来包装HttpServletRequest,在BodyReaderHttpServletRequestWrapper初始化时读取request中的InputStream数据,并将其以byte[]缓存其中,在filter中我们使用包装过的request对象

代码:(转自http://dditblog.com/itshare_529.html)

(1)BodyReaderHttpServletRequestWrapper类:

public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{

    private final byte[] body;

    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));
    }

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

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

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

            @Override
            public void setReadListener(ReadListener readListener) {
            }
        };
    }

}

(2)HttpHelper类:

public class HttpHelper {
public static String getBodyString(ServletRequest request) {
    StringBuilder sb = new StringBuilder();
    InputStream inputStream = null;
    BufferedReader reader = null;
    try {
        inputStream = request.getInputStream();
        reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
        String line = "";
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return sb.toString();
}
}

(3)filter中调用:

public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) arg0;
    HttpServletResponse response = (HttpServletResponse) arg1;
    // 解决Controller中RequestBody流的二次读取
    ServletRequest requestWrapper = null;
    try{
        if (request instanceof HttpServletRequest) {
    requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
}
String reqBody=HttpHelper.getBodyString(requestWrapper);    //获取请求参数
}catch (Exception e) {
    logger.error("过滤器错误" + e.getMessage());
}
    arg2.doFilter(requestWrapper, response);

}

(4)目标方法中还是通过request.getInputStream()获取参数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值