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数组课后习题
package javafirst; import java.util.Arrays; class Show{ public void showArray(int[] arr){ for(int i ...
- SQL生成n位随机字符串
--1.随着newid() go --创建一个视图(因为不能在功能直接用于newid()) create view vnewid as select newid() N'MacoId'; go --创 ...
- 【无旋 treap】例题
[bzoj3223]文艺平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[ ...
- 亲测有效,解决Can 't connect to local MySQL server through socket '/tmp/mysql.sock '(2) ";
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/hjf161105/article/details/78850658 最近租了一个阿里云云翼服务器,趁 ...
- linux下jar包的生存与开机自动启动
前言 作为一名Android开发,有的时候也是要做做其他工作的,前段时间写了一个很简单的java消息转发程序,因为和三方厂商合作,对方只提供了java的sdk,然而我们这边都是清一色的C#后台开发人员 ...
- 图解linux启动过程
概述 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWUVZVUFOR0VO/font/5a6L5L2T/fontsize/400/fill/I0JBQkF ...
- quartz结合多线程处理后台业务
最近项目中有播放视频的需求,技术选型采用UMS播放器,免费版只能播放FLV格式的视频文件,因此需要对用户上传的视频进行格式转换,转换工具为FormatFactory,功能还是比较强大的.但是面临的一个 ...
- Mobile Push Notification
In one embodiment, a method includes sending to a mobile client computing device a first notificatio ...
- WPF 渲染原理
原文:WPF 渲染原理 在 WPF 最主要的就是渲染,因为 WPF 是一个界面框架.想用一篇博客就能告诉大家完整的 WPF 渲染原理是不可能的.本文告诉大家 WPF 从开发者告诉如何画图像到在屏幕显示 ...
- .net remoting 使用事件
原文:.net remoting 使用事件 在RPC如果需要使用事件,相对是比较难的.本文告诉大家如何在 .net remoting 使用事件. 目录 使用 Channel 序列化 开发建议 修复异常 ...