一次掌握Swagger
Swagger介绍
Swagger是一个可以在线生成并且实时更新的API接口文档框架,可以直接集成在项目中
先上图:)

导入依赖
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
SpringMVC集成
springmvc.xml
SpringMVC的的配置文件中添加以下内容
<!-- 引入swagger相关 -->
<!-- 将SwaggerConfig配置类注入 -->
<bean class="com.djn.controller.Swagger2Config"/>
<!-- 引用Swagger 默认配置 -->
<bean class="springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration" id="swagger2Config"/>
<!--会去改目录下找相关资源 该目录在导入的依赖jar包中-->
<mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/" />
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>
SwaggerConfig
@Configuration:声明是一个配置类@EnableSwagger2:开启Swagger2@EnableWebMVC:开启默认的mvc配置- 该注解一定要添加,不然启动会出现No qualifying bean of type 'java.util.List<org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
.groupName("张三"):用于分组,该功能用于协同开发.select():扫描接口的方式.apis():扫描包RequestHandlerSelectors.basePackage("com.djn.controller"):只扫描com.djn.controller该包RequestHandlerSelectors.any():扫描全部(默认)RequestHandlerSelectors.none():不扫描
.paths:过滤PathSelectors.ant("/user"):只扫描包下的/user/*请求PathSelectors.any()PathSelectors.none()
.enable:是否可以访问swagger,传入boolean值,默认为true
@Configuration
@EnableSwagger2
@PropertySource("classpath:mall.properties")
public class Swagger2Config {
@Value("${swagger.enable}")
public Boolean flag;
//注入Bean,Docket是Swagger接口,提供默认配置和便捷配置
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("丁江楠")
.select()
.apis(RequestHandlerSelectors.basePackage("com.djn.controller"))
.build()
.enable(flag)
.apiInfo(apiInfo());
}
//swagger.html页面展示的信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SwaggerDemo项目接口文档")
.description("SwaggerDemo项目接口测试")
.version("1.0.0")
.termsOfServiceUrl("")
.license("")
.licenseUrl("")
.build();
}
}
Controller类
@RestController:@ResponseBody+@Controller,表示将方法的返回值转为特定的格式写入到response的body区域,从而返回给客户端- 如果没有@ResponseBody,默认会将方法的返回值封装为ModelView对象,从而跳转到视图
- 如果返回值是String,就直接将字符串返回给客户端,如果返回值是对象,会将对象转为json串返回给客户端
@ApiOperation:对方法的注释说明@GetMapping:用于映射get请求,这里不要使用@RequestMapping,不然会一个方法生成很多个item@ApiParam("用户ID"):对请求参数的注释说明@RequestBody:用于接受客户端传递的json字符串(请求体中的数据)
@RestController
public class HelloController {
@ApiOperation("Hello方法")
@GetMapping("/hello")
public String hello() {
return "hello";
}
//只要返回实体类就会添加到Swagger中
@ApiOperation("获取用户信息")
@GetMapping("/getUser")
public User getUser(@ApiParam("用户ID") Integer userId) {
return new User();
}
@ApiOperation("获取用户信息")
@PostMapping("/getUser2")
public User getUser(@ApiParam("用户ID") @RequestBody User user) {
int i= 1/0;
return new User(user.getName(),user.getAge(),user.getPassword());
}
}
Model类
@ApiModel:实体类的注释说明ApiModelProperty:实体类属性的说明- 属性必须要有getter方法或者声明为public,否则不会显示
@ApiModel("用户实体类")
public class User {
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("年龄")
private Integer age;
@ApiModelProperty("密码")
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
SpringBoot集成
与SpringMVC相似,不过不需要配置文件和@EnableWebMvc注解
业务场景
在开发环境开启Swagger,在线上环境关闭Swagger
因为Swagger启动是需要加载资源也就是占内存的,同时会将我们的接口暴露给别人,这肯定是死翘翘的~
- 通过配置文件中的值来控制:在配置文件中配置
swagger.enable,然后在SwaggerConfig获取值,从而将值传入到.enbale
@Configuration
@EnableSwagger2
@PropertySource("classpath:xxx.properties") //加载配置文件
public class Swagger2Config {
//获取开关值 boolean类型
@Value("${swagger.enable}")
public Boolean flag;
//注入Bean,Docket是Swagger接口,提供默认配置和便捷配置
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("丁江楠")
.select()
.apis(RequestHandlerSelectors.basePackage("com.djn.controller"))
.build()
.enable(flag) //赋值
.apiInfo(apiInfo());
}
//swagger.html页面展示的信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SwaggerDemo项目接口文档")
.description("SwaggerDemo项目接口测试")
.version("1.0.0")
.termsOfServiceUrl("")
.license("")
.licenseUrl("")
.build();
}
}
- 通过环境来配置:使用
@Profile注解:在类上添加@Profile("dev"):只有dev环境Swagger才生效
@Profile("dev") //只有dev环境才生效
@Configuration
@EnbaleWebMvc
@EnableSwagger2
public class Swagger2Config {
//注入Bean,Docket是Swagger接口,提供默认配置和便捷配置
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("丁江楠")
.select()
.apis(RequestHandlerSelectors.basePackage("com.djn.controller"))
.build()
.enable(true)
.apiInfo(apiInfo());
}
//swagger.html页面展示的信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SwaggerDemo项目接口文档")
.description("SwaggerDemo项目接口测试")
.version("1.0.0")
.termsOfServiceUrl("")
.license("")
.licenseUrl("")
.build();
}
}
忽略参数Class类型
今天写项目时发现的一个问题,先看一下不忽略有什么效果:
代码:
@ApiOperation("登录")
@PostMapping("/login")
public ServerResponse<User> login(@RequestParam("username") String username,
@RequestParam("password") String password,
HttpSession session) {
Subject subject = SecurityUtils.getSubject();
if (!subject.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
token.setRememberMe(true);
subject.login(token);
}
return ServerResponse.createBySuccess((User));
}
效果图:

可以看出,Swagger帮我们把HttpSession的参数也显示出来了,而HttpSession我们并不需要传参处理,如何解决?
两种方式:
第一种方式
在方法的参数前,添加
@ApiIgnore注解
@ApiOperation("登录")
@PostMapping("/login")
public ServerResponse<User> login(@RequestParam("username") String username,
@RequestParam("password") String password,
@ApiIgnore HttpSession session) {
Subject subject = SecurityUtils.getSubject();
if (!subject.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
token.setRememberMe(true);
subject.login(token);
}
return ServerResponse.createBySuccess((User));
}
虽然问题解决了,但是这不是最好的办法,假如我们有很多个接口都有HttpSession呢,岂不是每个方法都要加一个注解,又或者其他的对象,比如HttpServletRequest、HttpServletResponse都需要添加注解,所以看一下第二种方式
第二种方式
在创建Docket对象时,指定忽略相关的Class
使用ignoredParameterTypes方法传入我们要忽略的Class类型,可以传入多个
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("dingjn")
//扫描接口的方式
.select()
.apis(RequestHandlerSelectors.basePackage("com.djn.controller"))
.build()
//忽略Class,swagger参数中不显示
.ignoredParameterTypes(HttpSession.class)
.enable(true) //是否启动swagger
.apiInfo(apiInfo());
}
springFox默认为我们忽略了以下类型
private void initIgnorableTypes() {
ignored = newHashSet();
ignored.add(ServletRequest.class);
ignored.add(Class.class);
ignored.add(Void.class);
ignored.add(Void.TYPE);
ignored.add(HttpServletRequest.class);
ignored.add(HttpServletResponse.class);
ignored.add(HttpHeaders.class);
ignored.add(BindingResult.class);
ignored.add(ServletContext.class);
ignored.add(UriComponentsBuilder.class);
ignored.add(ApiIgnore.class); //Used to ignore parameters
}
最终效果图:

忽略字段
又发现了一个问题,所以再来更新一下~,因为有的时候我们传递的是一个对象,而对象里的字段有的是不想让前端传过来的,比如时间,所以需要做一个忽略
这个还是很简单的,不要慌,只需要在字段@ApiModelProperty(hidden = true)注解就OK了
@Data
@NoArgsConstructor
@ApiModel("用户信息")
public class User implements Serializable {
private Integer userId;
@ApiModelProperty("用户名名")
private String username;
@ApiModelProperty("密码")
private String password;
//该字段不显示在Swagger页面
@ApiModelProperty(hidden = true)
private Date createTime;
@ApiModelProperty(hidden = true)
private Date updateTime;
}
图我就不上了,自己试一下吧
结束~

浙公网安备 33010602011771号