• 使用aop实现统一记录请求方法返回值日志及统一异常处理


      接到将请求返回值写入到日志方便查问题需求,首先考虑的是用拦截器实现,无奈拦截器postHandle方法里获取不到返回值就此作罢。继续寻找新的方法,网上查询一番找到一个便捷的方法,利用log4j2,在log4j2.xml配置文件里添加如下配置:
    <AsyncLogger name="org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor" level="debug" additivity="false">
                <AppenderRef ref="Console"/>
                <AppenderRef ref="allLog"/>
     </AsyncLogger>

    这样就能将方法返回值记录到日志里了,但是这样记录的日志和系统其它日志不一样不方便查看,此方法pass。最后只能用spring aop来实现此功能了,步骤如下:

    1、引入aop依赖的jar包
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.0.0.RELEASE</version>
    </dependency>
     
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.0.0.RELEASE</version>
    </dependency>
    2、配置xml文件
         引入aop命名空间  
    xmlns:aop="http://www.springframework.org/schema/aop"
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    <!-- 开启自动切面代理 -->
    <aop:aspectj-autoproxy/>
    <!-- 使用annotation 自动注册bean -->
    <context:component-scan base-package="com.zzz.dealer.**"/>

    3、编写切面类

    @Aspect  //指定当前类为切面类
    @Component //把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>
    public class MethodLogAndExceptionAop {
     
        @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
        public Object around(ProceedingJoinPoint jp) throws Throwable {
            String targetName = jp.getTarget().getClass().getName();
            String methodName = jp.getSignature().getName();
            Object[] arguments = jp.getArgs();
            Object[] args = new Object[arguments.length];
            for (int i = 0; i < arguments.length; i++) {
                if (arguments[i] instanceof ServletRequest || arguments[i] instanceof ServletResponse || arguments[i] instanceof MultipartFile) { 
                  //ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
                  //ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
                    continue;
                }
                args[i] = arguments[i];
            }
            Object result = null;
            try {
                //StopWatch 计时
                StopWatch clock = new StopWatch();
                clock.start();
                result = jp.proceed();
                clock.stop();
                long executeTime = clock.getTime();
                LoggerUtil.info(targetName, methodName, "调用Controller方法返回结果", result, executeTime, args);
            } catch (Exception exception) {
                LoggerUtil.error(targetName, methodName, "统一异常处理", exception, args);
                ResultVo resultVo = new ResultVo(false);
                // 为安全起见,只有业务异常我们对前端可见,否则统一归为系统异常
                if (exception instanceof BusinessException) {
                    resultVo.setResultAndCode(false, ((BusinessException) exception).getErrorCode(), ((BusinessException) exception).getErrorMessage());
                } else {
                    resultVo.setResultAndCode(false, ErrorCode.DEALER_ERR_100000.getCode(), "系统异常,请联系管理员");
                }
                result = resultVo;
            }
            return result;
        }
    }

    系统本来的统一异常处理是通过实现HandlerExceptionResolver接口自定义异常处理,实现这个aop后发现,在这里也可以实现系统异常统一处理,于是就把自定义异常处理给干掉了。一举两得。

     
     
  • 相关阅读:
    上传——断点续传之实践篇(1)
    上传——断点续传之实践篇
    上传——断点续传之理论篇
    overrides报错:TypeError: Highway.forward: `input` must be present
    InvalidVersionSpecError: Invalid version spec: =2.7
    qt.qpa.plugin: Could not find the Qt platform plugin "windows" in "" This application failed to start because no Qt platform plugin could be initialized.
    匈牙利算法解决两个坐标列表匹配的问题
    pytorch-summary 针对DenseNet生成摘要报错: AttributeError: 'list' object has no attribute 'size'
    使用sklearn的pca模块fit数据报错“ValueError: array must not contain infs or NaNs”
    Nginx+rtmp构建时,localhost/stat显示为空白
  • 原文地址:https://www.cnblogs.com/zcz527/p/9300646.html
Copyright © 2020-2023  润新知