原文: http://zetcode.com/spring/custom404page/

Spring 自定义 404 错误页面教程展示了如何在 Spring Web 应用中创建自定义 404 错误页面。

Spring 是用于创建企业应用的流行 Java 应用框架。

404 代码

HTTP 404 或 404 未找到是计算机网络通信中的超文本传输协议(HTTP)标准响应代码,用于指示客户端能够与给定服务器进行通信,但是服务器找不到所请求的资源。

Spring 自定义 404 错误页面示例

以下应用使用创建自定义 404 错误页面。 默认情况下,当找不到资源时,将显示 Tomcat 的 404 错误页面。

  1. src
  2. ├───main
  3. ├───java
  4. └───com
  5. └───zetcode
  6. ├───config
  7. MyWebInitializer.java
  8. WebConfig.java
  9. └───controller
  10. ControllerAdvisor.java
  11. MyController.java
  12. └───resources
  13. logback.xml
  14. └───templates
  15. index.html
  16. └───error
  17. 404.html
  18. └───test
  19. └───java

这是项目结构。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>custom404page</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>war</packaging>
  11. <properties>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. <maven.compiler.source>11</maven.compiler.source>
  14. <maven.compiler.target>11</maven.compiler.target>
  15. </properties>
  16. <dependencies>
  17. <dependency>
  18. <groupId>ch.qos.logback</groupId>
  19. <artifactId>logback-classic</artifactId>
  20. <version>1.2.3</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>javax.servlet</groupId>
  24. <artifactId>javax.servlet-api</artifactId>
  25. <version>4.0.1</version>
  26. <scope>provided</scope>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework</groupId>
  30. <artifactId>spring-webmvc</artifactId>
  31. <version>5.1.3.RELEASE</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.thymeleaf</groupId>
  35. <artifactId>thymeleaf-spring5</artifactId>
  36. <version>3.0.11.RELEASE</version>
  37. </dependency>
  38. <dependency>
  39. <groupId>org.thymeleaf</groupId>
  40. <artifactId>thymeleaf</artifactId>
  41. <version>3.0.11.RELEASE</version>
  42. </dependency>
  43. </dependencies>
  44. <build>
  45. <plugins>
  46. <plugin>
  47. <groupId>org.apache.maven.plugins</groupId>
  48. <artifactId>maven-war-plugin</artifactId>
  49. <version>3.2.2</version>
  50. </plugin>
  51. </plugins>
  52. </build>
  53. </project>

pom.xml文件中,我们具有以下依存关系:logback-classicjavax.servlet-apispring-webmvcthymeleaf-spring5以及thymeleaf

resources/logback.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3. <logger name="org.springframework" level="ERROR"/>
  4. <logger name="com.zetcode" level="INFO"/>
  5. <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
  6. <encoder>
  7. <Pattern>%d{HH:mm:ss.SSS} %blue(%-5level) %magenta(%logger{36}) - %msg %n
  8. </Pattern>
  9. </encoder>
  10. </appender>
  11. <root>
  12. <level value="INFO" />
  13. <appender-ref ref="consoleAppender" />
  14. </root>
  15. </configuration>

这是logback.xml配置文件。

com/zetcode/config/MyWebInitializer.java

  1. package com.zetcode.config;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.context.WebApplicationContext;
  4. import org.springframework.web.servlet.DispatcherServlet;
  5. import org.springframework.web.servlet.FrameworkServlet;
  6. import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
  7. @Configuration
  8. public class MyWebInitializer extends
  9. AbstractAnnotationConfigDispatcherServletInitializer {
  10. @Override
  11. protected Class<?>[] getRootConfigClasses() {
  12. return null;
  13. }
  14. @Override
  15. protected Class<?>[] getServletConfigClasses() {
  16. return new Class[]{WebConfig.class};
  17. }
  18. @Override
  19. protected String[] getServletMappings() {
  20. return new String[]{"/"};
  21. }
  22. @Override
  23. protected FrameworkServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
  24. var dispatcher = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
  25. dispatcher.setThrowExceptionIfNoHandlerFound(true);
  26. return dispatcher;
  27. }
  28. }

