创建REST API时,良好的文档是有帮助的。而且,API中的每一个变化都应该在参考文档中同时描述。手动完成这是一个乏味的操作,因此这个过程的自动化是不可避免的。
在本教程中,我们将看看 Swagger 2的Spring Boot REST Web服务。对于本文,我们将使用Swagger 2规范的 Springfox 实现。如果您对Swagger不熟悉,则应 在继续阅读本文之前访问swagger官网以了解更多信息。
我们在示例中使用的REST服务的创建不在本文的讨论范围之内。如果您已经有合适的项目,请使用它。如果没有,下面的链接是一个很好的开始:
提示:创建Spring Boot REST项目可以参考之前写的Swagger2入门篇
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
提示:现在已经有2.8.0版本。目前存在一些无法汉化的问题。暂不推荐正式项目升级。学习研究即可。
Swagger的配置主要围绕着 Docket bean。
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
Swagger 2通过@ EnableSwagger2 批注启用 。
在定义了Docket bean 之后,其 select() 方法返回一个ApiSelectorBuilder实例,该实例提供了一种控制Swagger公开的端点的方法。
可以使用RequestHandlerSelectors和PathSelectors来配置RequestHandler选择的谓词。使用 任何() 都可以通过Swagger为整个API提供文档。
这种配置足以将Swagger 2集成到现有的Spring Boot项目中。对于其他Spring项目,需要进行一些额外的调整。
如果没有Spring Boot,你无法自动配置资源处理程序。Swagger UI添加了一组资源,您必须将其配置为扩展WebMvcConfigurerAdapter的类的一部分 , 并使用@EnableWebMvc进行注释 。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
要验证Springfox是否正常工作,可以在浏览器中访问以下URL:
http://localhost:8080/spring-security-rest/api/v2/api-docs
结果是带有大量键值对的JSON响应,这不是非常容易理解的。幸运的是,Swagger 为此提供了Swagger UI。
Swagger UI是一个内置的解决方案,使得用户可以更轻松地与Swagger生成的API文档进行交互。
要使用Swagger UI,需要另外一个Maven依赖项:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
现在,您可以通过访问http://localhost:8080/your-app-root/swagger-ui.html在浏览器中对其进行测试
在我们的例子中,顺便说一下,确切的URL是http://localhost:8080/spring-security-rest/api/swagger-ui.html
结果应该如下所示:Swagger的回复中列出了您的应用程序中定义的所有控制器。点击其中的任何一个将列出有效的HTTP方法(DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT)。
展开每种方法都会提供其他有用的数据,例如响应状态,内容类型和参数列表。也可以使用UI来尝试每种方法。
Swagger与您的代码库同步的能力至关重要。为了演示这一点,你可以添加一个新的控制器到你的应用程序。
@RestController
public class CustomController {
@RequestMapping(value = "/custom", method = RequestMethod.POST)
public String custom() {
return "custom";
}
}
现在,如果刷新Swagger文档,您将在控制器列表中看到自定义控制器。如您所知,Swagger的回复中只显示一种方法(POST)。
应用程序的Docket bean可以配置为让您更多地控制API文档生成过程。
公开整个API的文档并不总是可取的。您可以通过将参数传递给Docket类的apis()和paths()方法来限制Swagger的响应 。
如上所示,RequestHandlerSelectors允许使用 any或none谓词,但也可用于根据基本包,类注释和方法注释过滤API。
PathSelectors提供了额外的过滤功能,并使用谓词来扫描应用程序的请求路径。你可以使用 any(),none(), regex()或 ant()。
在下面的示例中,我们将指示Swagger使用ant() 谓词仅包含特定包中的控制器,并使用特定的路径。
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("org.baeldung.web.controller"))
.paths(PathSelectors.ant("/foos/*"))
.build();
}
Swagger还在您的自定义响应中提供了一些默认值,例如“Api文档”,“由联系人电子邮件创建”,“Apache 2.0”。
要更改这些值,可以使用 apiInfo(ApiInfo apiInfo) 方法。包含有关API的自定义信息的 ApiInfo类。
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.ant("/foos/*"))
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfo(
"My REST API",
"Some custom description of API.",
"API TOS",
"Terms of service",
new Contact("John Doe", "www.example.com", "myeaddress@company.com"),
"License of API", "API license URL", Collections.emptyList());
}
Swagger允许通过 Docket的 globalResponseMessage()方法全局覆盖HTTP方法的响应消息。首先,您必须指示Swagger不要使用默认响应消息。
假设您希望覆盖 所有GET方法的500和403响应消息。为了达到这个目的,一些代码必须被添加到Docket的初始化块(为了清楚起见,原始冗余代码被排除):
.useDefaultResponseMessages(false)
.globalResponseMessage(RequestMethod.GET,
newArrayList(new ResponseMessageBuilder()
.code(500)
.message("500 message")
.responseModel(new ModelRef("Error"))
.build(),
new ResponseMessageBuilder()
.code(403)
.message("Forbidden!")
.build()));
Swagger UI提供了许多非常有用的功能 - 目前为止我们已经介绍了这些功能。但是如果我们的API是安全的并且不可访问的话,我们不能真正使用其中的大部分。
让我们看看我们如何允许Swagger访问OAuth安全的API--在本例中使用授权代码授权类型。
我们将使用SecurityScheme和SecurityContext支持配置Swagger以访问我们的安全API :
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.securitySchemes(Arrays.asList(securityScheme()))
.securityContexts(Arrays.asList(securityContext()));
}
我们将在Swagger配置中定义一个 SecurityConfiguration bean - 并设置一些默认值:
@Bean
public SecurityConfiguration security() {
return SecurityConfigurationBuilder.builder()
.clientId(CLIENT_ID)
.clientSecret(CLIENT_SECRET)
.scopeSeparator(" ")
.useBasicAuthenticationWithAccessCodeGrant(true)
.build();
}
接下来,我们将定义我们的SecurityScheme ; 这用于描述我们的API如何保护(基本认证,OAuth2,...)。
在我们的例子中,我们将定义一个用于保护我们的资源服务器的OAuth方案:
private SecurityScheme securityScheme() {
GrantType grantType = new AuthorizationCodeGrantBuilder()
.tokenEndpoint(new TokenEndpoint(AUTH_SERVER + "/token", "oauthtoken"))
.tokenRequestEndpoint(
new TokenRequestEndpoint(AUTH_SERVER + "/authorize", CLIENT_ID, CLIENT_ID))
.build();
SecurityScheme oauth = new OAuthBuilder().name("spring_oauth")
.grantTypes(Arrays.asList(grantType))
.scopes(Arrays.asList(scopes()))
.build();
return oauth;
}
请注意,我们使用了授权码授权类型 - 我们需要为其提供令牌端点以及我们的OAuth2授权服务器的授权URL。
以下是我们需要定义的范围:
private AuthorizationScope[] scopes() {
AuthorizationScope[] scopes = {
new AuthorizationScope("read", "for read operations"),
new AuthorizationScope("write", "for write operations"),
new AuthorizationScope("foo", "Access foo API") };
return scopes;
}
这些与我们在应用中实际定义的范围同步/ foos API。
最后,我们需要为我们的示例API定义一个安全上下文:
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(Arrays.asList(new SecurityReference("spring_oauth", scopes())))
.forPaths(PathSelectors.regex("/foos.*"))
.build();
}
请注意,我们在此处使用的名称(参考 - spring_oauth)与我们之前使用的名称在SecurityScheme中同步。
好吧,现在我们已经准备好了所有的东西,让我们来看看我们的Swagger UI并尝试访问Foo API:
我们可以在本地访问Swagger UI:
1
|
http: //localhost :8082 /spring-security-oauth-resource/swagger-ui .html
|
由于我们的安全配置,我们可以看到现在存在一个新的“授权”按钮:
注意:
以下是安全API的标记方式:
现在,最后,我们可以打我们的API!
当然,不言而喻,我们需要小心如何在外部公开Swagger UI,因为此安全配置处于活动状态。
在本教程中,我们设置了Swagger 2来为Spring REST API生成文档。我们还探索了可视化和自定义Swagger输出的方法。最后,我们查看了Swagger的一个简单的OAuth配置。
https://www.leftso.com/article/393.html