springboot全局异常处理

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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值