一些系统经常需要关注用户请求的具体信息,如用户信息、请求参数、响应结果等等,在SpringBoot应用中可通过注册全局请求拦截器的方式统一处理。下面的案例将简单实现打印请求和响应的相关信息,具体可根据实际业务需要进行相应调整(注意方法尽量轻量化,防止加重系统处理每个请求的负担),记录下实现步骤。
1 自定义拦截器
实现HandlerInterceptorAdapter
或HandlerInterceptor
接口的preHandle
和postHandle
方法,分别对响应请求前和响应请求后做自定义的一些操作。完整代码如下:
/**
* 全局请求拦截器
*/
@Component
public class GlobalRequestInterceptor extends HandlerInterceptorAdapter {
private Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 请求之前被调用
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String username;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//如果用户已登录,获取登录用户信息
if (authentication.getPrincipal() != null && authentication.getPrincipal() instanceof User) {
username = ((User) (authentication.getPrincipal())).getUsername();
} else {
username = authentication.getName();
}
logger.info("=====> User({}) request({}) start, params:{}", username, request.getRequestURI(), JSONObject.toJSONString(request.getParameterMap()));
return super.preHandle(request, response, handler);
}
/**
* 请求完成之后,如果需要渲染视图,则此操作在渲染视图之前
*
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
String username;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//如果用户已登录,获取登录用户信息
if (authentication.getPrincipal() != null && authentication.getPrincipal() instanceof User) {
username = ((User) (authentication.getPrincipal())).getUsername();
} else {
username = authentication.getName();
}
logger.info("=====> User({}) request({}) end, response status:{}", username, request.getRequestURI(), response.getStatus());
super.postHandle(request, response, handler, modelAndView);
}
}
2 注册拦截器
对上一步中自定义拦截器进行注册,通过自定义配置类实现WebMvcConfigurer
接口的方式实现。完整代码如下:
注意,在未开启
EnableWebMvc
注解的情况下,自定义拦截器和SpringMVC默认自动配置是同时生效的
//@EnableWebMvc //需要全面接管SpringBoot中的SpringMVC配置时开启此注解,开启后SpringMVC自动配置失效。
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 添加拦截器
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new GlobalRequestInterceptor());
}
}
3 模拟请求
对比登录前后日志打印区别,主要是用户信息。
3.1 未登录模拟
未登录前访问查询redis的请求,控制台打印信息如下,此时无登录用户,SpringBoot框架默认的用户信息为匿名用户,如下图:
这方面具体实现代码可参考之前的文章<<Spring Boot:Idea从零开始初始化后台项目>>。
3.2 登录后模拟
登录后重新执行查询redis的请求。控制台打印信息中包含了用户信息,如下图: