Spring Boot对于异常的处理也做了不错的支持,它提供了一个@ControllerAdvice注解以及 @ExceptionHandler注解,前者是用来开启全局的异常捕获,后者则是说明捕获哪些异常,对这些捕获的异常进行处理。
测试代码项目结构图:
pom.xml:
4.0.0 org.springframework.boot spring-boot-starter-parent 2.6.2 jar com.kaven springboot 0.0.1-SNAPSHOT springboot springboot 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok org.springframework.boot spring-boot-maven-plugin
DeepLearningTrainException类(自定义异常):
package com.kaven.springboot.exception;
public class DeepLearningTrainException extends RuntimeException{
public String gpuMessage;
public DeepLearningTrainException(String message) {
this.gpuMessage = message;
}
public String addHandler(String handler) {
return this.gpuMessage + handler;
}
}
ResponseVO类(自定义响应封装类):
package com.kaven.springboot.vo; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Setter; @Setter @Builder @AllArgsConstructor public class ResponseVO{ public Integer code; public String message; public T data; }
DeepLearningController类(定义接口):
package com.kaven.springboot.controller;
import com.kaven.springboot.exception.DeepLearningTrainException;
import com.kaven.springboot.vo.ResponseVO;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DeepLearningController {
@GetMapping("/train/{gpu}")
public ResponseVO train(@PathVariable(name = "gpu") boolean gpu) {
System.out.println("方面级情感分析模型正在训练...");
System.out.println("GPU显存不足");
if(gpu) throw new DeepLearningTrainException("方面级情感分析模型训练失败,GPU显存不足");
else System.out.println("方面级情感分析模型训练成功");
return new ResponseVO<>(HttpStatus.OK.value(), HttpStatus.OK.name(), "训练成功");
}
}
GlobalExceptionHandler类(全局异常处理):
package com.kaven.springboot.handler.exception;
import com.kaven.springboot.exception.DeepLearningTrainException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(DeepLearningTrainException.class)
public String DeepLearningTrainExceptionHandler(Exception e) {
DeepLearningTrainException exception = (DeepLearningTrainException) e;
return exception.addHandler("[DeepLearningTrainExceptionHandler]");
}
}
@RestControllerAdvice注解组合了@ControllerAdvice和@ResponseBody这两个注解,因此全局异常处理方法可以以JSON数据进行响应。
SpringbootApplication类(启动类):
package com.kaven.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringbootApplication.class);
application.run(args);
}
}
application.properties(配置文件):
server.port=8080
Spring Boot应用的默认启动端口也是8080,这里只是为了演示。
启动应用,访问http://localhost:8080/train/true,响应如下图所示。
很显然针对自定义异常DeepLearningTrainException的全局异常处理起作用了。
访问http://localhost:8080/train/false,响应如下图所示。
默认情况下,Spring Boot是不会抛出404异常,所以@ControllerAdvice也不能捕获到404异常,比如访问http://localhost:8080/kaven。
就算添加针对异常NoHandlerFoundException的全局异常处理,也不能捕获到404异常。
@ExceptionHandler(NoHandlerFoundException.class)
public String NoHandlerFoundExceptionHandler(Exception e) {
NoHandlerFoundException exception = (NoHandlerFoundException) e;
return exception.getMessage() + "[NoHandlerFoundException]";
}
可以通过以下配置来让这个全局异常处理捕获到404异常(NoHandlerFoundException)。
spring.mvc.throw-exception-if-no-handler-found=true spring.web.resources.add-mappings=false
很显然针对异常NoHandlerFoundException的全局异常处理起作用了。
spring.mvc.throw-exception-if-no-handler-found=true
当发现404异常时直接抛出异常。
spring.web.resources.add-mappings=false
关闭默认的静态资源路径映射,这样404错误就能被捕获到,但是这个配置会让静态资源访问出现问题,也就是不适合前后端不分离的情况。
添加访问静态资源的接口,IndexController类(定义接口):
package com.kaven.springboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class IndexController {
@GetMapping("/index")
public String index() {
return "index";
}
}
index.html(静态资源):
添加配置:
spring.mvc.view.suffix=.html
访问http://localhost:8080/index,也被全局异常处理捕获了。
添加如下配置类,就能正常访问静态资源了。
package com.kaven.springboot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class ResourceConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
}
再添加配置:
spring.mvc.view.prefix=/static/
访问http://localhost:8080/index,就可以正常访问静态资源了,这些配置博主以后都会详细介绍。
也能正常请求其他接口。
Spring Boot全局异常处理就介绍到这里,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。



