解決request.getInputStream()只能讀取一次的問題
阿新 • • 發佈:2021-10-26
參考文章:http://dditblog.com/itshare_529.html
程式碼需要獲取入參裡面URL後面的引數,還有POST請求裡面BODY的資料;
1、直接獲取URL後面的資料
直接使用request.getParameter("appKey");就可以完成
2、獲取BODY裡面的JSON資料
無法直接獲取request,直接獲取getInputStream()裡面入參情況,遍歷的時候會提示streamclose()的錯誤;
造成原因:
request在Spring裡面已經獲取了一次,流只能讀一次、 讀了就沒有了、為了後面的程式碼還能夠取得流;
解決辦法:
/** * 獲取請求Body * *HttpHelper.java@param request * @return */ public static String getBodyString(ServletRequest request) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null; try { inputStream = request.getInputStream(); reader = new BufferedReader(newInputStreamReader(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(); }
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 防止流讀取一次後就沒有了, 所以需要將流繼續寫出去 ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request); String json = HttpHelper.getBodyString(requestWrapper); System.out.println(json); filterChain.doFilter(requestWrapper, response); }Filter.Java
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) { } }; } }BodyReaderHttpServletRequestWrapper.java