SpringBoot拦截器与过滤器 实现用户访问量/功能访问量的统计
前言
下一篇链接:实现用户访问量/功能访问量的统计信息的查询
真正在公司中的实践:NoSQL + RDBMS 一起使用才是最强的
技术没有高低之分,就看你如何去使用!(提升内功,思维的提高!多思考!)
云计算的长征之路:阿里云的这群疯子,阿里巴巴的架构演进!
1、过滤器 解决输入流不能重复读取问题
request的输入流只能读取一次不能重复读取
我们在过滤器或拦截器里读取了request的输入流之后
请求走到controller 层时就会报错。
文章最后会分析不能重复读取的原因
解决办法:HttpServletRequestWrapper + Filter(过滤器)
既然ServletInputStream不支持重新读写,那我们将ServletInputStream流读出来后,用容器存储起来起来,后面就可以多次读取了。
1.1定义RequestWrapper容器
关于HttpServletRequestWrapper类:
它并没有真正去实现HttpServletRequest的方法,而只是在方法内又去调用HttpServletRequest的方法
所以我们可以通过继承该类并实现想要重新定义的方法,就可以达到包装原生HttpServletRequest对象的目的。
RequestWrapper是我们定义的一个容器,将ServletInputStream输入流里面的数据存储到这个容器里
这个容器可以是数组或集合,然后我们重写里面的getInputStream方法
每次都从这个容器里读数据,这样我们的输入流就可以读取任意次了。
package com.hut.weekcp.server.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StreamUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
/**
* @author zxp
* @program wrapper-demo
* @description 包装HttpServletRequest,目的是让其输入流可重复读,解决了在过滤器或拦截器里读取了request的输入流之后,请求走到controller层时就会报错的问题
* @create 2021-1-22
**/
@Slf4j
public class RequestWrapper extends HttpServletRequestWrapper {
/**
* 缓存下来的HTTP body
*/
private byte[] body;
public RequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = StreamUtils.copyToByteArray(request.getInputStream());
}
/**
* 重新包装输入流
* @return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream() throws IOException {
InputStream bodyStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bodyStream.read();
}
/**
* 下面的方法一般情况下不会被使用,如果你引入了一些需要使用ServletInputStream的外部组件,可以重点关注一下。
* @return
*/
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
@Override
public BufferedReader getReader() throws IOException {
InputStream bodyStream = new ByteArrayInputStream(body);
return new BufferedReader(new InputStreamReader(getInputStream()));
}
}
1.2 定义ReplaceStreamFilter 过滤规则
在过滤器doFilter()方法里将原生的HttpServletRequest对象替换成我们的RequestWrapper对象
然后每次接口请求的输入流,都会用RequestWrapper容器存储了
package com.hut.weekcp.server.filter;
import com.hut.weekcp.server.utils.RequestWrapper;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author zxp
* @program wrapper-demo
* @description 替换HttpServletRequest
* @create 2021-1-22
**/
@Slf4j

最低0.47元/天 解锁文章
3624

被折叠的 条评论
为什么被折叠?



