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 being unable to read twice in controller

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

Share

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

This article introduces the relevant knowledge of "how to solve the problem that can not be read twice in controller". 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!

Catalogue

The request parameter is read in the interceptor, but cannot be read twice in controller

Create a new class

Add filter

Parameters in body cannot be obtained again in controller when using interceptor

Solution.

1. Obtain body information

2. Rewrite

3. Register filter

The request parameter is read in the interceptor, but the new class package com.ouyeelbuy.mc.common.base; import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.*; / * * @ author robin.zhang * @ date $* @ description cannot be read twice in controller to solve the problem that the data stream in request can only be read once * / public class RequestWrapper extends HttpServletRequestWrapper {private final String body Public RequestWrapper (HttpServletRequest request) {super (request); StringBuilder stringBuilder = new StringBuilder (); BufferedReader bufferedReader = null; InputStream inputStream = null; try {inputStream = request.getInputStream (); if (inputStream! = null) {bufferedReader = new BufferedReader (new InputStreamReader (inputStream)); char [] charBuffer = new char [128] Int bytesRead =-1; while ((bytesRead = bufferedReader.read (charBuffer)) > 0) {stringBuilder.append (charBuffer, 0, bytesRead);}} else {stringBuilder.append ("") } catch (IOException ex) {} finally {if (inputStream! = null) {try {inputStream.close ();} catch (IOException e) {e.printStackTrace () }} if (bufferedReader! = null) {try {bufferedReader.close ();} catch (IOException e) {e.printStackTrace ();} body = stringBuilder.toString () } @ Override public ServletInputStream getInputStream () throws IOException {final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream (body.getBytes ()); ServletInputStream servletInputStream = new ServletInputStream () {@ Override public boolean isFinished () {return false;} @ Override public boolean isReady () {return false } @ Override public void setReadListener (ReadListener readListener) {} @ Override public int read () throws IOException {return byteArrayInputStream.read ()}; return servletInputStream;} @ Override public BufferedReader getReader () throws IOException {return new BufferedReader (new InputStreamReader (this.getInputStream () } public String getBody () {return this.body;}} add filter package com.ouyeelbuy.mc.common.filter;import com.ouyeelbuy.mc.common.base.RequestWrapper;import org.springframework.stereotype.Component; import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException / * @ author robin.zhang * @ date $* @ description solves the problem that request data streams can only be read once * / @ Componentpublic class RequestFilter implements Filter {@ Override public void init (FilterConfig filterConfig) throws ServletException {} @ Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {ServletRequest requestWrapper = null; if (servletRequest instanceof HttpServletRequest) {requestWrapper = new RequestWrapper ((HttpServletRequest) servletRequest) } if (requestWrapper = = null) {filterChain.doFilter (servletRequest, servletResponse);} else {filterChain.doFilter (requestWrapper, servletResponse);} @ Override public void destroy () {}}

Then register the filter into the spring container and the problem is solved!

Parameters in body cannot be obtained again in controller when using interceptor

Error message: from the error message, you can see that the io stream has been closed. This is because the interceptor reads the parameter information in the body, so the controller cannot read it again.

I/O error while reading input message; nested exception is java.io.IOException: Stream closed

Solution.

After the interceptor reads the body information, it writes the content again

1. Obtain body information import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.ServletRequest;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.*;import java.nio.charset.Charset; / * Save stream * / public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {private final byte [] body; public BodyReaderHttpServletRequestWrapper (HttpServletRequest request) {super (request); String sessionStream = getBodyString (request) Body = sessionStream.getBytes (Charset.forName ("UTF-8"));} / * get request Body * * @ param request * @ return * / public String getBodyString (final ServletRequest request) {StringBuilder sb = new StringBuilder (); InputStream inputStream = null; BufferedReader reader = null; try {inputStream = cloneInputStream (request.getInputStream ()) Reader = new BufferedReader (new InputStreamReader (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 () } / * * Description: copy input stream * * @ param inputStream * @ return * / public InputStream cloneInputStream (ServletInputStream inputStream) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream (); byte [] buffer = new byte [1024]; int len Try {while ((len = inputStream.read (buffer)) >-1) {byteArrayOutputStream.write (buffer, 0, len);} byteArrayOutputStream.flush ();} catch (IOException e) {e.printStackTrace ();} InputStream byteArrayInputStream = new ByteArrayInputStream (byteArrayOutputStream.toByteArray ()); return byteArrayInputStream } @ 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) {}} }} 2. Rewrite import org.springframework.core.annotation.Order;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import java.io.IOException / / indicates the order in which filtering is performed. The lower the value, the better to perform @ Order (1) / / configure the address to be filtered @ WebFilter (filterName = "bodyReaderFilter", urlPatterns = "/ *") public class BodyReaderFilter implements Filter {@ Override public void init (FilterConfig filterConfig) throws ServletException {/ / System.out.println ("- filter initialization -") } @ Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {/ / System.out.println ("- perform filtering operation -"); / / prevent the stream from being left after it is read once, so you need to continue to write out the stream HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper (httpServletRequest); filterChain.doFilter (requestWrapper, servletResponse);} @ Override public void destroy () {/ / System.out.println ("- filter destruction -");}} 3, register filter import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication Import org.springframework.boot.web.servlet.ServletComponentScan;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.openfeign.EnableFeignClients; @ SpringBootApplication@EnableFeignClients@EnableDiscoveryClient// Registration filter Note @ ServletComponentScanpublic class WebPlatformApplication {public static void main (String [] args) {SpringApplication.run (WebPlatformApplication.class);}} "how to solve the problem that cannot be read twice in controller" 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.

Share To

Development

Wechat

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

12
Report