前言
- 1. SpringBoot + Swagger2(BootStrapUI)
- 2. 支持多个包扫描范围配置,以及设置接口文档header中默认token
- 3. 具体接口注解类详解
SpringBoot 集成
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
import cn.hutool.core.util.StrUtil;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfiguration {
/** 分隔符 */
private static final String SEPARATOR = ":";
/** 端口号 */
@Value("${server.port}")
private String port;
/**
* 创建rest api
*
* @return {@link Docket}
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.host("localhost:" + ("80".equals(port) ? "" : port))
.apiInfo(apiInfo())
.select()
//控制器位置
.apis(scanBasePackage("com.oaein.module.common.controller" + SEPARATOR
+ "com.oaein.third.email.controller"))
.paths(PathSelectors.any())
.build()
.globalOperationParameters(setHeaderToken());
}
/**
* api信息
*
* @return {@link ApiInfo}
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 标题
.title("platform-service api doc")
// 描述
.description("平台服务接口文档")
// 联系人
.contact(new Contact("ao.nie", "", "oaein_9@163.com"))
// 版本号
.version("1.0")
.build();
}
/**
* 添加token认证
*
* @return List<Parameter>
*/
private List<Parameter> setHeaderToken() {
List<Parameter> pars = new ArrayList<>();
ParameterBuilder tokenPar = new ParameterBuilder();
tokenPar.name("Authorization").defaultValue("Bearer b3ef9786-48ea-4edb-ad7f-489ab3b5daad")
.description("Authorization")
.modelRef(new ModelRef("string"))
.parameterType("header").required(true).build();
pars.add(tokenPar.build());
return pars;
}
/**
* 扫描基础包
*
* @param basePackage 基本包
* @return {@link Predicate}<{@link RequestHandler}>
*/
public static Predicate<RequestHandler> scanBasePackage(final String basePackage) {
String[] controllerPack = basePackage.split(SEPARATOR);
Predicate<RequestHandler> predicate = null;
for (int i = controllerPack.length - 1; i >= 0; i--) {
String strBasePackage = controllerPack[i];
if (StrUtil.isNotBlank(strBasePackage)) {
Predicate<RequestHandler> tempPredicate = RequestHandlerSelectors.basePackage(strBasePackage);
predicate = predicate == null ? tempPredicate : Predicates.or(tempPredicate, predicate);
}
}
return predicate;
}
}
此处,我集成了Shiro对所有资源进行拦截,需要在配置类中将Swagger相关的资源白名单放行。
filterMap.put("/**/*.js", "anon");
filterMap.put("/**/*.html", "anon");
filterMap.put("/**/*.css", "anon");
filterMap.put("/**/v2/**", "anon");
filterMap.put("/**/*.ico", "anon");
filterMap.put("/**/webjars/**", "anon");
filterMap.put("/**/swagger-resources/**", "anon");
项目启动成功访问 http://ip:port/doc.html
常用注解
@Api 类说明
作用于类上,是对请求类的说明
常用属性:tags、value(都是对类的说明,设置了tags后会对value进行覆盖重写)
// 1. @Api 作用于类上,是对请求类的说明,
// tags,value 都是对类的说明,设置了tags后会对value进行重写
@RestController
@Api(tags = "接口文档示例")
@RequestMapping(value = "/swagger")
public class Swagger2Controller {
}
@ApiOperation 方法描述
方法描述说明
常用属性:value:功能名、notes:接口描述、response:设置响应值
@ApiOperation(value = "新增", notes = "备注信息3",response = SwaggerVO.class )
public void add(@RequestBody SwaggerVO vo){
}
@ApiImplicitParams 参数描述
方法参数描述
/**
* @ApiImplicitParams 参数列表
* - @ApiImplicitParam 单个参数
* - name 参数名
* - value 参数描述
* - required 是否必填
* - paramType 参数类型
* · query --> 请求参数的获取:@RequestParam
* · header --> 请求参数的获取:@RequestHeader
* · path(用于restful接口)--> 请求参数的获取:@PathVariable
* · body(请求体)--> @RequestBody User user
* · form(普通表单提交)
* - dataType 数据类型
* - dataTypeClass 数据类型
* - defaultValue 参数默认值
*/
@ApiImplicitParams({
@ApiImplicitParam(name = "username", value = "用户名", required = false, paramType = "query", dataTypeClass = String.class),
@ApiImplicitParam(name = "age", value = "年龄", required = true, paramType = "query", dataTypeClass = Integer.class),
@ApiImplicitParam(name = "birthDay", value = "生日", required = true, paramType = "query", dataTypeClass = LocalDate.class)
})
public Result list(String username, Integer age, LocalDate birthDay) {
return Result.success();
}
@ApiResponses 响应结果
响应结果描述
属性:code:响应结果值、message:响应描述、response:响应结果集
// 4. 响应结果
@ApiResponses({
@ApiResponse(code = 200, message = "user", response = SwaggerVO.class),
})
@ApiResponses({
@ApiResponse(code = 200, message = "user", response = SwaggerVO.class),
})
public Result swagger() {
Map<String, SwaggerVO> resultMap = new HashMap<>();
resultMap.put("user", new SwaggerVO());
return Result.success(resultMap);
}
@ApiModel、@ApiModelProperty
实体类及参数描述描述
@Data
@ApiModel(description = "swagger示例对象")
public class SwaggerVO {
@ApiModelProperty(value = "主键id")
private Long id;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "生日")
private LocalDate birthDay;
@ApiModelProperty(value = "金额")
private BigDecimal moneyAmount;
@ApiModelProperty(value = "年龄")
private Integer age;
@ApiModelProperty(value = "是否启用")
private Boolean enabledFlag;
@ApiModelProperty(value = "兴趣爱好")
private List<String> hobbyList;
}
map类型响应结果
@GetMapping("/map")
@ApiOperation(value = "获取信息", notes = "备注信息6")
@ApiOperationSupport(order = 1, author = "ao.nie",
responses = @DynamicResponseParameters(properties = {
@DynamicParameter(value = "数据id", name = "id", dataTypeClass = String.class),
@DynamicParameter(value = "姓名", name = "name", dataTypeClass = String.class),
@DynamicParameter(value = "年龄", name = "age", dataTypeClass = String.class),
})
)
public Result mapData() {
Map<String, String> resultMap = new HashMap<>();
resultMap.put("id", "1");
resultMap.put("name", "小王");
resultMap.put("age", "24");
return Result.success(resultMap);
}