• SpringBoot 自定义404,SpringBoot 错误处理兼容Ajax请求


    SpringBoot 自定义404,SpringBoot 错误处理兼容Ajax请求

    SpringBoot全局异常处理类

    ================================

    ©Copyright 蕃薯耀 2021-04-29

    https://www.cnblogs.com/fanshuyao/

    一、SpringBoot 自定义异常页面,SpringBoot 自定义404页面和500页面,SpringBoot 错误兼容Ajax请求

    当是页面普通请求时,系统会返回404页面或500页面(handleError);

    当是Ajax请求时,系统会返回json结果(handleErrorBody)

    import java.io.IOException;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.boot.web.servlet.error.ErrorController;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.servlet.ModelAndView;
    
    import com.lqy.db.bean.Result;
    
    @Controller
    public class ErrorPageController implements ErrorController {
    
        public final static String STATUS_CODE = "javax.servlet.error.status_code";
        
        
        @Override
        public String getErrorPath() {
            return "/error";//路径必须为/error
        }
        
        
        /**
         * 处理html页面请求的错误
         * @param request
         * @param response
         * @return
         * @throws IOException
         */
        @RequestMapping(value = "/error", produces = {"text/html"})
        public ModelAndView handleError(HttpServletRequest request, HttpServletResponse response) throws IOException {
            
            Integer statusCode = (Integer) request.getAttribute(STATUS_CODE);
            
            ModelAndView mav = new ModelAndView();
            
            if(statusCode == 401) {
                mav.addObject("statusCode", 401);
                mav.setViewName("error/4xx");
                
            }else if(statusCode == 403) {
                mav.addObject("statusCode", 403);
                mav.setViewName("error/4xx");
                
            }else if(statusCode == 404) {
                mav.addObject("statusCode", 404);
                mav.setViewName("error/404");
                
            }else {
                mav.addObject("statusCode", 500);
                mav.setViewName("error/500");
            }
            
            return mav;
            
        }
        
        
        /**
         * 处理Ajax请求的错误
         * @param request
         * @param response
         * @return
         * @throws IOException
         */
        @RequestMapping(value = "/error")
        @ResponseBody
        public Result handleErrorBody(HttpServletRequest request, HttpServletResponse response) throws IOException {
            
            Integer statusCode = (Integer) request.getAttribute(STATUS_CODE);
                
            return Result.fail(statusCode);
        }
        
        
        /**
         * 判断是否为Ajax请求
         * @param request
         * @return
         */
        @Deprecated
        public boolean isAjaxRequest(HttpServletRequest request) {
            
            String x_request_with = request.getHeader("x-requested-with");
            
            if(!StringUtils.isBlank(x_request_with) && x_request_with.equals("XMLHttpRequest")) {
                return true;
            }
            return false;
        }
        
        
    
    }

    异常页面的位置(此处使用了freemarker模板,可以使用404.html):

    二、SpringBoot全局统一异常处理类

    import java.sql.SQLDataException;
    import java.sql.SQLException;
    import java.sql.SQLSyntaxErrorException;
    
    import org.apache.log4j.Logger;
    import org.springframework.dao.DataIntegrityViolationException;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.jdbc.BadSqlGrammarException;
    import org.springframework.web.HttpMediaTypeNotSupportedException;
    import org.springframework.web.HttpRequestMethodNotSupportedException;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.szpl.csgx.bean.Result;
    import com.szpl.csgx.exception.RunException;
    
    
    /**
     * 系统全局异常处理
     * 
     */
    @ControllerAdvice
    public class GlobalExceptionHandler {
        
        private static Logger log = Logger.getLogger(GlobalExceptionHandler.class);
        
        // 异常捕获,并处理
        @ExceptionHandler(Throwable.class)
        @ResponseBody
        public Result handleException(Throwable e) {
            
            log.error(e.getMessage(), e);
            
            Result result = null;
            
            if (e instanceof RunException) {//自定义异常
                result = Result.failMsg(e.getMessage());
                
            }else if (e instanceof HttpMediaTypeNotSupportedException) {
                result = Result.failMsg("Media类型不支持:" + e.getMessage());
                
            }else if (e instanceof HttpRequestMethodNotSupportedException) {
                result = Result.failMsg("请求方法不支持:" + e.getMessage());
                
            }else if (e instanceof HttpMessageNotReadableException) {
                result = Result.failMsg("参数错误");
                
            }else if (e instanceof ClassCastException) {
                result = Result.failMsg("类型转换出错:" + e.getMessage());
                
            }else if (e instanceof IllegalStateException) {
                result = Result.failMsg("类型出错:" + e.getMessage());
                
            }else if (e instanceof IllegalArgumentException) {
                result = Result.failMsg(e.getMessage());
                
            }else if (e instanceof BadSqlGrammarException) {
                result = Result.failMsg("sql脚本语法异常");
                
            }else if (e instanceof SecurityException) {
                result = Result.failMsg(e.getMessage());
                
            }else if (e instanceof SQLSyntaxErrorException) {
                result = Result.failMsg(e.getMessage());
                
            }else if (e instanceof SQLDataException) {
                result = Result.failMsg("sql参数类型不匹配");
                
            }else if (e instanceof DataIntegrityViolationException) {
                result = Result.failMsg("sql错误");
                
            }else if (e instanceof RuntimeException) {
                result = Result.failMsg("运行时异常");
                
            }else if (e instanceof SQLException) {
                result = Result.failMsg("SQL异常");
                
            }else if (e instanceof ClassNotFoundException) {
                result = Result.failMsg("找不到类,或者缺少类文件");
                
            }else if (e instanceof Exception) {
                result = Result.failMsg("系统异常");
                
            }else if (e instanceof NoClassDefFoundError) {
                result = Result.failMsg("Jar包冲突或者内部类编译文件缺失");
                
            }else if (e instanceof Error) {
                result = Result.failMsg("系统错误");
                
            }else {
                result = Result.failMsg("系统未知错误");
                
            }
            return result;
        }
    }

    自定义异常类

    /**
     * 校验异常
     * @author liqiongy
     *
     */
    public class RunException extends RuntimeException {
    
        private static final long serialVersionUID = -816523664429815048L;
    
        public RunException() {
            super();
        }
    
        public RunException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public RunException(String message) {
            super(message);
        }
    
        public RunException(Throwable cause) {
            super(cause);
        }
        
    }

    三、SpringBoot统一结果返回类

    import java.util.Date;
    
    import cn.hutool.core.date.DateUtil;
    
    public class Result {
        
        public static final String SUCCESS = "操作成功。";
        public static final String FAILURE = "操作失败!";
        
        private boolean result;
        private String timestamp;
        private String msg;
        private Object datas;
        
        private Result() {}
        
        public static Result ok() {
            return Result.ok(SUCCESS, null);
        }
        
        
        public static Result ok(Object datas) {
            return Result.ok(SUCCESS, datas);
        }
        
        
        public static Result okMsg(String msg) {
            return Result.ok(msg, null);
        }
        
        
        public static Result ok(String msg, Object datas) {
            Result result = new Result();
            result.setResult(true);
            result.setTimestamp(DateUtil.formatDateTime(new Date()));
            
            if(msg == null || msg == "" || msg.trim() == "") {
                result.setMsg(SUCCESS);
            }else {
                result.setMsg(msg);
            }
            
            result.setDatas(datas);
            return result;
        }
        
        public static Result fail() {
            return Result.fail(FAILURE, null);
        }
        
        
        public static Result failMsg(String msg) {
            return Result.fail(msg, null);
        }
        
        
        public static Result fail(Object datas) {
            return Result.fail(FAILURE, datas);
        }
        
        public static Result fail(String msg, Object datas) {
            Result result = new Result();
            result.setResult(false);
            result.setTimestamp(DateUtil.formatDateTime(new Date()));
            
            if(msg == null || msg == "" || msg.trim() == "") {
                result.setMsg(FAILURE);
            }else {
                result.setMsg(msg);
            }
            result.setDatas(datas);
            return result;
        }
        
        public boolean isResult() {
            return result;
        }
        public void setResult(boolean result) {
            this.result = result;
        }
        public String getTimestamp() {
            return timestamp;
        }
    
        public void setTimestamp(String timestamp) {
            this.timestamp = timestamp;
        }
    
        public String getMsg() {
            return msg;
        }
        public void setMsg(String msg) {
            this.msg = msg;
        }
        public Object getDatas() {
            return datas;
        }
        public void setDatas(Object datas) {
            this.datas = datas;
        }
        
    
        public static void main(String[] args) {
            
        }
        
        
    }

    (时间宝贵,分享不易,捐赠回馈,^_^)

    ================================

    ©Copyright 蕃薯耀 2021-04-29

    https://www.cnblogs.com/fanshuyao/

    今天越懒,明天要做的事越多。
  • 相关阅读:
    foreach next 操作数组指针移动问题,多个数连加,连除,连减,连乘php版本
    mysql 5.7 laravel json类型数据相关操作
    rbac权限控制,基于无线分类
    基于bootstrap-treeview做的一个漂亮的无限分类树层级联动菜单
    css页面字体替换源代码和页面显示不一样问题解决
    centos6.8 编译安装lnmp php7.2 mysql5.6 nginx1.1.4
    mysql5.7采坑
    laravel整合vue 多入口解决
    使用mysql设计一个全局订单生产计数器
    laravel整合workerman做聊天室
  • 原文地址:https://www.cnblogs.com/fanshuyao/p/14716703.html
Copyright © 2020-2023  润新知