【发布时间】:2019-12-18 13:35:00
【问题描述】:
我从 Springfox Swagger 迁移到 Springdoc OpenApi。我在配置中添加了几行关于 springdoc 的内容:
springdoc:
pathsToMatch: /api/**
api-docs:
path: /api-docs
swagger-ui:
path: /swagger-ui.html
在配置类MainConfig.kt我有以下代码:
val customGson: Gson = GsonBuilder()
.registerTypeAdapter(LocalDateTime::class.java, DateSerializer())
.registerTypeAdapter(ZonedDateTime::class.java, ZonedDateSerializer())
.addSerializationExclusionStrategy(AnnotationExclusionStrategy())
.enableComplexMapKeySerialization()
.setPrettyPrinting()
.create()
override fun configureMessageConverters(converters: MutableList<HttpMessageConverter<*>>) {
converters.add(GsonHttpMessageConverter(customGson))
}
当我转到 http://localhost:8013/swagger-ui.html(在配置中我有 server.port: 8013)时,页面不会重定向到 swagger-ui/index.html?url=/api-docs&validatorUrl=。但这不是我的主要问题:)。当我转到swagger-ui/index.html?url=/api-docs&validatorUrl= 时,我得到了包含以下信息的页面:
但是当我去 http://localhost:8013/api-docs 我有这个结果:
"{\"openapi\":\"3.0.1\",\"info\":{(...)}}"
我尝试使用默认配置并评论了configureMessageConverters() 方法和\api-docs 的结果现在看起来像普通的 JSON:
// 20191218134933
// http://localhost:8013/api-docs
{
"openapi": "3.0.1",
"info": {(...)}
}
我记得当我使用 Springfox 时,序列化出了点问题,我的 customGson 多了一行:.registerTypeAdapter(Json::class.java, JsonSerializer<Json> { src, _, _ -> JsonParser.parseString(src.value()) })
我想知道我应该有特殊的JsonSerializer。调试后,我的第一个想法是导致 io.swagger.v3.oas.models 包中的 OpenApi 类。我添加了这段代码:.registerTypeAdapter(OpenAPI::class.java, JsonSerializer<OpenAPI> { _, _, _ -> JsonParser.parseString("") }) 到 customGson 并没有任何改变......所以,我正在深入挖掘......
在我运行 Swagger 测试之后:
@EnableAutoConfiguration
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ExtendWith(SpringExtension::class)
@ActiveProfiles("test")
class SwaggerIntegrationTest(@Autowired private val mockMvc: MockMvc) {
@Test
fun `should display Swagger UI page`() {
val result = mockMvc.perform(MockMvcRequestBuilders.get("/swagger-ui/index.html"))
.andExpect(status().isOk)
.andReturn()
assertTrue(result.response.contentAsString.contains("Swagger UI"))
}
@Disabled("Redirect doesn't work. Check it later")
@Test
fun `should display Swagger UI page with redirect`() {
mockMvc.perform(MockMvcRequestBuilders.get("/swagger-ui.html"))
.andExpect(status().isOk)
.andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.TEXT_HTML))
}
@Test
fun `should get api docs`() {
mockMvc.perform(MockMvcRequestBuilders.get("/api-docs"))
.andExpect(status().isOk)
.andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.jsonPath("\$.openapi").exists())
}
}
我在控制台中看到了这个:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /api-docs
Parameters = {}
Headers = []
Body = null
Session Attrs = {}
Handler:
Type = org.springdoc.api.OpenApiResource
Method = org.springdoc.api.OpenApiResource#openapiJson(HttpServletRequest, String)
接下来我在OpenApiResource 中检查openapiJson 和...
@Operation(hidden = true)
@GetMapping(value = API_DOCS_URL, produces = MediaType.APPLICATION_JSON_VALUE)
public String openapiJson(HttpServletRequest request, @Value(API_DOCS_URL) String apiDocsUrl)
throws JsonProcessingException {
calculateServerUrl(request, apiDocsUrl);
OpenAPI openAPI = this.getOpenApi();
return Json.mapper().writeValueAsString(openAPI);
}
好的,Jackson... 我已通过 @EnableAutoConfiguration(exclude = [(JacksonAutoConfiguration::class)]) 禁用 Jackson,因为我(和我的同事)更喜欢 GSON,但这并不能解释为什么在添加自定义 GsonHttpMessageConverter 后序列化会出错。我不知道我做错了什么。这个openapiJson() 是端点,也许它搞砸了……我不知道。我没有任何想法。你有类似的问题吗?能给点建议或提示吗?
PS。对不起我的英语不好:)。
【问题讨论】:
标签: spring-boot kotlin gson swagger-ui openapi