zoukankan      html  css  js  c++  java
  • spring拦截器 实现应用之性能监控

    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;
        }
    }
  • 相关阅读:
    微信小程序授权获取用户详细信息openid
    微信开发之微信网页授权 完整示例
    linux 安装MySql 5.7.20 操作步骤【亲测】
    CentOS7下rabbitmq的详细安装教程
    Makefile:248: /usr/local/otp_src_18.1/make/x86_64-unknown-linux-gnu/otp_ded.mk: No such file
    Calendar的add()方法介绍
    怎样梳理属于自己的项目管理套路?
    项目经理必备9大获得领导支持秘技
    为什么绝大多数项目经理在不断救火?
    Java IO流学习总结
  • 原文地址:https://www.cnblogs.com/gmq-sh/p/6135220.html
Copyright © 2011-2022 走看看