SpringBoot的异常处理是不友好的,前端只会显示最基本的错误名称
后端控制台会报出具体的错误,那么我们如何告知前端具体的错误信息呢?
1:对全局异常进行处理
一个测试的Controller:
package org.dreamtech.springboot.exception; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ExceptionController { @RequestMapping("/test/exception") private Object test() { int i = 1 / 0; return "test"; } }
自定义一个异常处理类:
package org.dreamtech.springboot.exception; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice //类似的,有@ControllerAdvice public class CustomExceptionHandler { @ExceptionHandler(value = Exception.class) Object handleException(Exception e, HttpServletRequest request) { Map<String, Object> map = new HashMap<String, Object>(); map.put("code", 100); map.put("errMsg", e.toString()); map.put("url", request.getRequestURI()); return map; } }
更进一步,可以加入日志处理:
package org.dreamtech.springboot.exception; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice public class CustomExceptionHandler { private static final Logger LOG = LoggerFactory.getLogger(CustomExceptionHandler.class); @ExceptionHandler(value = Exception.class) Object handleException(Exception e, HttpServletRequest request) { LOG.error("url {},msg {}", request.getRequestURI(), e.toString()); Map<String, Object> map = new HashMap<String, Object>(); map.put("code", 100); map.put("errMsg", e.toString()); map.put("url", request.getRequestURI()); return map; } }
如果前端访问了测试URL,应该显示的内容是:
{"code":100,"errMsg":"java.lang.ArithmeticException: / by zero","url":"/test/exception"}
2.自定义异常处理
导入SpringBoot推荐的thymeleaf模板引擎:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
新建自定义异常类:
package org.dreamtech.springboot.exception; public class MyException extends RuntimeException { private static final long serialVersionUID = -1876094492594770999L; public MyException(String code, String msg) { super(); this.code = code; this.msg = msg; } private String code; private String msg; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
测试Controller:
package org.dreamtech.springboot.exception; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ExceptionController { @RequestMapping("/test/exception") private Object test() { throw new MyException("101", "error"); } }
异常处理类:
package org.dreamtech.springboot.exception; import javax.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView; @ControllerAdvice public class CustomExceptionHandler { @ExceptionHandler(value = MyException.class) Object handleException(MyException e, HttpServletRequest request) { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error.html"); modelAndView.addObject("msg", e.toString()); System.out.println(e.toString()); return modelAndView; } }
可以看出,我这里是返回了一个错误页面:error.html,当然也可以返回JSON,类似上面的@RestControllerAdvice
巧合的是,我运行SpringBoot之后发现所有错误页面都跳转到error.html,一开始以为是配置错误了
后来仔细测试后发现,SpringBoot默认将error.html作为同意异常处理页面了,哈哈