上一章我们在项目中整合了redis和RabbitMq,这一章我们整合Swagger3和自定义异常。
1. common工程引入swagger
在common工程pom.xml引入swagger依赖,我这边引用的是swagger3.0依赖
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
在common工程config目录添加swagger需要的配置类
package com.swh.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
* @author songWenHao
*/
@Configuration
@EnableOpenApi
public class SwaggerConfiguration {
/**
* 配置基本信息
* @return
*/
@Bean
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger Test App Restful API")
.description("Swagger Test App Restful API")
.termsOfServiceUrl("https://dev.infol.com")
.contact(new Contact("springboot项目搭建","https://blog.csdn.net/weixin_43470322/article","xxxxx@XXXX.com"))
.version("1.0.0")
.build();
}
/**
* 配置文档生成最佳实践
* @param apiInfo
* @return
*/
@Bean
public Docket createRestApi(ApiInfo apiInfo) {
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo)
.groupName("SwaggerGroupOneAPI")
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.paths(PathSelectors.any())
.build();
}
}
如果你想给swagger添加全局通用参数可以修改刚刚的配置类,我这边就加上了全局参数token和开发调试的auth
package com.swh.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
* @author songWenHao
*/
@Configuration
@EnableOpenApi
public class SwaggerConfiguration {
/**
* 配置基本信息
* @return
*/
@Bean
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger Test App Restful API")
.description("Swagger Test App Restful API")
.termsOfServiceUrl("https://dev.infol.com")
.contact(new Contact("南京瀚元科技","http://njhyst.com/","xxxxx@XXXX.com"))
.version("1.0.0")
.build();
}
/**
* 配置文档生成最佳实践
* @param apiInfo
* @return
*/
@Bean
public Docket createRestApi(ApiInfo apiInfo) {
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo)
.groupName("SwaggerGroupOneAPI")
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.paths(PathSelectors.any())
.build().globalRequestParameters(getGlobalRequestParameters());
}
//生成全局通用参数
private List<RequestParameter> getGlobalRequestParameters() {
List<RequestParameter> parameters = new ArrayList<>();
parameters.add(new RequestParameterBuilder()
.name("internal-auth")
.description("开发调试")
.required(true)
.in(ParameterType.HEADER)
.query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)).defaultValue("OK"))
.required(false)
.build());
parameters.add(new RequestParameterBuilder()
.name("Authorization")
.description("客户端登录token")
.required(false)
.in(ParameterType.HEADER)
.query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
.required(false)
.build());
return parameters;
}
}
2.全局异常处理
首先在common工程exception目录创建一个自定义异常类
package com.hy.common.exception;
import com.hy.common.result.IResultCode;
/**
* @ClassName: RequestException
* @Description:
* @Author: songWenHao
* @Date: 2022/5/30 13:26
*/
public class RequestException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String code;
private String message;
public RequestException(String code, String messages) {
super(messages);
this.code = code;
this.message = messages;
}
public RequestException(IResultCode httpCode) {
super(httpCode.getMsg());
this.code = httpCode.getCode();
this.message = httpCode.getMsg();
}
public RequestException(String message){
this.message = message;
}
public RequestException() {
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessages() {
return message;
}
public void setMessages(String messages) {
this.message = messages;
}
}
然后再创建一个全局异常处理类
package com.hy.common.exception;
import com.hy.common.result.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.stream.Collectors;
/**
* GlobalException Handler Class
* @author songWenHao
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 请求异常,异常信息将以AjaxResult格式返回前端
*
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler({Exception.class})
public Object handler(Exception e, ServerHttpResponse response) {
// Default Exception HttpCode 400
response.setStatusCode(HttpStatus.valueOf(HttpStatus.BAD_REQUEST.value()));
if (e instanceof RequestException) {
// 400
if (e instanceof BadRequestException) {
response.setStatusCode(HttpStatus.valueOf(HttpStatus.BAD_REQUEST.value()));
return AjaxResult.errorOf(String.valueOf(HttpStatus.BAD_REQUEST.value()), HttpStatus.BAD_REQUEST.getReasonPhrase());
}
// 401
if (e instanceof UnauthorizedException) {
response.setStatusCode(HttpStatus.valueOf(HttpStatus.UNAUTHORIZED.value()));
return AjaxResult.errorOf(String.valueOf(HttpStatus.UNAUTHORIZED.value()), HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
// 403
if (e instanceof ForbiddenException) {
response.setStatusCode(HttpStatus.valueOf(HttpStatus.FORBIDDEN.value()));
return AjaxResult.errorOf(String.valueOf(HttpStatus.FORBIDDEN.value()), HttpStatus.FORBIDDEN.getReasonPhrase());
}
return AjaxResult.errorOf(((RequestException) e).getCode(), e.getMessage());
}
// 412 Method Argument Not Valid
if (e instanceof MethodArgumentNotValidException) {
BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
if (bindingResult.hasErrors()) {
return AjaxResult.errorOf(String.valueOf(HttpStatus.PRECONDITION_FAILED.value()), String.format("Method Argument Not Valid, %s", bindingResult.getFieldErrors().parallelStream().map(FieldError::getField).collect(Collectors.joining("|"))));
}
}
e.printStackTrace();
return AjaxResult.errorOf(String.valueOf(HttpStatus.BAD_REQUEST.value()), "服务内部错误");
}
}