In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces the knowledge of "how to build a request that can read inputStream repeatedly". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Build a request that can read inputStream repeatedly
We know that the inputStream of request can only be read once, and multiple reads will report an error, so how can it be read repeatedly? One answer is to increase buffering and record what has been read.
The code is as follows:
Import lombok.extern.log4j.Log4j2;import org.springframework.mock.web.DelegatingServletInputStream;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.*;/** * request wrapper: repeatable read request.getInputStream * / @ Log4j2public class RepeatedlyReadRequestWrapper extends HttpServletRequestWrapper {private static final int BUFFER_START_POSITION = 0; private static final int CHAR_BUFFER_LENGTH = 1024; / * * input stream buffer * / private final String body / * * @ param request {@ link javax.servlet.http.HttpServletRequest} object. * / public RepeatedlyReadRequestWrapper (HttpServletRequest request) {super (request); StringBuilder stringBuilder = new StringBuilder (); InputStream inputStream = null; try {inputStream = request.getInputStream ();} catch (IOException e) {log.error ("Error reading the request body …" , e);} if (inputStream! = null) {try (BufferedReader bufferedReader = new BufferedReader (new InputStreamReader (inputStream) {char [] charBuffer = new char [Char _ BUFFER_LENGTH]; int bytesRead; while ((bytesRead = bufferedReader.read (charBuffer)) > 0) {stringBuilder.append (charBuffer, BUFFER_START_POSITION, bytesRead) } catch (IOException e) {log.error ("Fail to read input stream", e);}} else {stringBuilder.append (");} body = stringBuilder.toString ();} @ Override public ServletInputStream getInputStream () throws IOException {final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream (body.getBytes ()) Return new DelegatingServletInputStream (byteArrayInputStream);}}
Next, you need a corresponding Filter.
The code is as follows:
Import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;public class RepeatlyReadFilter implements Filter {@ Override public void init (FilterConfig filterConfig) throws ServletException {/ / Do nothing} @ Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {if (request instanceof HttpServletRequest) {request = new RepeatedlyReadRequestWrapper ((HttpServletRequest) request);} chain.doFilter (request, response) } @ Override public void destroy () {/ / Do nothing}}
Finally, you need to add the configuration of the Filter in web.xml.
InputStream read multiple times in request
When using HTTP protocol to achieve inter-application interface communication, the server will use request.getInputStream () to read the data requested by the client. The data can be read when it is read for the first time, but it can not be read in the next read operation.
Reason
After an InputStream object has been read, it cannot be read again and always returns-1
InputStream does not implement the reset method (which can reset the position read for the first time) and cannot implement the reset operation
Solution (caching read data)
Use request, session, etc., to cache read data, which is easy to implement, as long as setAttribute and getAttribute
Use HttpServletRequestWrapper to wrap HttpServletRequest, initialize reading InputStream data from request, cache it in the form of byte [], and then convert request to wrapped request in Filter
Code
Write a rHttpServletRequestWrapper subclass to process the request data
Import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.nio.charset.Charset;import java.util.Enumeration;import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import lombok.extern.slf4j.Slf4j;@Slf4jpublic class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {private final byte [] body Public BodyReaderHttpServletRequestWrapper (HttpServletRequest request) throws IOException {super (request); Enumeration e = request.getHeaderNames (); while (e.hasMoreElements ()) {String name = (String) e.nextElement (); String value = request.getHeader (name) Log.debug ("HttpServletRequest header information: {}-{}", name, value);} 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 boolean isFinished () {return false } @ Override public boolean isReady () {return false } @ Override public void setReadListener (ReadListener listener) {} @ Override public int read () throws IOException {return bais.read () }}; @ Override public String getHeader (String name) {return super.getHeader (name);} @ Override public Enumeration getHeaderNames () {return super.getHeaderNames () @ Override public Enumeration getHeaders (String name) {return super.getHeaders (name);}}
Call
Public void doFilter (ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; ServletRequest requestWrapper = null; requestWrapper = new BodyReaderHttpServletRequestWrapper (httpRequest) / / data reading processing / /. / / send the requestWrapper to the following filter filterChain.doFilter (requestWrapper, httpResponse);} "how to build a request that can read inputStream repeatedly" ends here. Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.