乐趣区

SpringBoot系列教程web篇之404500异常页面配置

接着前面几篇 web 处理请求的博文,本文将说明,当出现异常的场景下,如 404 请求 url 不存在,,403 无权,500 服务器异常时,我们可以如何处理

原文友链: SpringBoot 系列教程 web 篇之 404、500 异常页面配置

<!– more –>

I. 环境搭建

首先得搭建一个 web 应用才有可能继续后续的测试,借助 SpringBoot 搭建一个 web 应用属于比较简单的活;

创建一个 maven 项目,pom 文件如下

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7</version>
    <relativePath/> <!-- lookup parent from update -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.45</version>
    </dependency>
</dependencies>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

依然是一般的流程,pom 依赖搞定之后,写一个程序入口

/**
 * Created by @author yihui in 15:26 19/9/13.
 */
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class);
    }
}

II. 异常页面配置

在 SpringBoot 项目中,本身提供了一个默认的异常处理页面,当我们希望使用自定义的 404,500 等页面时,可以如何处理呢?

1. 默认异常页面配置

在默认的情况下,要配置异常页面非常简单,在资源路径下面,新建 error 目录,在下面添加 400.html, 500html 页面即可

项目结构如上,注意这里的实例 demo 是没有使用模板引擎的,所以我们的异常页面放在 static 目录下;如果使用了如 FreeMaker 模板引擎时,可以将错误模板页面放在 template 目录下

接下来实际测试下是否生效, 我们先定义一个可能出现服务器 500 的服务

@Controller
@RequestMapping(path = "page")
public class ErrorPageRest {

    @ResponseBody
    @GetMapping(path = "divide")
    public int divide(int sub) {System.out.println("divide1");
        return 1000 / sub;
    }
}

请求一个不存在的 url,返回我们定义的 400.html 页面

<html>
<head>
    <title>404 页面 </title>
</head>
<body>
<h3> 页面不存在 </h3>
</body>
</html>

请求一个服务器 500 异常,返回我们定义的 500.html 页面

<html>
<head>
    <title>500 页面 </title>
</head>
<body>
<h2 style="color: red;"> 服务器出现异常!!!</h2>
</body>
</html>

2. BasicErrorController

看上面的使用比较简单,自然会有个疑问,这个异常页面是怎么返回的呢?

从项目启动的日志中,注意一下RequestMappingHandlerMapping

可以发现里面有个 /error 的路径不是我们自己定义的,从命名上来看,这个多半就是专门用来处理异常的 Controller -> BasicErrorController,部分代码如下

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {

    @Override
    public String getErrorPath() {return this.errorProperties.getPath();
    }

    @RequestMapping(produces = "text/html")
    public ModelAndView errorHtml(HttpServletRequest request,
            HttpServletResponse response) {HttpStatus status = getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
    }

    @RequestMapping
    @ResponseBody
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        Map<String, Object> body = getErrorAttributes(request,
                isIncludeStackTrace(request, MediaType.ALL));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<>(body, status);
    }
}

这个 Controller 中,一个返回网页的接口,一个返回 Json 串的接口;我们前面使用的应该是第一个,那我们什么场景下会使用到第二个呢?

  • 通过制定请求头的Accept,来限定我们只希望获取 json 的返回即可

3. 小结

本篇内容比较简单,归纳为两句话如下

  • 将自定义的异常页面根据 http 状态码命名,放在 /error 目录下
  • 在异常状况下,根据返回的 http 状态码找到对应的异常页面返回

II. 其他

0. 项目

a. 系列博文

  • 190930-SpringBoot 系列教程 web 篇之 404、500 异常页面配置
  • 190929-SpringBoot 系列教程 web 篇之重定向
  • 190913-SpringBoot 系列教程 web 篇之返回文本、网页、图片的操作姿势
  • 190905-SpringBoot 系列教程 web 篇之中文乱码问题解决
  • 190831-SpringBoot 系列教程 web 篇之如何自定义参数解析器
  • 190828-SpringBoot 系列教程 web 篇之 Post 请求参数解析姿势汇总
  • 190824-SpringBoot 系列教程 web 篇之 Get 请求参数解析姿势汇总
  • 190822-SpringBoot 系列教程 web 篇之 Beetl 环境搭建
  • 190820-SpringBoot 系列教程 web 篇之 Thymeleaf 环境搭建
  • 190816-SpringBoot 系列教程 web 篇之 Freemaker 环境搭建
  • 190421-SpringBoot 高级篇 WEB 之 websocket 的使用说明
  • 190327-Spring-RestTemplate 之 urlencode 参数解析异常全程分析
  • 190317-Spring MVC 之基于 java config 无 xml 配置的 web 应用构建
  • 190316-Spring MVC 之基于 xml 配置的 web 应用构建
  • 190213-SpringBoot 文件上传异常之提示 The temporary upload location xxx is not valid

b. 项目源码

  • 工程:https://github.com/liuyueyi/spring-boot-demo
  • 项目: https://github.com/liuyueyi/spring-boot-demo/blob/master/spring-boot/207-web-response

1. 一灰灰 Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现 bug 或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

  • 一灰灰 Blog 个人博客 https://blog.hhui.top
  • 一灰灰 Blog-Spring 专题博客 http://spring.hhui.top

退出移动版