spring统一管理异常和访问日志

随着产品开发的深入,我们需要对用户的访问习惯进行分析,对各种异常情况都需要统一处理。为了避免代码的冗余以及模块的耦合,很自然想到了spring的切面原理。

切面,简而言之,就是将业务中相对独立的模块,例如日志、异常等作为一个处理点,统一管理并处理。这样做的好处是,以后的维护不需要大面积更改代码,提高模块之间的耦合度,代码会显得美观,可读性强,可移植性强。下面重点总结一下使用过程,具体如下:

1.首先应用spring切片,需要对应的jar包(org.aspectj

   可以直接应用jar包,也可以利用pom文件下载


2.配置注解扫描

  <!-- 扫描注解,扫描controller -->
   <context:component-scan base-package="zhitongits.controller,zhitongits.aop"/>

  或者直接指定需要扫描的实体

  1. <aop:aspectj-autoproxy proxy-target-class="true"/>  
  2.     <bean class="com.yusj.interceptor.LogAspect" />  

3.日志捕获和处理

  

 通过注解标记切面,并通过@Before("execution(* com.yusj.controller..*.*(..))")、 @After("execution(* com.yusj.controller..*.*(..))")、@Around("execution(* com.yusj.controller..*.*(..))")  来处理日志,处理日志很容易想到,如何取获取请求内容和结果的问题,方法如下

//获取request对象
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
//获取request中的请求参数
Map<String, String[]> map = request.getParameterMap();
//获取请求结果

Object result = pjp.proceed();

这样,你就可以随心所欲地处理日志了,入库、利用log4j写日志等等


4.异常的统一处理


通过实现ThrowsAdvice捕获所有抛出的异常,这样,不需要在代码中写过多的try... catch代码

public void afterThrowing(Method method, Object[] args, Object target,  Exception ex) throws Throwable  
    {  
        // 在后台中输出错误异常异常信息,通过log4j输出。  
        Logger log = Logger.getLogger(target.getClass());  
        System.out.println("Error happened in class: "+ target.getClass().getName() +";Error happened in method: " + method.getName());
        System.out.println("异常详情:" + ex.getMessage());  
        ex.printStackTrace();
  
        // 在这里判断异常,根据不同的异常返回错误。  
        if (ex.getClass().equals(DataAccessException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("数据库操作失败!");  
        } else if (ex.getClass().toString().equals( NullPointerException.class.toString()))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("调用了未经初始化的对象或者是不存在的对象!");  
        } else if (ex.getClass().equals(IOException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("IO异常!");  
        } else if (ex.getClass().equals(ClassNotFoundException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("指定的类不存在!");  
        } else if (ex.getClass().equals(ArithmeticException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("数学运算异常!");  
        } else if (ex.getClass().equals(ArrayIndexOutOfBoundsException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("数组下标越界!");  
        } else if (ex.getClass().equals(IllegalArgumentException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("方法的参数错误!");  
        } else if (ex.getClass().equals(ClassCastException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("类型强制转换错误!");  
        } else if (ex.getClass().equals(SecurityException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("违背安全原则异常!");  
        } else if (ex.getClass().equals(SQLException.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("操作数据库异常!");  
        } else if (ex.getClass().equals(NoSuchMethodError.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("方法末找到异常!");  
        } else if (ex.getClass().equals(InternalError.class))  
        {  
            ex.printStackTrace();  
            throw new BusinessException("Java虚拟机发生了内部错误");  
        } else  
        {  
            ex.printStackTrace();  
            throw new BusinessException("程序内部错误,操作失败!" + ex.getMessage());  
        }  
    }

这样很容易记录下所有的异常信息,包括发生异常的class、method等,并返回准确的异常信息;特别的如果只需要监听部分类文件抛出的异常,也可以通过配置文件指定package或bean来实现

猜你喜欢

转载自blog.csdn.net/yanyuegongzuoshi/article/details/51439691