Spring Boot配置Swagger与全局异常处理
@author 阿日哥
swagger的配置和全局异常处理基本上是Spring项目的一个必须环节了,做了几个项目之后觉得还是有必要总结一下的。
swagger配置
要进行swagger的配置,我们需要导入swagger ui和swagger2两个依赖,这里使用的版本是2.9.2。
swagger ui是用来渲染html界面的,记得不要忘了导入
<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger-ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
下面是swagger的配置类:
package cn.edu.whu.reservoir.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author thomas
* @version 1.0
* @date 2020/12/19 21:36 下午
* swagger配置
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.controller"))
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("标题")
.description("描述")
.termsOfServiceUrl("www.baidu.com")
.version("1.0")
.build();
}
}
一个很简单的配置类,没什么好说的,配置了标题描述等基本属性。
注意加上@EnableSwagger2
注解,表示启用swagger。
配置好了以后访问localhost:port/swagger-ui.html
(其中port是你程序运行的端口号),就能看到swagger的ui界面了。
全局异常处理
首先我们需要在application.yaml中配置spring的两个属性:
spring:
resources:
add-mappings: false
mvc:
throw-exception-if-no-handler-found: true
第一个属性的作用是为静态资源添加一个url映射,我们要将它设置为false,否则之后spring mvc遇到404异常时就会跳转到默认的/error地址,渲染一个默认的错误html界面。
第二个属性的作用是将404异常向上抛出,以便我们之后统一进行异常处理。
全局异常处理的两种方案
关于全局统一异常处理,目前大概有两种实现方案,第一种是使用RestControllerAdvice注解(其实就是ControllerAdvice注解的restful版本),第二种则是直接实现Spring的ErrorController接口。
下面大致讲一讲两者的区别。
使用@RestControllerAdvice注解
使用@RestControllerAdvice注解来实现很简单。
首先写一个异常处理类,然后加上@RestControllerAdvice注解,写好对应异常处理的方法,在每个方法体上加上@ExceptionHandler()注解,value的值就是你对应的要处理的异常,方法的参数就是对应的异常类。然后就能愉快的自定义你的异常处理过程啦~
package cn.edu.whu.reservoir.component;
import cn.edu.whu.reservoir.api.CommonResult;
import cn.edu.whu.reservoir.api.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MissingServletRequestParameterException;
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.servlet.NoHandlerFoundException;
/**
* @author thomas
* @version 1.0
* @date 2020/12/19 21:36 下午
* 统一异常处理
*/
@Slf4j
@Component
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* NoHandlerFoundException 404 异常处理
*/
@ExceptionHandler(value = NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.OK)
public CommonResult<?> handleNotFoundException(NoHandlerFoundException e) throws Throwable {
// 404不需要处理 直接返回就行
return CommonResult.fail(ResultCode.NotFound);
}
@ExceptionHandler(value = NullPointerException.class)
@ResponseStatus(HttpStatus.OK)
public CommonResult<?> handleNullPointerException(NullPointerException e) throws Throwable {
log.error(e.getMessage());
return CommonResult.fail(ResultCode.InternalServerError);
}
@ExceptionHandler(value = MissingServletRequestParameterException.class)
@ResponseStatus(HttpStatus.OK)
public CommonResult<?> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) throws Throwable {
log.error(e.getMessage());
return CommonResult.fail(ResultCode.InternalServerError);
}
@ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.OK)
public CommonResult<?> handleException(Exception e) throws Throwable {
log.error(e.getMessage());
return CommonResult.fail(ResultCode.InternalServerError);
}
}
实现ErrorController接口
ErrorController对比使用@ControllerAdvice主要是以下几点:
- ErrorController可对全局错误进行处理,但是其获取不到异常的具体信息,同时也无法根据异常类型进行不同的响应,例如对自定义异常的处理
- 而@ControllerAdvice可对全局异常进行捕获,包括自定义异常
- 需要清楚的是,其是应用于对springmvc中的控制器抛出的异常进行处理,而对于404这样不会进入控制器处理的异常不起作用,所以此时还是要依靠ErrorController来处理
关于使用ErrorController的实现也很简单,我这里没有实现,直接贴上一篇文章:
SpringBoot实战(03):全局异常处理ErrorController
Q.E.D.