springboot 2.x处理404、500等异常
404错误
404错误是不经过Controller的,所以使用@ControllerAdvice或@RestControllerAdvice无法获取到404错误
springboot2处理404错误的两种方式
第一种:直接配置
#出现错误时, 直接抛出异常
spring.mvc.throw-exception-if-no-handler-found=true
这种方式不太适用实际开发,比如和swagger集成时,访问/swagger-ui.html会出现404异常
第二种:继承ErrorController来处理错误
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class MyErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError(HttpServletRequest request){
//获取statusCode:401,404,500
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if(statusCode == 500){
return "/error/500";
}else if(statusCode == 404){
//对应的是/error/404.html、/error/404.jsp等,文件位于/templates下面
return "/error/404";
}else if(statusCode == 403){
return "/403";
}else{
return "/500";
}
}
@Override
public String getErrorPath() {
return "/error";
}
}
import com.bettn.common.util.Result;
import com.bettn.common.util.WebUtils;
import org.apache.shiro.ShiroException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 全局异常捕获处理
*/
@RestControllerAdvice
public class ExceptionControllerAdvice {
private static final Logger logger= LoggerFactory.getLogger(ExceptionControllerAdvice.class);
// 捕捉shiro的异常
@ExceptionHandler(ShiroException.class)
public Result handle401() {
return new Result(401,"您没有权限访问!",null);
}
// 捕捉其他所有异常
@ExceptionHandler(Exception.class)
public Object globalException(HttpServletRequest request, HandlerMethod handlerMethod, Throwable ex) {
if(WebUtils.isAjax(handlerMethod)){
return new Result(getStatus(request).value(), "访问出错,无法访问: " + ex.getMessage(), null);
}else {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/error/500"); //这里需要在templates文件夹下新建一个/error/500.html文件用作错误页面
modelAndView.addObject("errorMsg",ex.getMessage());
return modelAndView;
}
}
/**
* 判断是否是Ajax请求
*
* @param request
* @return
*/
public boolean isAjax(HttpServletRequest request) {
return (request.getHeader("X-Requested-With") != null &&
"XMLHttpRequest".equals(request.getHeader("X-Requested-With").toString()));
}
// @ExceptionHandler(Exception.class)
// public Result globalException(HttpServletRequest request, Throwable ex) {
// return new Result(getStatus(request).value(),"访问出错,无法访问: " + ex.getMessage(),null);
// }
/**
* 获取响应状态码
* @param request
* @return
*/
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
}
/**
* 捕捉404异常,这个方法只在配置
* spring.mvc.throw-exception-if-no-handler-found=true来后起作用
*
*/
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoHandlerFoundException.class)
public Result handle(HttpServletRequest request,NoHandlerFoundException e) {
System.out.println(12);
return new Result(404,"没有【"+request.getMethod()+"】"+request.getRequestURI()+"方法可以访问",null);
}
}
这个异常类与ExceptionControllerAdvice连用,ExceptionControllerAdvice类除了不能处理404异常以外,其他异常都可以处理,其中
globalException异常这个方法会捕获500错误,导致MyErrorController无法捕获到500错误,从而跳转到500页面,也就是说MyErrorController在这个项目中
只能捕获404异常
500异常捕获
500异常分为ajax和直接跳转500页面
具体的异常捕获,代码如何下:
// 捕捉其他所有异常
@ExceptionHandler(Exception.class)
public Object globalException(HttpServletRequest request, HandlerMethod handlerMethod, Throwable ex) {
if(WebUtils.isAjax(handlerMethod)){
return new Result(getStatus(request).value(), "访问出错,无法访问: " + ex.getMessage(), null);
}else {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/error/500"); //这里需要在templates文件夹下新建一个/error/500.html文件用作错误页面
modelAndView.addObject("errorMsg",ex.getMessage());
return modelAndView;
}
}
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
public class WebUtils extends org.springframework.web.util.WebUtils {
/**
* 判断是否ajax请求
* spring ajax 返回含有 ResponseBody 或者 RestController注解
* @param handlerMethod HandlerMethod
* @return 是否ajax请求
*/
public static boolean isAjax(HandlerMethod handlerMethod) {
ResponseBody responseBody = handlerMethod.getMethodAnnotation(ResponseBody.class);
if (null != responseBody) {
return true;
}
// 获取类上面的Annotation,可能包含组合注解,故采用spring的工具类
Class<?> beanType = handlerMethod.getBeanType();
responseBody = AnnotationUtils.getAnnotation(beanType, ResponseBody.class);
if (null != responseBody) {
return true;
}
return false;
}
public static String getCookieValue(HttpServletRequest request, String cookieName) {
Cookie cookie=getCookie(request, cookieName);
return cookie==null?null:cookie.getValue();
}
public static void removeCookie(HttpServletResponse response, String cookieName) {
setCookie(response, cookieName, null, 0);
}
public static void setCookie(HttpServletResponse response, String cookieName, String cookieValue,
int defaultMaxAge) {
Cookie cookie=new Cookie(cookieName,cookieValue);
cookie.setHttpOnly(true);
cookie.setPath("/");
cookie.setMaxAge(defaultMaxAge);
response.addCookie(cookie);
}
}
TIP
404、500页面需要放在/templates下,且确认配置了视图,如jsp、thymeleaf等,否则也会出现找不到页面,例如集成thymeleaf
依赖
<!-- thymeleaf模板引擎和shiro框架的整合,这个是与shiro集成的,一般不整合shiro就不需要这个依赖 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>${thymeleaf.extras.shiro.version}</version>
</dependency>
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
配置
spring:
# 模板引擎
thymeleaf:
mode: HTML5
encoding: utf-8
# 禁用缓存
cache: false
404、500页面地址(目录结构)
src/main/resources/templates/error/404.html
src/main/resources/templates/error/500.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>500</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<!--
直接使用${el}无法解析出el的值
${errorMsg}
-->
<h3>糟糕! 服务器出错啦~~(>_<)~~</h3>
<div>
异常信息如下:<br/>
<p th:text="${errorMsg}"></p>
</div>
</body>
</html>
参考:https://www.jianshu.com/p/8d41243e7fba
springboot 2.x处理404、500等异常的更多相关文章
- C# MVC模式 404 500页面设置方法
<customErrors mode="On" defaultRedirect="Controllers/Action"> <error st ...
- java异常处理及400,404,500错误处理
java代码中经常碰到各种需要处理异常的时候,比如什么IOException SQLException NullPointException等等,在开发web项目中,遇到异常,我现在做的就 ...
- HTML状态码大全(301,404,500等)
HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等) 这些状态码被分 ...
- idea启动springboot+jsp项目出现404
场景:用IntelliJ IDEA 启动 springBoot项目访问出现404,很皮,因为我用eclipse开发时都是正常的,找了很久,什么加注释掉<scope>provided< ...
- Spring MVC自定义403,404,500状态码返回页面
代码 HTTP状态码干货:http://tool.oschina.net/commons?type=5 import org.springframework.boot.web.servlet.erro ...
- Springboot解决资源文件404,503等特殊报错,无法访问
Springboot解决资源文件404,503等特殊报错 原文链接:https://www.cnblogs.com/blog5277/p/9324609.html 原文作者:博客园--曲高终和寡 ** ...
- Django 编写自定义的 404 / 500 报错界面
Django 编写自定义的 404 / 500 报错界面 1. 首先 setting.py 文件中的 debug 参数设置成 false ,不启用调试. DEBUG = False 2. 在 temp ...
- 解决spring boot中rest接口404,500等错误返回统一的json格式
在开发rest接口时,我们往往会定义统一的返回格式,列如: { "status": true, "code": 200, "message" ...
- apache 网页301重定向、自定义400/403/404/500错误页面
首先简单介绍一下,.htaccess文件是Apache服务器中的一个配置文件(Nginx服务器没有),它负责相关目录下的网页配置.通过对.htaccess文件进行设置,可以帮我们实现:网页301重定向 ...
随机推荐
- 对Java JVM中类加载几点解释
1.用到类的时候,类加载到方法区,同时方法区会存放static的内容(包括静态方法和静态变量),随类的加载而加载 2当new的时候,会在堆中创建一个对象,在其中会开辟其中的实例变量内存并初始化,堆中变 ...
- Compile Graphics Magick, Boost, Botan and QT with MinGW64 under Windows 7 64
Compile Graphics Magick, Boost, Botan and QT with MinGW64 under Windows 7 64 Sun, 01/01/2012 - 15:43 ...
- hexo主题选择和配置
之前用next主题,发现文章标题都是h2,不利于seo,想着通过改模板改成h1的,发现很繁琐.今天发现,通过下载指定版本的next后,标题自动是h1的. 参考网页https://notes.iissn ...
- 【非常高%】【codeforces 733B】Parade
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- JTextpane 加入的行号
最近项目需求,在需求JTextPane加入行号等信息,网上找了半天才发现JTextArea加入行号信息.copy正在研究在线程序.他发现自己能够做出改变来改变JTextPane显示行号. 代码: pa ...
- WPF 使用 SharpDX
原文:WPF 使用 SharpDX 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee.io 访问 ...
- CUDA+OpenCV 绘制朱利亚(Julia)集合图形
Julia集中的元素都是经过简单的迭代计算得到的,很适合用CUDA进行加速.对一个600*600的图像,需要进行360000次迭代计算,所以在CUDA中创建了600*600个线程块(block),每个 ...
- JDBC学习笔记——事务、存储过程以及批量处理
1.事务 1.1.事务的基本概念和使 ...
- 升级phpstudy2018默认mysql版本到5.7
原文:升级phpstudy2018默认mysql版本到5.7 版权声明:在那最初的相遇中,我们都曾经为彼此心动过... https://blog.csdn.net/weixin_36185028/ar ...
- uboot初体验-----趣谈nand设备发起的浅显理解
1 选择Uboot版本号 2 移植uboot至console正常work 3 制造uImage和使用uboot指南 4 写NFC驱动器 5 uboot从nand启动引导系统 1 选择Uboot版本号 ...