云e办(后端)——Swagger2接口文档
接口文档:在前后端分离开发的项目中,后端写完代码后,需要将接口文档整理好发给前端,前端根据接口文档再去开发。
而Swagger是来自动生成接口文档。其优势:
- 当添加好配置信息、以及注解,就会自动生成接口文档。
- 接口文档还支持接口调试的功能,相当于替代了postMan来测试接口。
一、添加依赖
<!-- Swagger第三方ui依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!-- swagger2 依赖 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
二、生成文档
1、配置类:SwaggerConfig.java
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket createDocket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//为当前包下的controller生成api文档
.apis(RequestHandlerSelectors.basePackage("com.xxxx.server.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("云E办接口文档")
.description("云E办接口文档")
.contact(new Contact("xxxx","http:localhost:8081/doc.html","xxxx@xxxx.com"))
.version("1.0")
.build();
}
}
2、创建测试接口 Controller/helloController
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
进行测试
发现无法访问,这是因为Swagger的地址被SpringSecurity拦截。我们修改下SpringSecurity的配置,放行Swagger。
3.修改SecurityConfig
public void configure(WebSecurity web) throws Exception {
//放行静态资源
web.ignoring().antMatchers(
"/login",
"/logout",
"/css/**",
"/js/**",
"/index.html",
"/favicon.ico",
"/doc.html",
"/webjars/**",
"/swagger-resources/**",
"/v2/api-docs/**");
}
重启项目再次访问 /hello 接口
发现接口访问失败,提示暂未登录或token已经过期。这是因为 /hello 接口需要登录成功之后才能访问。
再次修改配置类:将Swagger2添加全局的Authorize
4、修改配置类:Swagger2添加全局的Authorize
因为springSecurity放行的路径只有以上的内容(Swagger 静态资源、登录登出),其他情况都是要求用户登录之后才能访问的接口。 那么如果想访问那么必须先登录,才能访问其他接口。
如果先登录,那么接口文档怎么办呢?
Swagger2提供了全局登录的功能。现在用的是jwt登录,返回的是jwt令牌,令牌是放在前端的请求头里面的,那么swagger文档也可以这样:先登录,然后把令牌放在全局的Authentication里面,然后文档相当于访问hello接口时,会携带jwt令牌,刚刚写的jwt令牌拦截器,如果有令牌就会自动登录,就可以访问的接口了。
Swagger2Config.java
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket createDocket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//为当前包下的controller生成api文档
.apis(RequestHandlerSelectors.basePackage("com.xxxx.server.controller"))
.paths(PathSelectors.any())
.build()
.securityContexts(securityContexts())
.securitySchemes(securitySchemes());
}
private List<SecurityContext> securityContexts(){
//需要认证的路径
List<SecurityContext> result = new ArrayList<>();
result.add(getContextByPath("/hello/.*"));
return result;
}
private SecurityContext getContextByPath(String pathRegex) {
return SecurityContext.builder()
//默认的授权
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex(pathRegex))
.build();
}
private List<SecurityReference> defaultAuth(){
List<SecurityReference> result = new ArrayList<>();
AuthorizationScope authorizationScope = new AuthorizationScope("global","accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
result.add(new SecurityReference("Authorization",authorizationScopes));
return result;
}
private List<ApiKey> securitySchemes(){
List<ApiKey> result = new ArrayList<>();
ApiKey apiKey =new ApiKey("Authorization","Authorization","Header");
result.add(apiKey);
return result;
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("云E办接口文档")
.description("云E办接口文档")
.contact(new Contact("xxxx","http:localhost:8081/doc.html","xxxx@xxxx.com"))
.version("1.0")
.build();
}
}
再次访问,然后进行登录 ,获取token
在Authorization中,先写Bearer在有一个空格,然后在写token信息。从而保存即可。这样就可以在接口文档中登录成功。
现在以及登录成功了,进行测试,访问某个接口数据: