文档章节

spring boot 拦截器 或 Spring AOP 方式记录请求日志

whitelover
 whitelover
发布于 2016/07/01 19:03
字数 785
阅读 12418
收藏 10


选择使用拦截器实现,在实现中遇到两个个问题:

a. POST请求 @RequestBody 传的参数不知怎么获取?

b. 返回结果如何获取?

c.拦截器中service 无法注入;(已解决)

不知道有没有人遇到这种情况,拦截器没有解决上述问题,后来使用 spring AOP 处理。 

《一》拦截器方式

@Configuration
public class OptPermissionHandlerInterceptor extends HandlerInterceptorAdapter {

    private Logger logger = LoggerFactory.getLogger(OptPermissionHandlerInterceptor.class);

    @Autowired
    private OptLogService optLogService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    } 

    @SuppressWarnings("rawtypes")
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
        try {
            if (handler instanceof HandlerMethod) {
              
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                String beanName = handlerMethod.getBean().getClass().toString();
                String methodName = handlerMethod.getMethod().getName();
                String uri = request.getRequestURI();
                String remoteAddr = getIpAddr(request);
                String sessionId = request.getSession().getId();
                String user = (String) request.getSession().getAttribute(Constant.USER);
                String method = request.getMethod();
                System.out.println("请求方式为="+method);
                Map params = null;
                if("POST".equals(method)){
                    //........
                }else{
                    params = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
                }
                // 取不到值
                MethodParameter[] mps = ((HandlerMethod) handler).getMethodParameters();
                for(MethodParameter mp : mps){
                    System.out.println(mp.getParameterName() + " --  "+ mp.getParameterType());
                }
                // 取不到值
                Map<String, String[]> params2 = request.getParameterMap();   

                 
               //拦截器中optLogService 没有注入成功时,重新获取;
               if (optLogService == null) {
                   System.out.println("optLogService is null !!!");
                    BeanFactory factory =
                            WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());

                    optLogService = (OptLogService) factory.getBean("optLogService");
                    
                }

                optLogService.saveOptLog(.....);
            }
        } catch (Exception e) {
            logger.error("用户操作日志记录异常", e);
        }
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {

    }


    //获取客户端IP
    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

 

《二》Spring AOP方式(面向切面)

1.在pom.xml 中引入spring aop 依赖

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

2.在 application.properties 文件中添加:

spring.aop.auto=true
spring.aop.proxy-target-class=false

3.实现切面

@Aspect
@Component
public class WebRequestLogAspect {

    private static Logger logger = LoggerFactory.getLogger(WebRequestLogAspect.class);

    private ThreadLocal<OperatorLog> tlocal = new ThreadLocal<OperatorLog>();

    @Autowired
    private OptLogService optLogService;

    @Pointcut("execution(public * com.whitelover.test..*.create*(..))")
    public void webRequestLog() {}

    // @Order(5)
    @Before("webRequestLog()")
    public void doBefore(JoinPoint joinPoint) {
        try {

            long beginTime = System.currentTimeMillis();

            // 接收到请求,记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String beanName = joinPoint.getSignature().getDeclaringTypeName();
            String methodName = joinPoint.getSignature().getName();
            String uri = request.getRequestURI();
            String remoteAddr = getIpAddr(request);
            String sessionId = request.getSession().getId();
            String user = (String) request.getSession().getAttribute("user");
            String method = request.getMethod();
            String params = "";
            if ("POST".equals(method)) {
                Object[] paramsArray = joinPoint.getArgs();
                params = argsArrayToString(paramsArray);
            } else {
                Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
                params = paramsMap.toString();
            }

            logger.debug("uri=" + uri + "; beanName=" + beanName + "; remoteAddr=" + remoteAddr + "; user=" + user
                    + "; methodName=" + methodName + "; params=" + params);

            OperatorLog optLog = new OperatorLog();
            optLog.setBeanName(beanName);
            optLog.setCurUser(user);
            optLog.setMethodName(methodName);
            optLog.setParams(params != null ? params.toString() : "");
            optLog.setRemoteAddr(remoteAddr);
            optLog.setSessionId(sessionId);
            optLog.setUri(uri);
            optLog.setRequestTime(beginTime);
            tlocal.set(optLog);

        } catch (Exception e) {
            logger.error("***操作请求日志记录失败doBefore()***", e);
        }
    }

