SpringBoot实现拦截器其实很简单,我们只需要实现HandlerInterceptor接口,然后实现接口里面的preHandle和postHandle方法,或者afterCompletion方法。
这里我们分别说下这三个方法
preHandle:从方法的名字看,预处理;意思就是拦截器在执行业务方法前的一个预处理。返回值是一个boolean型,true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器。
postHandle:方法执行后的回调方法,就是当业务处理类方法执行结束之后会回调这个方法。
afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调。如果有需要性能监控的需求,我们可以在此记录结束时间并输出消耗时间;还可以进行一些资源清理,类似于try-catch-finally中的finally等等。
@Component
@Slf4j
public class SignInterceptor implements HandlerInterceptor {
private YourService yourService;
// 开始时间
private long startTime = 0;
// 结束时间
private long endTime = 0;
// 通过构造方面注入你的service方便业务逻辑处理
public SignInterceptor(YourService yourService) {
this.yourService = yourService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
startTime = System.currentTimeMillis();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date reqDate = new Date(startTime);
log.info("CurrentTime:{}", formatter.format(reqDate));
String requestURL = request.getRequestURI();
log.info("RequestURL: {} ", requestURL);
log.info("GetMethod: {}", handler);
// 获取请求参数
RequestWrapper requestWrapper = new RequestWrapper(request);
String body = requestWrapper.getBody();
log.info("RequestBody: {}", body);
在这里我们就可以处理一些数据校验或者其他方面的业务逻辑
} catch (Exception e){
log.error("start-MVC业务处理-拦截器异常:", e);
recordEntity.setErrorMsg(e.getMessage());
} finally {
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
// 获取接口响应状态码
Integer resStatus = response.getStatus();
这里编写接口响应之后的业务逻辑代码
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
endTime = System.currentTimeMillis();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date resDate = new Date(endTime);
log.info("ReqLengthTime:{}", (endTime - startTime) + "ms");
这里可以做一些性能方面的监控和资源清理
}
}
@Configuration
@AllArgsConstructor
public class MvcInterceptorConfig implements WebMvcConfigurer {
private final YourService yourService;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 设置拦截器拦截的URL地址
registry.addInterceptor(new SignInterceptor(yourService)).addPathPatterns("/api/**");
}
}
获取请求报文的代码
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() {
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;
}
}