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) {
        
    }
    
    
}

 

 

四、SpringBoot 2.3.0.RELEASE版本自定义404页面

在spring-boot-starter-parent 2.3.0.RELEASE版本后,org.springframework.boot.web.servlet.error.ErrorController接口已经不建议采用getErrorPath方法,在2.5.3版本后,ErrorController接口已经无getErrorPath方法(直接删除)。

SpringBoot 2.3.0.RELEASE版本后自定义404页面,见:

https://www.cnblogs.com/fanshuyao/p/15066188.html

 

 

 

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

 

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

©Copyright 蕃薯耀 2021-04-29

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

posted @ 2021-04-29 09:34  蕃薯耀  阅读(975)  评论(1编辑  收藏  举报