package cn.ximi.erp.web.common.interceptors;

import cn.ximi.core.common.utils.string.StringUtil;
import cn.ximi.erp.web.constant.Constants;
import cn.ximi.erp.web.base.UserContext;
import cn.ximi.manage.entity.SysResource;
import cn.ximi.manage.entity.SysUser;
import cn.ximi.manage.service.ResourceService;
import cn.ximi.manage.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Set; /**
* 登录拦截器
* (
* 实现应用之性能监控
* 拦截器是实现成单例的,因此不管用户请求多少次都只访问同一个拦截器实现,即线程不安全。
* 解决方案是:使用ThreadLocal,它是线程绑定的变量,提供线程局部变量(一个线程一个ThreadLocal,
* A线程的ThreadLocal只能看到A线程的ThreadLocal,不能看到B线程的ThreadLocal)。
* )
* Created by gmq on 2016/4/28.
*/
public class LoginInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class); // 统计应用性能
private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("StopWatch-StartTime"); @javax.annotation.Resource
private SysUserService sysUserService;
@Autowired
private ResourceService resourceService; private Set<String> excludeURIs; @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 设置起始时间
// 1、开始时间
long startTime = System.currentTimeMillis();
// 线程绑定变量(该数据只有当前请求的线程可见)
startTimeThreadLocal.set(startTime); String requestUri = request.getRequestURI();
UserContext loginUser = (UserContext) request.getSession().getAttribute(Constants.CURRENT_USER); if (excludeURIs.contains(requestUri)) { return true;
} else { // 判断是否已经登录
Subject subject = SecurityUtils.getSubject();
String userId = (String) subject.getPrincipal();
if (StringUtil.isNotEmpty(userId)) {
SysUser user = sysUserService.findByUsername(userId);
// menu菜单
Set<String> permissions = sysUserService.findPermissions(user.getUsername());
List<SysResource> menus = resourceService.findByMenus(permissions);
if (user != null) {
UserContext userContext = new UserContext(user.getId(), user.getOrganizationId(), user.getUsername(), user.getRoleIds(), user.getLocked(), user.getRealname(),
user.getSex(), user.getMobile(), user.getRoleNames(), menus,"/static/images/pixel-admin/avatar.png");
request.getSession().setAttribute(Constants.CURRENT_USER, userContext);
}
} UserContext loginInfo = (UserContext) request.getSession().getAttribute(Constants.CURRENT_USER);
if (loginInfo == null) {
response.sendRedirect(getBasePath(request) + "login.htm");
return false;
} return true;
} } @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 统计应用的性能
// 2、结束时间
long endTime = System.currentTimeMillis();
// 得到线程绑定的局部变量(开始时间)
long beginTime = startTimeThreadLocal.get();
// 3、消耗的时间
long consumeTime = endTime - beginTime;
// 此处认为处理时间超过500毫秒的请求为慢请求
if(consumeTime > 500) {
//TODO 记录到日志文件
logger.warn("监控==========================: " + String.format("%s consume %d millis", request.getRequestURI(), consumeTime));
}
} private boolean contains(Set<String> sets, String key) { boolean result = false;
if (sets != null && sets.size() > 0) {
for (String s : sets) {
if (s.indexOf(key) != -1) {
result = true;
break;
}
}
} return result;
} private String getBasePath(HttpServletRequest request) { int port = request.getServerPort();
return request.getScheme() + "://" + request.getServerName() + ((port == 80) ? "" : (":" + port)) + request.getContextPath() + "/";
} public Set<String> getExcludeURIs() {
return excludeURIs;
} public void setExcludeURIs(Set<String> excludeURIs) {
this.excludeURIs = excludeURIs;
}
}

