在项目中,经常有一些业务需要抛出异常,但是如果后台直接抛出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