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/
今天越懒,明天要做的事越多。