spring拦截器 实现应用之性能监控的更多相关文章

  1. Spring 拦截器——HandlerInterceptor

    采用Spring拦截器的方式进行业务处理.HandlerInterceptor拦截器常见的用途有: 1.日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV(Page View)等. 2 ...

  2. spring 拦截器简介

    spring 拦截器简介 常见应用场景 1.日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV(Page View)等.2.权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直 ...

  3. Spring拦截器中通过request获取到该请求对应Controller中的method对象

    背景:项目使用Spring 3.1.0.RELEASE,从dao到Controller层全部是基于注解配置.我的需求是想在自定义的Spring拦截器中通过request获取到该请求对应于Control ...

  4. spring拦截器中修改响应消息头

    问题描述 前后端分离的项目,前端使用Vue,后端使用Spring MVC. 显然,需要解决浏览器跨域访问数据限制的问题,在此使用CROS协议解决. 由于该项目我在中期加入的,主要负责集成shiro框架 ...

  5. Spring 拦截器实现+后台原理(HandlerInterceptor)

    过滤器跟拦截器的区别 spring mvc的拦截器是只拦截controller而不拦截jsp,html 页面文件的.这就用到过滤器filter了,filter是在servlet前执行的,你也可以理解成 ...

  6. Spring拦截器和过滤器

    什么是拦截器 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对象,允许开发者 ...

  7. Spring 拦截器配置

    Spring interceptor拦截器配置 Spring mvc的拦截器是通过handlerinterceptor来实现的 实现方式: 1.自定义一个类实现Spring的handlerinterc ...

  8. spring拦截器的定义

    (一).拦截器的定义 1.为什么需要拦截器:在做身份认证或者是进行日志的记录时,我们需要通过拦截器达到我们的目的 2.什么事拦截器:在AOP(Aspect-Oriented Programming)中 ...

  9. Spring 拦截器实现事物

    Spring+Hibernate的实质:就是把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactio ...

随机推荐

  1. 【C#】toString("Format") 格式化

    1..ToString("P");//得到小数点后2位的百分比,自动 加上%号;//9512.35% 这个比较厉害! furenjun yoolonet

  2. redis配置文件详解

    基于redis2.4版本的配置文件. # 注意单位问题:当需要设置内存大小的时候,可以使用类似1k.5GB.4M这样的常见格式:## 1k => 1000 bytes# 1kb => 10 ...

  3. 基于ArcGIS API for Javascript的地图编辑工具

    最近工作上需要用ArcGIS API for Javascript来开发一个浏览器上使用的地图编辑工具,分享一下一些相关的开发经验. 我开发的地图编辑工具是根据ESRI提供的例子修改而来的,参考的例子 ...

  4. zookeeper原理解析-客户端与服务器端交互

    Zookeeper集群中server数量总是确定的,所以集群中的server交互采用比较可靠的bio长连接模型:不同于集群中sever间交互zookeeper客户端其实数量是未知的,为了提高zooke ...

  5. json基础

    1 xml缺点 用xml表示一个对象,数据存储效率低 <person> <firstName>Morra<firstName> <lastName>Do ...

  6. C#之索引器

    实际中不使用这个东西,只做了解 using System; using System.Collections.Generic; using System.Linq; using System.Text ...

  7. 【原创】PageAdminCMS 前台SQL注入漏洞(2)

    之前根据公司的要求找了几个web程序的漏洞提交CNVVD,发现漏洞提交上去两个月了,CNVVD却没有任何回应,我提交的这几个漏洞却悄悄的修补掉了. 文章作者:rebeyond 受影响版本:V3.0 漏 ...

  8. 基于linux(centos)的svn环境搭建

    1. 安装svn yum intall subversion 2. 查看安装位置 rpm -ql subversion 3. 检验svn是否安装成功,查看帮助 svn --help , 看到下图表示成 ...

  9. Comet技术

    1.Comet是什么? 维基百科: Comet是一种用于web的推送技术,能使服务器实时地将更新的信息传送到客户端,而无须客户端发出请求,目前有两种实现方式,长轮询和iframe流. 说白了就是web ...

  10. 2016百度之星 初赛2A ABEF

    只做了1001 1002 1005 1006.剩下2题可能以后补? http://acm.hdu.edu.cn/search.php?field=problem&key=2016%22%B0% ...