问答社区-统一异常处理、统一记录日志(AOP)
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的实现
###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)); } }
```