我从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=
时,我得到了包含以下信息的页面:
Unable to render this definition
The provided definition does not specify a valid version field.
Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).
但是,当我访问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
,什么都没变...所以,我在深入挖掘...
在我做了斯威格测试之后:
@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......我禁用了Jackson@EnableAutoConfiguration(exclude = [(JacksonAutoConfiguration::class)])
,因为我(和我的同事)更喜欢GSON,但是它没有解释为什么在添加自定义的GsonHttpMessageConverter
之后序列化会出错。我不知道我做错了什么。这个openapiJson()
是端点,也许它会弄乱一些东西...我不知道。我没有任何想法。你有过类似的问题吗?你能给予点建议或提示吗?
PS.抱歉我的英语不好:)。
1条答案
按热度按时间lrpiutwd1#
我在一个用Java编写的项目中遇到了同样的问题,我刚刚通过定义一个过滤器来使用Gson格式化我的springdoc-openapi json文档,从而解决了这个问题。
您还必须仅为文档url模式注册过滤器。