In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "how to solve the problem of repeatedly reading Request Body content above SpringBoot v2.2". In daily operation, I believe many people have doubts about how to solve the problem of repeatedly reading Request Body content above SpringBoot v2.2. Xiaobian consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubt of "how to solve the problem of repeatedly reading Request Body content above SpringBoot v2.2". Next, please follow the editor to study!
Catalogue
Read Request Body content repeatedly above SpringBoot v2.2
I. demand
II. Solutions
Third, encounter problems
IV. Troubleshooting
Solution
The pit where Springboot reads the Request parameter
The backend is related to the parameters
About flow
SpringBoot v2.2 and above repeatedly read Request Body content 1. Requirements
The project has two scenarios that will be used to read content from Request's Body.
Print request log
Provides Api interface, reads parameters from Request Body for signature verification before api method execution, and executes api method after signature verification
II. Solutions
2.1 Custom RequestWrapper
Public class MyRequestWrapper extends HttpServletRequestWrapper {private final String body; public MyRequestWrapper (HttpServletRequest request) throws IOException {super (request); this.body = RequestReadUtils.read (request);} public String getBody () {return body;} @ Override public ServletInputStream getInputStream () throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream (body.getBytes ()); return new ServletInputStream () {... Slightly}; @ Override public BufferedReader getReader () throws IOException {return new BufferedReader (new InputStreamReader (this.getInputStream ();}}
RequestReadUtils (copied on the Internet)
Private static final int BUFFER_SIZE = 1024 * 8; public static String read (HttpServletRequest request) throws IOException {BufferedReader bufferedReader = request.getReader (); for (Enumeration iterator = request.getHeaderNames (); iterator.hasMoreElements ();) {String type = iterator.nextElement (); System.out.println (type+ "=" + request.getHeader (type));} System.out.println (); StringWriter writer = new StringWriter (); write (bufferedReader,writer) Return writer.getBuffer (). ToString ();} public static long write (Reader reader,Writer writer) throws IOException {return write (reader, writer, BUFFER_SIZE);} public static long write (Reader reader,Writer writer, int bufferSize) throws IOException {int read; long total = 0; char [] buf = new char [bufferSize] While ((read = reader.read (buf))! =-1) {writer.write (buf, 0, read); total + = read;} return total;}
2.2 define Filter
@ WebFilterpublic class TestFilter implements Filter {@ Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) {HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; MyRequestWrapper wrapper = WebUtils.getNativeRequest (request, MyRequestWrapper.class); chain.doFilter (wrapper = = null? New MyRequestWrapper (request): wrapper,servletRequest);}} III. Encounter problems
SpringBoot v2.1.x version used
There is no problem with Form submission.
There is no problem with getting RequestBody
Use SpringBoot v2.2.0 or later (including v2.3.x)
Form submission failed to get parameters
There is no problem with getting RequestBody
IV. Troubleshooting
After troubleshooting, the difference between v2.2.x and v2.1.x lies in the following code differences:
BufferedReader bufferedReader = request.getReader ();-char [] buf = new char [bufferSize]; while ((read = reader.read (buf))! =-1) {writer.write (buf, 0, read); total + = read;}
When the form is submitted
V2.1.x cannot read to the content, the read result is-1
V2.2.x, v2.3.x can read the content
When the form is submitted (x-www-form-urlencoded), the getInputStream operation of wrapper is not triggered after the inputStream is read once, so Controller cannot get the parameters.
Solution
MyRequestWrapper transformation
Public class MyRequestWrapper extends HttpServletRequestWrapper {private final String body; public MyRequestWrapper (HttpServletRequest request) throws IOException {super (request); this.body = getBodyString (request);} public String getBody () {return body;} public String getBodyString (final HttpServletRequest request) throws IOException {String contentType = request.getContentType (); String bodyString = "; StringBuilder sb = new StringBuilder () If (StringUtils.isNotBlank (contentType) & & (contentType.contains ("multipart/form-data") | | contentType.contains ("x-www-form-urlencoded")) {Map parameterMap = request.getParameterMap (); for (Map.Entry next: parameterMap.entrySet ()) {String [] values = next.getValue (); String value = null If (values! = null) {if (values.length = = 1) {value = values [0];} else {value = Arrays.toString (values) }} sb.append (next.getKey ()) .append ("=") .append (value) .append ("&");} if (sb.length () > 0) {bodyString = sb.toString (). Substring (0, sb.toString (). Length ()-1);} return bodyString } else {return IOUtils.toString (request.getInputStream ());} @ Override public ServletInputStream getInputStream () throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream (body.getBytes ()); return new ServletInputStream () {@ Override public boolean isFinished () {return false;} @ Override public boolean isReady () {return false;} @ Override public int read () {return bais.read () } @ Override public void setReadListener (ReadListener readListener) {}}; @ Override public BufferedReader getReader () throws IOException {return new BufferedReader (new InputStreamReader (this.getInputStream ();}} Springboot reads the parameters related to the pit end of the Request parameter
When the default configuration
An error will be reported when getInputStream () is used with getReader ().
Use getInputStream () twice, and the second time will be empty
When there are annotations such as @ RequestBody, springMVC has read through the stream, and either getInputStream () or getReader () alone is empty by default.
Solution: write filter inherits HttpServletRequestWrapper, cache InputStream, override getInputStream () and getReader () methods, use ByteArrayInputStream is = new ByteArrayInputStream (body.getBytes ()); read InputStream.
Note: in springboot, the filter only needs @ Component to take effect, and the path and priority can be configured in FilterRegistrationBean.
For interceptors, the addInterceptor method must be called in InterceptorRegistry. (paths can be chained)
About flow
You can only read it once, like a pipe.
It only takes the responsibility of transmission, and has nothing to do with processing and storage.
For byte streams, repeated reads are easy to implement, but the pointer is not reset in order to be consistent with the InputStream interface definition.
At this point, the study on "how to solve the problem of repeatedly reading Request Body content above SpringBoot v2.2" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
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.