个人博客项目--异常与日志处理

异常处理

在平时访问页面时,可能会因为各种问题导致无法访问,如果页面出现白页,对于访问用户并不友好,那么是否可以将页面访问错误时,提高页面可读性呢?
答案是肯定的。我们可以先定制一个error,404,500三个html文件,然后在后端handler包下新建ControllerExceptionHandler类

@ControllerAdvice
public class ControllerExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @ExceptionHandler
    public ModelAndView exceptionHander(HttpServletRequest request, Exception e) throws Exception {
        logger.error("Request URL: {}, Exception: {}",request.getRequestURI(),e.getMessage());

        if(AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null){
            throw e;
        }

        ModelAndView mv = new ModelAndView();
        mv.addObject("url",request.getRequestURI());
        mv.addObject("exception",e.getMessage());
        mv.setViewName("error/error");

        return mv;
    }
}

注意这里的引用

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法加一些逻辑处理。最常用的就是异常处理。

if(AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null){
            throw e;
        }

在已有状态码下,会根据错误状态码进行后续操作

@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{
    public NotFoundException() {

    }

    public NotFoundException(String message) {
        super(message);
    }

    public NotFoundException(String message, Throwable cause) {
        super(message, cause);
    }
}

这里是先继承一个RuntimeException,再加上@ResponseStatus(HttpStatus.NOT_FOUND),表明这是一个404状态码。当博客为空时,跳转至404界面。
在这里插入图片描述

日志处理

1.日志记录内容

请求url
访问者ip
调用方法classMethod
参数args
返回内容

2.日志记录类

@Aspect
@Component
public class LogAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    //@Pointcut表明这是一个切面,execution()里规定这个切面拦截哪些内容 *(..)任何参数的所有方法
    @Pointcut("execution(* com.lh.web.*.*(..))")
    public void log(){

    }

    @Before("log()")
    public void doBefore(){
        logger.info("----before-----");
    }

    @After("log()")
    public void doAfter(){
        logger.info("----after-----");
    }

    //记录返回内容
    //returning = "res" 返回的是什么东西
    @AfterReturning(returning = "res",pointcut = "log()")
    public void doAfterReturn(Object res){
        logger.info("返回结果:{}" ,res);
    }
}

切面注解需要加上@Aspect @Component
在controller里进行测试
在这里插入图片描述
启动结果
在这里插入图片描述
当要想获得自己想要记录的东西时,在日志记录类中定义一个内部类
在这里插入图片描述
对代码进行扩充

//url和ip须通过http获取
    //类名和方法名通过JoinPoint获取
    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String url = request.getRequestURI();
        String ip = request.getRemoteAddr();
        //getDeclaringTypeName()类名  getName()方法名
        String classMethod = joinPoint.getSignature().getDeclaringTypeName() +
                "." + joinPoint.getSignature().getName();
        //拿请求参数
        Object[] args = joinPoint.getArgs();
        RequestLog requestLog = new RequestLog(url,ip,classMethod,args);

        logger.info("----before-----"+"请求内容:{}",requestLog);
    }

在这里插入图片描述
启动后输入
在这里插入图片描述
得到结果
在这里插入图片描述
如果输入localhost,则会出现
ip=0:0:0:0:0:0:0:1

知识小结

JoinPoint

JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象.

常用api

方法名功能
Signature getSignature();获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息
joinPoint.getSignature().getDeclaringTypeName()获取类名
joinPoint.getSignature().getName()获取方法名
Object[] getArgs();获取传入目标方法的参数对象
Object getTarget();获取被代理的对象
Object getThis();获取代理对象

url和ip须通过http获取

在一个方法里面如果想获取请求信息,需要从请求上下文获取request,或者在参数列表使用HttpServletRequest request

步骤

  1. 在方法中获取请求上下文
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
  1. 获取请求request
HttpServletRequest request = attributes.getRequest();
  1. 获取参数
String url = request.getRequestURI();
String ip = request.getRemoteAddr();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值