SpringBoot SpringMVC @ControllerAdvice、@RestControllerAdvice全局异常处理(@ExceptionHandler)(推荐)

需要了解:SpringBoot SpringMVC @ControllerAdvice、@RestControllerAdvice介绍

介绍

注解@ControllerAdvice(@RestControllerAdvice) 和 注解@ExceptionHandler 搭配使用,用来处理全局异常

  • @ExceptionHandler:修饰方法,表示处理某个异常,必须 传入 要处理的异常

注意1

当 controlle抛错时,推荐使用该方式处理异常

当 过滤器抛错 ,该注解将无法处理

当 资源不存在时,该注解能处理,比较麻烦,推荐使用 BasicExceptionController 处理

注意2:**

原controller不会打印错误,需要在该方法中处理错误

返回json

package top.malaoshi.netdisk.ctrl;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.malaoshi.netdisk.exception.BaseException;
import top.malaoshi.netdisk.vo.JsonResult;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public JsonResult handlerException(Exception e) {

        e.printStackTrace();//为了便于找到错误
        String msg = e.getMessage();
        if(msg == null || "".equals(msg)){
            msg = e.toString();
        }
        JsonResult res=new JsonResult(4000, msg);

        return res;
    }

    @ExceptionHandler(BaseException.class)
    public JsonResult handlerBaseException(BaseException e) {
        e.printStackTrace();
        JsonResult res=new JsonResult(e.getCode(),e.getMessage());
        return res;
    }
}

重定向页面

package top.malaoshi.stdsecurity.config;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class GlobalExceptionHandler {
    //当Controller抛出异常时,由该方法处理
    @ExceptionHandler(Exception.class)
    public ModelAndView handlerException(Exception e) {
        e.printStackTrace();//为了便于找到错误
        ModelAndView mv = new ModelAndView();
        mv.addObject("message", e.getMessage());
        mv.setViewName("redirect:/exception.html");
        return mv;
    }
}

统一处理 Ajax请求 和 普通请求

@ControllerAdvice
public class GlobalExceptionHandler {
    //当Controller抛出异常时,由该方法处理
    @ExceptionHandler(Exception.class)
    public Object handlerException(HttpServletRequest request, 
                                   HttpServletResponse response, 
                                   Exception e) throws IOException {

        // 如果是ajax请求
        if(Ajax.isAjax(request)){
            e.printStackTrace();
            String msg = e.getMessage();
            if(msg == null || "".equals(msg)){
                msg = e.toString();
            }
            JsonResult jr = JsonResult.fail(500, msg);
            ResponseUtils.sendJSON(response,jr);
            return null;
        }else{
            ModelAndView mv = new ModelAndView();
            mv.addObject("exception", e.getMessage());
            mv.addObject("url", reqest.getRequestURL());
            mv.setViewName(ERROR_VIEW);
            return mv;
        }
    }
}

抛异常例子

登录controlle

package top.malaoshi.netdisk.ctrl;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import top.malaoshi.netdisk.service.LoginSrvImpl;
import top.malaoshi.netdisk.vo.JsonResult;
import top.malaoshi.netdisk.vo.User;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

@RestController
public class LoginCtrl {

    @Resource
    private LoginSrvImpl loginSrv;
    @PostMapping("/login")
//    public JsonResult login(HttpSession session,String username, String password) throws Exception {
    public JsonResult login(HttpSession session, @RequestBody User user) throws Exception {
//        User user = loginSrv.login(username, password);
        User userRes = loginSrv.login(user.getUsername(), user.getPassword());
        session.setAttribute("user",userRes);
        return JsonResult.success("登录成功!");
    }

}

登录Service

package top.malaoshi.netdisk.service;

import org.springframework.stereotype.Service;
import top.malaoshi.jdbc.DbUtils;
import top.malaoshi.jdbc.Record;
import top.malaoshi.netdisk.exception.LoginException;
import top.malaoshi.netdisk.jdbc.DbPool;
import top.malaoshi.netdisk.vo.JsonCodeMsg;
import top.malaoshi.netdisk.vo.User;

import javax.annotation.Resource;
import java.sql.Connection;
import java.util.List;

@Service
public class LoginSrvImpl {

    @Resource
    private DbPool dbPool;
    public User login(String username, String password) throws Exception {
        DbUtils dbUtils = null;
        List<Record> list = null;
        try {
            dbUtils = dbPool.getDbUtils();

            String sql = "select uid,username,password from t_user where username = ? and password = ?";
            list = dbUtils.query(sql, username, password);
        }catch (Exception e){
            throw e;
        }finally {
            if(dbUtils!=null){
                dbUtils.close();
            }
        }
        if(list == null || list.size() == 0){
            throw new LoginException(JsonCodeMsg.LOGIN_FAIL.getCode(), "用户名或密码错误!");
        }

        Record record = list.get(0);
        User user = new User();
        user.setId(record.getLongValue("uid"));
        user.setUsername(record.getStringValue("username"));
        user.setPassword(record.getStringValue("password"));


        return user;
    }
}

BaseException自定义异常基类

https://www.malaoshi.top/show_1IX74r04LyFp.html

LoginException 登录失败的异常

https://www.malaoshi.top/show_1IX74r0gOx4q.html

参考:
https://blog.csdn.net/Peng_Hong_fu/article/details/85007726


原文出处:/show_1EF60wKyxKSH.html