当前位置:   article > 正文

解决多次读取request输入流 : getInputStream/getReader() has already been called for this request_ut010004: cannot call getreader(), getinputstream(

ut010004: cannot call getreader(), getinputstream() already called

需求

实际开发中可能需要多次读取request中的输入流进行参数校验和修改,但HttpServletRequest是只能被读取一次

问题

  1. public java.io.BufferedReader getReader()
  2. Throws:
  3. java.lang.IllegalStateException - if getInputStream() method has been called on this request
  4. public ServletInputStream getInputStream()
  5. Throws:
  6. java.lang.IllegalStateException - if the getReader() method has already been called for this request

解决方法

总体是克隆请求并通过filter再继续传递下去

step 1:

添加RepeatedlyReadRequestWrapper 类并继承 HttpServletRequestWrapper 包装类

  1. public class RepeatedlyReadRequestWrapper extends HttpServletRequestWrapper {
  2. private final String body;
  3. /**
  4. *
  5. * @param request
  6. */
  7. public RepeatedlyReadRequestWrapper(HttpServletRequest request) throws IOException{
  8. super(request);
  9. StringBuilder sb = new StringBuilder();
  10. InputStream ins = request.getInputStream();
  11. BufferedReader isr = null;
  12. try{
  13. if(ins != null){
  14. isr = new BufferedReader(new InputStreamReader(ins));
  15. char[] charBuffer = new char[128];
  16. int readCount;
  17. while((readCount = isr.read(charBuffer)) != -1){
  18. sb.append(charBuffer,0,readCount);
  19. }
  20. }
  21. }catch (IOException e){
  22. throw e;
  23. }finally {
  24. if(isr != null) {
  25. isr.close();
  26. }
  27. }
  28. sb.toString();
  29. body = sb.toString();
  30. }
  31. @Override
  32. public BufferedReader getReader() {
  33. return new BufferedReader(new InputStreamReader(this.getInputStream()));
  34. }
  35. @Override
  36. public ServletInputStream getInputStream() {
  37. final ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes());
  38. ServletInputStream servletIns = new ServletInputStream() {
  39. @Override
  40. public boolean isFinished() {
  41. return false;
  42. }
  43. @Override
  44. public boolean isReady() {
  45. return false;
  46. }
  47. @Override
  48. public void setReadListener(ReadListener readListener) {
  49. }
  50. @Override
  51. public int read() {
  52. return byteArrayIns.read();
  53. }
  54. };
  55. return servletIns;
  56. }
  57. }

step 2:

实现Filter传递请求

  1. @WebFilter("/*")
  2. public class ReadBodyHttpServletFilter extends OncePerRequestFilter {
  3. @Override
  4. protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
  5. RepeatedlyReadRequestWrapper requestWrapper = new RepeatedlyReadRequestWrapper(httpServletRequest);
  6. filterChain.doFilter(requestWrapper, httpServletResponse);
  7. }
  8. @Override
  9. public void destroy() {
  10. }
  11. }

这里采用了通过继承OncePerRequestFilter方式来实现Filter,另外,直接实现Filter。

Reference

https://blog.csdn.net/liangxw1/article/details/51095484

https://blog.csdn.net/beflyabot/article/details/78053130

https://blog.csdn.net/qq_18495465/article/details/78470939

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/550825
推荐阅读
相关标签
  

闽ICP备14008679号