这篇文章主要介绍了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; @Slf4jpublic 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); } private String getBody(HttpServletRequest request) { try { return StreamUtil.getString(request.getInputStream()); } catch (IOException e) { mLogger.debug(e.getMessage()); throw new RuntimeException(e); } } 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). 使用
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; } 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怎么实现多次读取流”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。