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 that the SpringBoot interceptor can no longer read the stream after it has read it?

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article focuses on "how to solve the problem that the SpringBoot interceptor can no longer read the stream", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "how to solve the problem that the SpringBoot interceptor can no longer read the stream".

Catalogue

I can think of two ways to solve this problem.

The first method

The second method

Reading the data from the body through the stream (request.getInputStream ()) in the interceptor of the SpringBoot will cause the controller to receive no value.

This problem is actually a problem of stream reading. It is well known that the input stream can only be read once in Java. The main reason is that the marking method is used to determine whether the stream has been read or not (read bit-1 means that the stream has finished reading).

I can think of two ways to solve this problem.

1. You can determine whether the stream supports the mark and reset methods by modifying the markup (the inputstream.markSupported () method). They are marking and relocating streams, respectively.)

two。 Assign the stream to a byte [] array, or other variables. Just call this array when you download the read stream.

The first method

Coming back to the question, we can first use the first method to determine whether the inputStream in requet supports tagging and relocation. Because this way is relatively simple to implement. Don't think too much about it.

@ Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {boolean b = request.getInputStream () .markSupported (); System.out.println (b);} / / the output is false

The above code returns a false so it is obvious that the input stream in request does not support tagging and relocation.

The second method

Let's consider the second method, where we need a variable to hold the stream. And make sure you get this variable both in the filter and in the controller. It is possible to directly define a global variable to obtain and modify the way of passing values. I won't demonstrate global variables in this way.

Here is the demo that changes the way the value is passed

Public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {ServletInputStream inputStream1 = request.getInputStream (); / / various operations on inputStream1 processing. Object obejct = inputStream1; request.setAttribute ("Params", obejct);}

In this way, you can get the value in Attribute directly from controller.

But! This has great limitations, for example: I have written most of the controller method bodies. At this time, the value is passed in this way. It is a great pain for developers-so through disdain Baidu query to another way to rewrite the HttpServletRequestWrapper method one by one. Why this method? Because he implemented the interface HttpServletRequest. It is also the type of request request received by our interceptor. First of all, let's look at a picture. * * Note the middle between filter and inteceptor. **

From the figure above, we can see that there is a layer of Servlet between Filter and Inteceptor. And Servlet is where the request is submitted. So we can only override the HttpServletRequest method before Servlet. That is, in filter. Here is the code directly.

1. Rewrite HttpServletRequest

Package com.xqw.kyg.util;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStreamReader;import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import org.springframework.util.StreamUtils;public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {private byte [] requestBody = null;// is used to save the stream public MyHttpServletRequestWrapper (HttpServletRequest request) throws IOException {super (request) RequestBody = StreamUtils.copyToByteArray (request.getInputStream ());} @ Override public ServletInputStream getInputStream () {final ByteArrayInputStream bais = new ByteArrayInputStream (requestBody); return new ServletInputStream () {@ Override public int read () {return bais.read () / / read data in requestBody} @ Override public boolean isFinished () {return false;} @ Override public boolean isReady () {return false;} @ Override public void setReadListener (ReadListener readListener) {}} @ Override public BufferedReader getReader () throws IOException {return new BufferedReader (new InputStreamReader (getInputStream ();}}

two。 Write Filter

Package com.xqw.kyg.filter;import com.xqw.kyg.util.MyHttpServletRequestWrapper;import org.springframework.stereotype.Component;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;@Componentpublic class HttpServletRequestReplacedFilter implements Filter {@ Override public void destroy () {} @ Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {ServletRequest requestWrapper = null If (request instanceof HttpServletRequest) {requestWrapper = new MyHttpServletRequestWrapper ((HttpServletRequest) request);} if (requestWrapper = = null) {chain.doFilter (request, response);} else {chain.doFilter (requestWrapper, response);}} @ Override public void init (FilterConfig arg0) throws ServletException {}

At this point, the code is written. You can now read the inputstream data in the filter and get it in the controller. In fact, the code is not particularly difficult. The main reason is that BUG can think of the reason in time, and provide the solution.

At this point, I believe you have a deeper understanding of "how to solve the problem that the SpringBoot interceptor can no longer read the stream". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

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