MyWebInitializer初始化 Spring Web 应用。 它包含一个配置类:WebConfig

  1. @Override
  2. protected FrameworkServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
  3. var dispatcher = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
  4. dispatcher.setThrowExceptionIfNoHandlerFound(true);
  5. return dispatcher;
  6. }

使用setThrowExceptionIfNoHandlerFound(),我们将 Spring 配置为在找不到资源时抛出NoHandlerFoundException。 如果我们在此行中添加注释,则会显示 Web 服务器的 404 错误页面。

com/zetcode/config/WebConfig.java

  1. package com.zetcode.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.ComponentScan;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.web.servlet.ViewResolver;
  8. import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  9. import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
  10. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  11. import org.thymeleaf.spring5.SpringTemplateEngine;
  12. import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
  13. import org.thymeleaf.spring5.view.ThymeleafViewResolver;
  14. @Configuration
  15. @EnableWebMvc
  16. @ComponentScan(basePackages = {"com.zetcode"})
  17. public class WebConfig implements WebMvcConfigurer {
  18. @Autowired
  19. private ApplicationContext applicationContext;
  20. @Bean
  21. public SpringResourceTemplateResolver templateResolver() {
  22. var templateResolver = new SpringResourceTemplateResolver();
  23. templateResolver.setApplicationContext(applicationContext);
  24. templateResolver.setPrefix("classpath:/templates/");
  25. templateResolver.setSuffix(".html");
  26. return templateResolver;
  27. }
  28. @Bean
  29. public SpringTemplateEngine templateEngine() {
  30. var templateEngine = new SpringTemplateEngine();
  31. templateEngine.setTemplateResolver(templateResolver());
  32. templateEngine.setEnableSpringELCompiler(true);
  33. return templateEngine;
  34. }
  35. @Bean
  36. public ViewResolver viewResolver() {
  37. var resolver = new ThymeleafViewResolver();
  38. var registry = new ViewResolverRegistry(null, applicationContext);
  39. resolver.setTemplateEngine(templateEngine());
  40. registry.viewResolver(resolver);
  41. return resolver;
  42. }
  43. }

WebConfig配置 Thymeleaf 模板引擎。 Thymeleaf 模板文件位于类路径的templates子目录中。

com/zetcode/controller/MyController.java

  1. package com.zetcode.controller;
  2. import org.springframework.http.MediaType;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.ui.Model;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import java.time.LocalDateTime;
  7. @Controller
  8. public class MyController {
  9. @GetMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE)
  10. public String home(Model model) {
  11. model.addAttribute("now", LocalDateTime.now());
  12. return "index";
  13. }
  14. }

MyController包含主页的一种路由。

com/zetcode/controller/ControllerAdvisor.java

  1. package com.zetcode.controller;
  2. import org.springframework.web.bind.annotation.ControllerAdvice;
  3. import org.springframework.web.bind.annotation.ExceptionHandler;
  4. import org.springframework.web.servlet.ModelAndView;
  5. import org.springframework.web.servlet.NoHandlerFoundException;
  6. @ControllerAdvice
  7. public class ControllerAdvisor {
  8. @ExceptionHandler(NoHandlerFoundException.class)
  9. public ModelAndView handle(Exception ex) {
  10. var mv = new ModelAndView();
  11. mv.addObject("message", ex.getMessage());
  12. mv.setViewName("error/404");
  13. return mv;
  14. }
  15. }

ControllerAdvisor包含NoHandlerFoundException的处理器。 它显示404.html错误页面,位于resources/templates/error/404.html中。

resources/templates/error/404.html

  1. <!doctype html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Resource not found</title>
  7. </head>
  8. <body>
  9. <h2>404 - resource not found</h2>
  10. <p>
  11. <span th:text="${message}" th:remove="tag"></span>
  12. </p>
  13. </body>
  14. </html>

404.html是我们的自定义 404 错误页面。

resources/templates/index.html

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Home page</title>
  6. </head>
  7. <body>
  8. <p>
  9. This is home page.
  10. </p>
  11. <p>
  12. Today is <span th:text="${now}"></span>
  13. </p>
  14. </body>
  15. </html>

这是主页。

在本教程中,我们在 Spring 应用中创建了一个自定义 404 错误页面。

您可能也对这些相关教程感兴趣: Spring WebJars 教程Spring @GetMapping教程Spring DefaultServlet教程Spring Web 应用简介Java 教程