使用Spring MVC中的Interceptor和slf4j中的MDC实现日志归类标记

*

1.Interceptor的介绍

*
SpringMVC 中Interceptor 拦截器的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行用户登陆、日志记录、性能评估、权限控制等。
SpringMVC 中的Interceptor拦截请求是通过HandlerInterceptor来实现的。SpringMVC中实现类的可以通过实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter类。
Interceptor具体接口定义如下(来至源码):

package org.springframework.web.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface HandlerInterceptor {

    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception;

    void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception;

    void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception;

}

注:以上部分内容摘要至SpringMVC 中的Interceptor 拦截器,更多关于Interceptor的介绍可以参考SpringMVC 中的Interceptor 拦截器

2.slf4j MDC的介绍

MDC ( Mapped Diagnostic Contexts ),其目的是为了便于我们诊断线上问题而出现的方法工具类。它的好处是可以实现同一请求的日志追踪功能,比如如果你的系统已经上线,突然有一天老板说我们增加一些用户数据到日志里分析一下。如果没有MDC我猜此时此刻你应该处于雪崩状态。MDC恰到好处的让你能够实现在日志上突如其来的一些需求。

MDC 对外提供的接口:

public class MDC {
  //在当前线程中插入一个键值对,键不能为空,值只有当子类实现允许时才能为空
  public static void put(String key, String val);

  //通过键获取对应的context值
  public static String get(String key);

  //通过键删除context值
  public static void remove(String key);

  //清除所有的context
  public static void clear();
}

注:slf4j MDC的详细介绍可以参考Slf4j MDC 使用和 基于 Logback 的实现分析

3.应用实例

(1)首先新建Interceptor的实例类

package com.test.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.MDC;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.test.User;//User类我这里没有粘贴出来,可以自己建

public class Slf4jMDCInterceptor extends HandlerInterceptorAdapter {

    /** 会话ID */
    private final static String KEY_SESSION_ID = "session_Id";
    /** 用户ID */
    private final static String KEY_USER_ID = "user_id";
    /** 用户姓名 */
    private final static String KEY_USER_NAME = "user_name";

    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        MDC.clear();
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        // 放SessionId
        String sessionId = request.getSession().getId();
        MDC.put(KEY_SESSION_ID, sessionId);
        // 放入用户id和姓名
        User currentUser = request.getSession().getAttribute("User");
        if (currentUser != null) {
            MDC.put(KEY_USER_ID, currentUser.getUserId());
            MDC.put(KEY_USER_NAME, currentUser.getUserName());
        }
        return true;
    }

}

(2)然后配置Interceptor
文件命名为:web-mvc-interceptor.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**/*.html" />
            <mvc:mapping path="/**/*.json" />
            <mvc:mapping path="/**/*.xml" />
            <bean class="com.pccc.poup.loanmall.interceptor.Slf4jMDCInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors> 
</beans>

4.总结

其实应用起来代码不是很多,关键是MDC能够通过put()方法加入需要的日志分类标志,以上内容是我通过整合知识和实践得来的,如果有不足之请留言。

猜你喜欢

转载自blog.csdn.net/sinat_37729104/article/details/76026621