Springboot教程(六)——异常处理

拦截异常

在Spring Boot中,我们可以将异常统一放在全局处理类来处理,创建一个全局异常处理类需要用到@ControllerAdvice和@ExceptionHandler注解。

@ControllerAdvice类似一个增强版的@Controller,用于标注类,表示该类声明了整个项目的全局资源

@ExceptionHandler类似catch语句,标注一个方法,用于处理异常。而这个方法可以有返回值,类似@Controller的返回值

@ExceptionHandler可以传入一个参数,为异常类的Class对象


接下来举个例子:

创建一个exception包,在这个包下面写入一个异常处理类:

package com.example.c0101.exception

import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody

@ControllerAdvice
class GlobalExceptionHandle {

    @ExceptionHandler(NullPointerException::class)
    @ResponseBody
    fun handler(): String{
        return "参数不能为空"
    }

}

这表示,当遇到空指针异常时,向前端发送消息“参数不能为空”

接下来创建一个controller包。在这个包下面写一个控制器类:

package com.example.c0101.controller

import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class TestController {

    @RequestMapping("/index")
    fun index(name: String): String{
        return "您的用户名是$name"
    }

}

在/index的URI下,用户需要传入一个name参数,如果用户没有传入,则会触发空指针异常,调用我们之前写的异常处理类

我们使用postman测试一下:

可以看到,如果我们不传入name参数,则会调用异常处理类,并返回“参数不能为空” 


获取异常日志

我们可以使用slf4j打印异常日志:

log.error("参数为空", e)

这里面,log.error可以接受两个参数,第一个是提示字符串,第二个是异常对象


修改异常处理类如下:

package com.example.c0101.exception

import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody

@ControllerAdvice
class GlobalExceptionHandle {

    companion object{
        val log = LoggerFactory.getLogger(GlobalExceptionHandle::class.java)
    }

    @ExceptionHandler(NullPointerException::class)
    @ResponseBody
    fun handler(e: NullPointerException): String{
        log.error("参数为空", e)
        return "参数不能为空"
    }

}

这样我们就可以在出现异常时,打印异常日志了。用postman不传入参数,发现控制台输出:

说明我们成功的在日志中输出了错误信息 

修改异常状态下的响应码

我们可以通过@ResponseStatus注解设置响应码,如:

@ResponseStatus(HttpStatus.BAD_REQUEST)

修改异常处理类,使其能够在出现空指针异常时,返回400(Bad Request)状态码:

package com.example.c0101.exception

import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.bind.annotation.ResponseStatus

@ControllerAdvice
class GlobalExceptionHandle {

    companion object{
        val log = LoggerFactory.getLogger(GlobalExceptionHandle::class.java)
    }

    @ExceptionHandler(NullPointerException::class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    fun handler(e: NullPointerException): String{
        log.error("参数为空", e)
        return "参数不能为空"
    }

}

用postman不加参数,测试一下:

可以看到,服务器最终返回了400状态码

只拦截某个包下发生的异常

我们可以通过@ControllerAdvice的默认属性或basePackages属性只拦截某个包下发生的异常:

@ControllerAdvice("com.example.c0101.controller")
@ControllerAdvice(basePackages = ["com.example.c0101.controller"])

只拦截被某个注解标注的类发生的异常

我们可以通过@ControllerAdvice的annotations属性只拦截某个注解标注的类发生的异常:

@ControllerAdvice(annotations = [RestController::class])

拦截自定义异常

我们可以在exception包下自定义异常,并使用拦截普通异常的方法拦截自定义异常:

package com.example.c0101.exception

class MyException(msg: String) : Exception(msg)

在异常处理类里设置要拦截的异常:

@ExceptionHandler(MyException::class)
@ResponseBody
fun handler(e: MyException): String{
    log.error("自定义异常", e)
    return "出现自定义异常"
}

这样就可以拦截自定义异常了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值