SpringBoot全局异常处理
SpringBoot异常处理是指当controller中方法在执行过程中如果出现异常,我们应该如何处理异常。
传统方式开发的异常处理
对java定义的异常的处理
在controller中产生异常
@Controller
@RequestMapping("user")
public class DemoController {
@RequestMapping("login")
public String login(){
Integer num = 10/0;
return "index";
}
}
当访问index网址时,会出现
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Sep 15 20:07:50 CST 2021
There was an unexpected error (type=Internal Server Error, status=500).
可以在controller中直接处理这个异常
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("index")
public String index(){
try {
Integer num = 10/0;
return "index";
} catch (Exception e) {
e.printStackTrace();
return "500";
}
}
}
但是如果多个controller中都存在异常,在controller中直接处理异常就会降低工作效率。在springboot中可以创建一个实现了HandlerExceptionResolver接口的全局异常处理类,解决这个问题。(实现方法见代码注释)
@Component
public class GlobalExceptionResolve implements HandlerExceptionResolver {
//resolveExcpetion: 当控制器中任意一个方法出现异常时,如果该控制器的方法没有自己异常处理(try...catch),则会进入当前方法
//注意:在异常处理这个方法中 完成自定义异常处理
//参数1: request 当前请求对象
//参数2: response 当前请求对应响应对象
//参数3: 当前出现错误的方法对象
//参数4: 出现异常的异常对象
//返回值: modelAndview 模型和视图
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
System.out.println("这是全局异常...");
System.out.println("当前异常为:" + e);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("500");
return modelAndView;
}
}
再次访问时,如果出现异常,就会直接访问500页面了。
对自定义异常的处理
自定义异常
public class UserNotFoundException extends RuntimeException{
public UserNotFoundException(String message) {
super(message);
}
}
controller中抛出异常
@RequestMapping("login")
public String login(String username,String password){
log.debug("username:{},password:{}",username,password);
if ("zhangsan".equals(username) && "123".equals(password)){
return "index";
}else{
throw new UserNotFoundException("用户名或密码输入错误");
}
}
针对不同的异常进行不同的处理
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
System.out.println("这是全局异常...");
System.out.println("当前异常为:" + e);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("500");
//针对自定义进行跳转
if (e instanceof UserNotFoundException){
modelAndView.setViewName("login");
}
return modelAndView;
}
前后端分离开发方式的异常处理
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax</title>
</head>
<body>
<input type="button" onclick="sendMsg()" value="进行ajax发送">
<h4 id="msg"></h4>
<script>
function sendMsg() {
var xmlHttpRequest = new XMLHttpRequest();
//处理返回结果
xmlHttpRequest.onreadystatechange = function (){
if (xmlHttpRequest.status == 200 && xmlHttpRequest.readyState == 4){
console.log(xmlHttpRequest.responseText);
document.getElementById('msg').innerText = xmlHttpRequest.responseText;
}
}
xmlHttpRequest.open("GET","http://localhost:8080/demos/2");
xmlHttpRequest.send();
}
</script>
</body>
</html>
自定义异常
package com.hg.exception;
public class IlleaglNumberException extends Exception{
public IlleaglNumberException(String message) {
super(message);
}
}
全局异常处理类
package com.hg.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class AjaxGlobalExceptionResolve {
private static final Logger log = LoggerFactory.getLogger(AjaxGlobalExceptionResolve.class);
//处理指定异常
@ExceptionHandler(value = IlleaglNumberException.class)
@ResponseBody
public ResponseEntity<String> illeaglNumberExceptionHandler(Exception ex){
System.out.println("进入非法参数异常处理");
log.debug("exception:{}", ex.getMessage());
return new ResponseEntity<>(ex.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
}
//处理Exception子类异常
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResponseEntity<String> exceptionHandler(Exception ex){
System.out.println("进入异常处理");
return new ResponseEntity<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
controller
package com.hg.controller;
import com.hg.exception.IlleaglNumberException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/demos")
public class DemoController {
@GetMapping("/{id}")
public ResponseEntity<String> demos(@PathVariable("id") Integer id) {
if (id < 0) throw new IlleaglNumberException("id值小于0");
return new ResponseEntity<>("demo ok!", HttpStatus.OK);
}
}