高防服务器

SpringBoot怎么实现多次读取流


SpringBoot怎么实现多次读取流

发布时间:2022-01-31 14:25:00 来源:高防服务器网 阅读:69 作者:iii 栏目:开发技术

这篇文章主要介绍了SpringBoot怎么实现多次读取流的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot怎么实现多次读取流文章都会有所收获,下面我们一起来看看吧。

1). 存在问题
流只能读取一次

2). 目标
多次读取流

3). 解决方法
创建包装类

4). RequestWrapper

package com.mazaiting.redeye.wrapper;     import com.mazaiting.redeye.utils.StreamUtil;  import lombok.extern.slf4j.Slf4j;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;     import javax.servlet.ReadListener;  import javax.servlet.ServletInputStream;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletRequestWrapper;  import java.io.BufferedReader;  import java.io.ByteArrayInputStream;  import java.io.IOException;  import java.io.InputStreamReader;  import java.nio.charset.Charset;     /***   * @author mazaiting   * @date 2019-06-27   * @decription HttpServletRequest 包装器   * 解决: request.getInputStream()只能读取一次的问题   * 目标: 流可重复读   */  @Slf4j  public class RequestWrapper extends HttpServletRequestWrapper {      /**       * 日志       */      private static final Logger mLogger = LoggerFactory.getLogger(RequestWrapper.class);         /**       * 请求体       */      private String mBody;         public RequestWrapper(HttpServletRequest request) {          super(request);          // 将body数据存储起来          mBody = getBody(request);      }         /**       * 获取请求体       * @param request 请求       * @return 请求体       */      private String getBody(HttpServletRequest request) {          try {              return StreamUtil.getString(request.getInputStream());          } catch (IOException e) {              mLogger.debug(e.getMessage());              throw new RuntimeException(e);          }      }         /**       * 获取请求体       * @return 请求体       */      public String getBody() {          return mBody;      }         @Override      public BufferedReader getReader() throws IOException {          return new BufferedReader(new InputStreamReader(getInputStream()));      }         @Override      public ServletInputStream getInputStream() throws IOException {          // 创建字节数组输入流          final ByteArrayInputStream bais = new ByteArrayInputStream(mBody.getBytes(Charset.defaultCharset()));             return new ServletInputStream() {              @Override              public boolean isFinished() {                  return false;              }                 @Override              public boolean isReady() {                  return false;              }                 @Override              public void setReadListener(ReadListener readListener) {                 }                 @Override              public int read() throws IOException {                  return bais.read();              }          };      }  }

5).设置过滤器(必须)

@Component  @WebFilter(filterName = "HttpServletRequestFilter", urlPatterns = "/")  @Order(10000)  public class HttpServletRequestFilter implements Filter {      @Override      public void init(FilterConfig filterConfig) throws ServletException {         }         @Override      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {          ServletRequest requestWrapper = null;          if(servletRequest instanceof HttpServletRequest) {              requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);          }          //获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中          // 在chain.doFiler方法中传递新的request对象          if(null == requestWrapper) {              filterChain.doFilter(servletRequest, servletResponse);          } else {              filterChain.doFilter(requestWrapper, servletResponse);          }      }         @Override      public void destroy() {         }  }

6). 使用

/***   *   * @author mazaiting   * @date 2019-06-26   * @decription Session 拦截器   */  public class SessionInterceptor implements HandlerInterceptor {         /**       * 日志       */      private static final Logger mLogger = LoggerFactory.getLogger(SessionInterceptor.class);         @Override      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {          mLogger.debug("SessionInterceptor");          // 获取地址          String url = request.getRequestURL().toString();          mLogger.debug("url: " + url);          // 获取 session          HttpSession session = request.getSession();          String id = session.getId();          mLogger.debug("sessionId: " + id);          String requestMethod = request.getMethod();          mLogger.debug("requestMethod: " + requestMethod);          String servletPath = request.getServletPath();          mLogger.debug("servletPath: " + servletPath);             if (isJson(request)) {              String body = new RequestWrapper(request).getBody();              mLogger.debug("body: " + body);          }             return true;      }         /**       * 判断本次请求的数据类型是否为json       *       * @param request request       * @return true: 是 JSON 数据; false: 非 json 数据       */      private boolean isJson(HttpServletRequest request) {          if (request.getContentType() != null) {              return request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE) ||                      request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE);          }             return false;      }  }

关于“SpringBoot怎么实现多次读取流”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“SpringBoot怎么实现多次读取流”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注高防服务器网行业资讯频道。

[微信提示:高防服务器能助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

[图文来源于网络,不代表本站立场,如有侵权,请联系高防服务器网删除]
[