6

异常这样处理,对用户更友好

 3 years ago
source link: https://segmentfault.com/a/1190000040422835
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

异常这样处理,对用户更友好

在项目中,经常有一些业务需要抛出异常,但是如果后台直接抛出throw new Exception的话,前端就很难看,对用户提示也不够友好,今天我们就来解决这个问题。

先建立一个工程,模拟将异常抛出。如下:

@RestController
public class DemoController {

    @GetMapping("test")
    public String test() throws Exception{
        if(true){
            throw new Exception("error");
        }
        return "ok";
    }
}

前端用浏览器请求下,看看界面什么样子:

@ControllerAdvice@ExceptionHandler

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
        @ExceptionHandler
        @ResponseBody
        @ResponseStatus(HttpStatus.OK)
        public ResultDto globalException(HttpServletResponse response, Exception ex){
                log.info("ExceptionHandler...");
                log.info("错误代码:"  + response.getStatus());
                ResultDto resultDto = new ResultDto();
                resultDto.setCode(0);
                resultDto.setMsg(ex.getMessage());
                resultDto.setData(null);
                return resultDto;
        }
}

定义个返回到前端的通用结构体

@Data
public class ResultDto {
    //请求结果0表示失败,其他是成功
    private int code;
    //失败的消息
    private String msg;
    //实际返回到前端的数据
    private Object data;
}

然后我们写一个controller模拟抛出异常

@GetMapping("test1")
public String test1() throws Exception{
    if(true){
        throw new NullPointerException("NullPointerException");
    }
    return "ok";
}

@GetMapping("test2")
public String test2() throws Exception{
    if(true){
        throw new RuntimeException("RuntimeException");
    }
    return "ok";
}

@GetMapping("test3")
public String test3() throws MyException{
    if(true){
        //不能直接拋Exception 否则不能捕获,可以自己定义一个异常
        throw new MyException("MyException");
    }
    return "ok";
}

请求下,看看postman返回的是什么

{
    "code": 0,
    "msg": "NullPointerException",
    "data": null
}

在实际业务中我们通常返回自定义的异常,那么我接下来定义一个自己的异常,并对自己的异常进行单独的处理:

public class MyException extends Exception {
    public MyException() {
        super();
    }

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

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

    public MyException(Throwable cause) {
        super(cause);
    }

    protected MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

然后在GlobalExceptionHandler中增加对MyException的处理:

@ExceptionHandler(MyException.class)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public ResultDto myException(HttpServletResponse response, MyException ex){
        log.info("MyExceptionHandler...");
        log.info("错误代码:"  + response.getStatus());
        ResultDto resultDto = new ResultDto();
        resultDto.setCode(0);
        resultDto.setMsg(ex.getMessage());
        resultDto.setData(null);
        return resultDto;
}

请求http://localhost:8080/test3看看输出到前端的是什么

{
    "code": 0,
    "msg": "MyException",
    "data": null
}

这里其实看不出来到底走的是myException还是globalException但是如果你看后台日志输出就能清晰的看到。因此我们在对多种异常进行处理的时候springboot会优先处理子类异常。

更多java原创阅读:https://javawu.com


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK