怎么解决在controller中无法二次读取的问题
发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,本篇内容介绍了"怎么解决在controller中无法二次读取的问题"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能
千家信息网最后更新 2025年02月02日怎么解决在controller中无法二次读取的问题
本篇内容介绍了"怎么解决在controller中无法二次读取的问题"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
目录
拦截器中读取request参数,在controller中无法二次读取
新建类
添加过滤器
使用拦截器时,controller中不能再次获取body中的参数
解决办法
1、获取body信息
2、重新写入
3、注册过滤器
拦截器中读取request参数,在controller中无法二次读取
新建类
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 解决在request的数据流只能读取一次的问题 */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; }}
添加过滤器
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 解决request数据流只能读取一次的问题 */@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() { }}
然后注册这个过滤器到spring容器中,问题解决!
使用拦截器时,controller中不能再次获取body中的参数
报错信息:从报错信息可以看出,io流已经关闭。这是由于拦截器读取了body中的参数信息,导致controller不能再次读取。
I/O error while reading input message; nested exception is java.io.IOException: Stream closed
解决办法
在拦截器读取到body信息后,再次将内容写入
1、获取body信息
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; /** * 保存流 */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")); } /** * 获取请求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: 复制输入流 * * @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、重新写入
import org.springframework.core.annotation.Order;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import java.io.IOException;// 表示执行过滤顺序,值越小,越先执行@Order(1)// 配置需要过滤的地址@WebFilter(filterName = "bodyReaderFilter", urlPatterns = "/*")public class BodyReaderFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {// System.out.println("--------------过滤器初始化------------"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// System.out.println("--------------执行过滤操作------------"); // 防止流读取一次后就没有了, 所以需要将流继续写出去 HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest); filterChain.doFilter(requestWrapper, servletResponse); } @Override public void destroy() {// System.out.println("--------------过滤器销毁------------"); } }
3、注册过滤器
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// 注册过滤器注解@ServletComponentScanpublic class WebPlatformApplication { public static void main(String[] args) { SpringApplication.run(WebPlatformApplication.class); }}
"怎么解决在controller中无法二次读取的问题"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
过滤器
信息
拦截器
问题
参数
再次
内容
办法
数据
数据流
更多
知识
UTF-8
实用
学有所成
接下来
困境
地址
实际
容器
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
启用4g单数据库
刘志辉网络安全
联社积极开展网络安全宣传周活动
数据库删除是逻辑删除还是物理
网络安全是谁的责任
苹果的网络安全设置
网吧网络安全管理制度
两台电脑直接传输数据库
专注于科技互联网的公司
广州花朵网络技术
家用监控网络安全性怎么样
网络安全技术与实践第四
accse数据库数据位数处理
沈阳新华互联网科技学校
新乡市黑玛网络技术有限公司
网络技术专升本英语考题
民警网络安全意识不强的表现
计算机网络安全开题报告2000
雪晴计算机软件开发工作室1
access数据库难学吗
用数据库写一个购物车
白银市网络安全宣传周
党史学习教育税务局网络安全
爬虫中如何解析网页数据库
战舰少女r ios服务器
华为的数据库如何打开
威高软件开发面试
衡水商城软件开发哪家好
pb画板连接数据库报错
北交大信息网络安全