    // @Order(5)
    @AfterReturning(returning = "result", pointcut = "webRequestLog()")
    public void doAfterReturning(Object result) {
        try {
            // 处理完请求,返回内容
            OperatorLog optLog = tlocal.get();
            optLog.setResult(result.toString());
            long beginTime = optLog.getRequestTime();
            long requestTime = (System.currentTimeMillis() - beginTime) / 1000;
            optLog.setRequestTime(requestTime);

            System.out.println("请求耗时:" + optLog.getRequestTime() + optLog.getUri() + "   **  " + optLog.getParams() + " ** "
                    + optLog.getMethodName());
            System.out.println("RESPONSE : " + result);

            optLogService.saveLog(optLog);
        } catch (Exception e) {
            logger.error("***操作请求日志记录失败doAfterReturning()***", e);
        }
    }


    /**
     * 获取登录用户远程主机ip地址
     * 
     * @param request
     * @return
     */
    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 请求参数拼装
     * 
     * @param paramsArray
     * @return
     */
    private String argsArrayToString(Object[] paramsArray) {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0) {
            for (int i = 0; i < paramsArray.length; i++) {
                Object jsonObj = JSON.toJSON(paramsArray[i]);
                params += jsonObj.toString() + " ";
            }
        }
        return params.trim();
    }

}

spring aop参考网站:

http://blog.didispace.com/springbootaoplog/

@PointCut 表达式参考网站:

http://www.cnblogs.com/lic309/p/4079194.html

 

© 著作权归作者所有

whitelover
粉丝 13
博文 26
码字总数 10236
作品 0
私信 提问
加载中

评论(2)

whitelover
whitelover 博主

引用来自“哼哈三将”的评论

你这种AOP的方式只是记录的URL 参数 如果现在有一个POST请求入参为JSON格式 你这就不行了!
(二)Spring AOP方式 中提到的就是post请求,为什么参数为json就不行了,json 不能当作一个string 参数对待吗?
哼哈三将
哼哈三将
你这种AOP的方式只是记录的URL 参数 如果现在有一个POST请求入参为JSON格式 你这就不行了!
在Spring-Boot中实现通用Auth认证的几种方式

前言 最近一直被无尽的业务需求淹没,没时间喘息,终于接到一个能让我突破代码舒适区的活儿,解决它的过程非常曲折,一度让我怀疑人生,不过收获也很大,代码方面不明显,但感觉自己抹掉了 ...

枕边书
2018/07/17
0
0
Spring AOP 日志拦截器的事务管理

如果要在方法执行前或后或抛出异常后加上一个自己的拦截器,或者一个环绕拦截器,在拦截器中执行一些操作,比如执行一些数据库操作,记录一些信 息,这些操作通过调用一个服务类的方法来执行...

哲别0
2018/05/18
466
0
spring boot 集成shiro ,使用aspect记录日志不生效

现在我用了spring boot shiro 做我权限控制,用spring boot aspect来做我的日志记录,拦截的是controller层。但是现在我的shiro配置没有什么问题,权限可以控制。但是我用aspect记录日志的地...

王晓哲
2018/08/13
1K
1
220.详细整理学习spring boot

1.springboot是什么? 有什么用? 1.1 是什么 一个整合常用第三方框架,简化xml配置,完全采用注解形式,内置tomcat容器,帮助开发者快速实现项目搭建,spring boot 的web组件默认集成的是spr...

Lucky_Me
04/23
130
1
SpringBoot | 第二十四章:日志管理之AOP统一日志

前言 上一章节,介绍了目前开发中常见的及日志框架的整合知识。在很多时候,我们在开发一个系统时,不管出于何种考虑,比如是审计要求,或者防抵赖,还是保留操作痕迹的角度,一般都会有个全...

oKong
2018/08/24
1K
4

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部