第一种方式,实现ErrorPageRegistrar接口,指定异常状态码或者异常类和对应的跳转页面,如下:
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.edu.spring</groupId> <artifactId>springboot_web</artifactId> <version>1.0.0</version> <name>springboot_web</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
CommonErrorPageRegistrar.java,实现ErrorPageRegistrar接口,并且装配到spring容器中
package com.edu.spring.springboot; import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.ErrorPageRegistrar; import org.springframework.boot.web.server.ErrorPageRegistry; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @Component public class CommonErrorPageRegistrar implements ErrorPageRegistrar{ @Override public void registerErrorPages(ErrorPageRegistry registry) { ErrorPage e404=new ErrorPage(HttpStatus.NOT_FOUND,"/404.html"); ErrorPage e500=new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,"/500.html"); ErrorPage args=new ErrorPage(IllegalArgumentException.class,"/args.html"); ErrorPage nullpoint=new ErrorPage(NullPointerException.class,"/nullpoint.html"); registry.addErrorPages(e404,e500,args,nullpoint); } }
异常跳转页面如下:
UserController.java测试类
package com.edu.spring.springboot; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @RequestMapping("/user/innererror") public String innererror(){ System.out.println("============innererror============="); int a=10/0; return "innererror" +a; } @RequestMapping("/user/index") public String index(){ System.out.println("============index============="); throw new IllegalArgumentException("IllegalArgumentException抛出的异常"); } @RequestMapping("/user/empty") public String empty(){ System.out.println("============empty============="); throw new NullPointerException("NullPointerException抛出的异常"); } }
App.java,排除掉默认的处理类:ErrorMvcAutoConfiguration(高版本不用排除,本示例可以不排除)
package com.edu.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; @SpringBootApplication(exclude=ErrorMvcAutoConfiguration.class) public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
浏览器输入:http://localhost:8080/user/aaa ,该url不存在,跳转404页面,如下:
浏览器输入:http://localhost:8080/user/innererror ,跳转500页面,如下:
浏览器输入:http://localhost:8080/user/index ,跳转args页面,如下:
浏览器输入:http://localhost:8080/user/empty ,跳转空指针页面,如下:
假如程序抛出的异常满足多个匹配,到底匹配会匹配哪个,尚未看源码。
第二种方式,使用@ControllerAdvice、@ExceptionHandler注解,如下
BookController.java
package com.edu.spring.springboot; import java.io.FileNotFoundException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class BookController { @ExceptionHandler(value=Exception.class) public String error(Exception e){ return "found exception:"+e.getMessage(); } @RequestMapping("/book/error1") public String error1 () throws FileNotFoundException{ throw new FileNotFoundException(" book.txt not found"); } @RequestMapping("/book/error2") public String error2 () throws ClassNotFoundException{ throw new ClassNotFoundException(" Book class not found"); } }
UserController.java
package com.edu.spring.springboot; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @RequestMapping("/user/index") public String index(){ System.out.println("============index============="); throw new IllegalArgumentException("IllegalArgumentException抛出的异常"); } }
GlobalExceptionHandler.java
package com.edu.spring.springboot; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value=Exception.class) @ResponseBody public String error(Exception e){ return "global exception:"+e.getClass().getName(); } }
App.java
package com.edu.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
浏览器输入:http://localhost:8080/book/error1 ,被方法所在类中的@ExceptionHandler注解捕获,如下:
浏览器输入:http://localhost:8080/book/error2 ,被方法所在类中的@ExceptionHandler注解捕获,如下:
浏览器输入:http://localhost:8080/user/index ,被全局异常类GlobalExceptionHandler中的@ExceptionHandler注解捕获,如下:
说明:程序抛出的异常优先在本类中处理,如果本类中没有处理的方法,则全局异常会处理