【JAVA笔记】记一次HandlerInterceptor处理器拦截优化,解决preHandle()执行多次的问题

本文介绍了一个关于SpringMVC拦截器preHandle方法在高并发场景下导致的性能问题,通过过滤静态资源请求,有效降低了服务器和数据库的压力。

1.简介

preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进行调用。

SpringMVC中的Interceptor拦截器是链式的,可以同时存在多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行,而且所有的Interceptor中的preHandle方法都会在Controller方法调用之前调用。

(SpringMVC的这种Interceptor链式结构也是可以进行中断的,这种中断方式是令preHandle的返回值为false,当preHandle的返回值为false的时候整个请求就结束了。)

重写preHandle方法,在请求发生前执行。

 

2.问题

我们先来看看尼特社区的原始代码:

@Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 //设置广告
 for (AdPosEnum adPos : AdPosEnum.values()) {
 request.getServletContext().setAttribute(adPos.name(), adService.list(adPos.name()));
 }

 Cookie[] cookies = request.getCookies();
 if(cookies!=null&&cookies.length!=0){
 for (Cookie cookie : cookies) {
 if(cookie.getName().equals("token")){
 String token=cookie.getValue();
 UserExample userExample = new UserExample();
 userExample.createCriteria()
 .andTokenEqualTo(token);
 List<User> users = userMapper.selectByExample(userExample);
 if(users.size()!=0){
 User user = users.get(0);
 UserAccountExample userAccountExample = new UserAccountExample();
 userAccountExample.createCriteria().andUserIdEqualTo(user.getId());
 List<UserAccount> userAccounts = userAccountMapper.selectByExample(userAccountExample);
 UserAccount userAccount = userAccounts.get(0);
 request.getSession().setAttribute("user",user);
 request.getSession().setAttribute("userAccount",userAccount);
 Long unreadCount = notificationService.unreadCount(users.get(0).getId());
 request.getSession().setAttribute("unreadCount", unreadCount);
 System.out.println("用户组ID:"+userAccount.getGroupId());
 }
 break;
 }
 }
 }
 return true;
 }

我们在调试中,打印登录用户的用户组ID,发现用户每次访问一个页面,preHandle()方法都会执行24次之多。在大访问量下,这对服务器和数据库都会造成极大的压力,从而影响到性能。

 

3.解决方法

我们发现拦截器会对页面用到的外部CSS,js,图片文件等静态资源也会进行拦截,所以我们只需要过滤掉队静态资源的拦截即可。我们在preHandle()方法的最前部加入以下一行代码:

if (handler instanceof ResourceHttpRequestHandler)
 return true;

再调试一次,发现只打印一次了。问题解决!

原文地址:https://niter.cn/p/100

 

欢迎访问我的开源社区:https://niter.cn/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值