Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the problem of repeatedly reading Request Body content above SpringBoot v2.2

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report