1.统一异常处理

错误页面放到template下error包中

@ControllerAdvice

  • 用于修饰类,表示该类是Controller的全局配置类
  • 在此类中,可以对Controller进行如下三种全局配置:
    异常处理方案、绑定数据方案、绑定参数方案
    @ExceptionHandler
  • 用于修饰方法,该方***在Controller出现异常后被调用,用于处理捕获到的异常
/**
 * @ControllerAdvice表示该类是Controller的全局配置类 可对Controller进行异常处理、绑定数据、绑定参数配置
 */
@ControllerAdvice(annotations = Controller.class)
public class ExceptionAdvice {

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

    @ExceptionHandler({Exception.class})
    public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.error("服务器发生异常:" + e.getMessage());
        for (StackTraceElement element : e.getStackTrace()) {
            logger.error(element.toString());
        }

        //判断是否异步请求
        String xRequestedWith = request.getHeader("x-requested-with");
        if ("XMLHttpRequest".equals(xRequestedWith)) {
            //是异步请求
            response.setContentType("application/plain;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write(CommunityUtil.getJSONString(1, "服务器异常!"));
        } else {
            //非异步请求
            response.sendRedirect(request.getContextPath() + "/error");
        }

    }


}

2.统一记录日志

AOP的概念,即面向切面编程
AOP说明
AOP术语
##AOP的实现
###AspectJ

  • AspectJ是语言级的实现,它拓展了Java语言,定义了AOP语法
  • AspectJ在编译期织入代码,它有一个专门的编译器,用来生成遵守Java字节码规范的class文件

Spring AOP

  • 使用纯Java实现,不需要专门的编译过程,也不需要特殊的类装载器
  • 在运行时通过代理方法织入代码,只支持方法类型的连接点
  • 支持对AspectJ的集成

@Before: 前置通知, 在方法执行之前执行
@After: 后置通知, 在方法执行之后执行 。
@AfterRunning: 返回通知, 在方法返回结果之后执行
@AfterThrowing: 异常通知, 在方法抛出异常之后
@Around: 环绕通知, 围绕着方法执行

实现统一记录日志
1、建立切面类,增加@aspect注解
2、新建切入点@Pointcut("execution(* com.gpnu.community.service..(..))")
3、增加@Before注解,在方法执行前通知
4、通过RequestContextHolder获取request对象

  • RequestContextHolder顾名思义,持有上下文的Request容器.使用是很简单的

  • RequestContextHolder.getRequestAttributes();
    5、从request对象中获取所需信息,添加到log中

    @Component
    @Aspect
    public class ServiceLogAspect {
      private static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class);
    
      @Pointcut("execution(* com.gpnu.community.service.*.*(..))")
      public void pointcut() {
      }
    
      @Before("pointcut()")
      public void before(JoinPoint joinPoint) {
          ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
          if (attributes == null){
              return;
          }
          HttpServletRequest request = attributes.getRequest();
          String ip = request.getRemoteHost();
          String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
          String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
          logger.info(String.format("用户[%s],在[%s],访问了[%s]", ip, now, target));
    
      }
    }
    

```