OpenAPI 抛出无法解析引用:无法解析指针:@ExampleObject 文件
OpenAPI throws Could not resolve reference: Could not resolve pointer: for @ExampleObject files
我正在开发一个基于 Quarkus 服务的应用程序,我正在为其添加基于 open API
的注释,例如 @ExampleObject
。为此,我想添加资源文件内容作为可以出现在 SwaggerUI
.
中的示例
当我从资源文件夹中添加对文件的引用时,出现以下错误:
Errors
Resolver error at paths./api/generateTestData.post.requestBody.content.application/json.examples.Example1 Schema.$ref
Could not resolve reference: Could not resolve pointer: /Example1.json does not exist in document
Resolver error at paths./api/generateTestData.post.requestBody.content.application/json.examples.Example2 Schema.$ref
Could not resolve reference: Could not resolve pointer: /Example2.json does not exist in document
以下是我的Quarkus based Java code
:
@RequestBody(description = "InputTemplate body",
content = @Content(schema = @Schema(implementation = InputTemplate.class), examples = {
@ExampleObject(name = "Example-1",
description = "Example-1 for InputTemplate.",
ref = "#/resources/Example1.json"), externalValue = "#/resources/Example2.json"
@ExampleObject(name = "Example-2",
description = "Example-2 for InputTemplate.",
ref = "#/resources/Example1.json") //externalValue = "#/resources/Example1.json"
}))
注意:
我可以将 String
添加为 value
,但是这些示例的内容非常大,所以我只想从文件中读取,所以尝试这种方法。
有什么方法可以访问资源文件并将其作为 ref
添加到我的 @ExampleObject
中
下面的工作示例:
创建一个实现 OASFilter
:
的 OASModelFilter class
package org.acme;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.microprofile.openapi.OASFactory;
import org.eclipse.microprofile.openapi.OASFilter;
import org.eclipse.microprofile.openapi.models.Components;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.microprofile.openapi.models.examples.Example;
public class OASModelFilter implements OASFilter {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public void filterOpenAPI(OpenAPI openAPI) {
//openApi.getComponents() will result in NULL as we don't have any openapi.yaml file.
Components defaultComponents = OASFactory.createComponents();
if(openAPI.getComponents() == null){
openAPI.setComponents(defaultComponents);
}
generateExamples().forEach(openAPI.getComponents()::addExample);
}
Map<String, Example> generateExamples() {
Map<String, Example> examples = new LinkedHashMap<>();
try {
//loop over your Example JSON Files,..
//In this case, the example is only for 1 file.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream userJsonFileInputStream = loader.getResourceAsStream("user.json");
String fileJSONContents = new String(userJsonFileInputStream.readAllBytes(), StandardCharsets.UTF_8);
//Create a unique example for each File/JSON
Example createExample = OASFactory.createExample()
.description("User JSON Description")
.value(objectMapper.readValue(fileJSONContents, ObjectNode.class));
// Save your Example with a Unique Map Key.
examples.put("createExample", createExample);
} catch (IOException ioException) {
System.out.println("An error occured" + ioException);
}
return examples;
}
}
控制器使用createExample
作为其@ExampleObject
。
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
@APIResponses(
value = {
@APIResponse(responseCode = "200", content = @Content(
mediaType = "*/*",
examples = {
@ExampleObject(name = "boo",
summary = "example of boo",
ref = "createExample")
}
))
}
)
public String hello() {
return "Hello RESTEasy";
}
}
在您的 application.properties 中指定以下内容:请注意,它引用了过滤器的完整包路径。
mp.openapi.filter=org.acme.OASModelFilter
user.json 文件的内容:
{
"hello": "world",
"my": "json",
"testing": "manually adding resource JSONs as examples"
}
使用的JSON文件直接位于资源下。当然,您可以更改该路径,但您需要更新您的 InputStream。
mvn clean install
mvn quarkus:dev
转到 http://localhost:8080/q/swagger-ui/
,您现在将看到显示的 user.json 文件内容
希望对您有所帮助,
我的调查参考资料:
编辑:这在 spring-boot
中运行良好
上面的答案可能有效,但要放入太多代码才能使其有效。
Instead, you can use externalValue field to pass on the JSON file.
例如,
@ExampleObject(
summary = "temp",
name =
"A 500 error",
externalValue = "/response.json"
)
现在您可以在 /resources/static 下创建 json 文件,如下所示,
Swagger 文档截图
这就是您所需要的。您无需在此处编写任何手动代码。
希望这能帮助您解决问题。
以下有效,但如您所见,我正在创建 PATHS,您仍然需要知道 (path/address/is) 是什么才能创建路径。
它可以帮助您思考以不同的方式处理它。
如果您正在考虑直接修改 @ApiResponses/@ApiResponse
注释,那将行不通。
package org.acme;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.microprofile.openapi.OASFactory;
import org.eclipse.microprofile.openapi.OASFilter;
import org.eclipse.microprofile.openapi.models.Components;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.microprofile.openapi.models.examples.Example;
import io.quarkus.logging.Log;
public class CustomOASFilter implements OASFilter {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public void filterOpenAPI(OpenAPI openAPI) {
//openApi.getComponents() will result in NULL as we don't have any openapi.yaml file.
Components defaultComponents = OASFactory.createComponents();
if (openAPI.getComponents() == null) {
openAPI.setComponents(defaultComponents);
}
generateExamples().forEach(openAPI.getComponents()::addExample);
openAPI.setPaths(OASFactory.createPaths()
.addPathItem(
"/hello/customer", OASFactory.createPathItem()
.GET(
OASFactory.createOperation()
.operationId("hello-customer-get")
.summary("A simple get call")
.description("Getting customer information")
.responses(
OASFactory.createAPIResponses()
.addAPIResponse(
"200", OASFactory.createAPIResponse()
.content(OASFactory.createContent()
.addMediaType("application/json", OASFactory.createMediaType()
.examples(generateExamples()))))))));
}
Map<String, Example> generateExamples() {
Map<String, Example> examples = new LinkedHashMap<>();
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String userJSON = new String(loader.getResourceAsStream("user.json").readAllBytes(), StandardCharsets.UTF_8);
String customerJson = new String(loader.getResourceAsStream("customer.json").readAllBytes(), StandardCharsets.UTF_8);
Example userExample = OASFactory.createExample()
.description("User JSON Example Description")
.value(objectMapper.readValue(userJSON, ObjectNode.class));
Example customerExample = OASFactory.createExample()
.description("Customer JSON Example Description")
.value(objectMapper.readValue(customerJson, ObjectNode.class));
examples.put("userExample", userExample);
examples.put("customerExample", customerExample);
} catch (IOException ioException) {
Log.error(ioException);
}
return examples;
}
}
我正在开发一个基于 Quarkus 服务的应用程序,我正在为其添加基于 open API
的注释,例如 @ExampleObject
。为此,我想添加资源文件内容作为可以出现在 SwaggerUI
.
当我从资源文件夹中添加对文件的引用时,出现以下错误:
Errors
Resolver error at paths./api/generateTestData.post.requestBody.content.application/json.examples.Example1 Schema.$ref
Could not resolve reference: Could not resolve pointer: /Example1.json does not exist in document
Resolver error at paths./api/generateTestData.post.requestBody.content.application/json.examples.Example2 Schema.$ref
Could not resolve reference: Could not resolve pointer: /Example2.json does not exist in document
以下是我的Quarkus based Java code
:
@RequestBody(description = "InputTemplate body",
content = @Content(schema = @Schema(implementation = InputTemplate.class), examples = {
@ExampleObject(name = "Example-1",
description = "Example-1 for InputTemplate.",
ref = "#/resources/Example1.json"), externalValue = "#/resources/Example2.json"
@ExampleObject(name = "Example-2",
description = "Example-2 for InputTemplate.",
ref = "#/resources/Example1.json") //externalValue = "#/resources/Example1.json"
}))
注意:
我可以将 String
添加为 value
,但是这些示例的内容非常大,所以我只想从文件中读取,所以尝试这种方法。
有什么方法可以访问资源文件并将其作为 ref
添加到我的 @ExampleObject
下面的工作示例:
创建一个实现 OASFilter
:
package org.acme;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.microprofile.openapi.OASFactory;
import org.eclipse.microprofile.openapi.OASFilter;
import org.eclipse.microprofile.openapi.models.Components;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.microprofile.openapi.models.examples.Example;
public class OASModelFilter implements OASFilter {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public void filterOpenAPI(OpenAPI openAPI) {
//openApi.getComponents() will result in NULL as we don't have any openapi.yaml file.
Components defaultComponents = OASFactory.createComponents();
if(openAPI.getComponents() == null){
openAPI.setComponents(defaultComponents);
}
generateExamples().forEach(openAPI.getComponents()::addExample);
}
Map<String, Example> generateExamples() {
Map<String, Example> examples = new LinkedHashMap<>();
try {
//loop over your Example JSON Files,..
//In this case, the example is only for 1 file.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream userJsonFileInputStream = loader.getResourceAsStream("user.json");
String fileJSONContents = new String(userJsonFileInputStream.readAllBytes(), StandardCharsets.UTF_8);
//Create a unique example for each File/JSON
Example createExample = OASFactory.createExample()
.description("User JSON Description")
.value(objectMapper.readValue(fileJSONContents, ObjectNode.class));
// Save your Example with a Unique Map Key.
examples.put("createExample", createExample);
} catch (IOException ioException) {
System.out.println("An error occured" + ioException);
}
return examples;
}
}
控制器使用createExample
作为其@ExampleObject
。
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
@APIResponses(
value = {
@APIResponse(responseCode = "200", content = @Content(
mediaType = "*/*",
examples = {
@ExampleObject(name = "boo",
summary = "example of boo",
ref = "createExample")
}
))
}
)
public String hello() {
return "Hello RESTEasy";
}
}
在您的 application.properties 中指定以下内容:请注意,它引用了过滤器的完整包路径。
mp.openapi.filter=org.acme.OASModelFilter
user.json 文件的内容:
{
"hello": "world",
"my": "json",
"testing": "manually adding resource JSONs as examples"
}
使用的JSON文件直接位于资源下。当然,您可以更改该路径,但您需要更新您的 InputStream。
mvn clean install
mvn quarkus:dev
转到 http://localhost:8080/q/swagger-ui/
,您现在将看到显示的 user.json 文件内容
希望对您有所帮助,
我的调查参考资料:
编辑:这在 spring-boot
中运行良好上面的答案可能有效,但要放入太多代码才能使其有效。
Instead, you can use externalValue field to pass on the JSON file.
例如,
@ExampleObject(
summary = "temp",
name =
"A 500 error",
externalValue = "/response.json"
)
现在您可以在 /resources/static 下创建 json 文件,如下所示,
Swagger 文档截图
这就是您所需要的。您无需在此处编写任何手动代码。
希望这能帮助您解决问题。
以下有效,但如您所见,我正在创建 PATHS,您仍然需要知道 (path/address/is) 是什么才能创建路径。
它可以帮助您思考以不同的方式处理它。
如果您正在考虑直接修改 @ApiResponses/@ApiResponse
注释,那将行不通。
package org.acme;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.microprofile.openapi.OASFactory;
import org.eclipse.microprofile.openapi.OASFilter;
import org.eclipse.microprofile.openapi.models.Components;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.microprofile.openapi.models.examples.Example;
import io.quarkus.logging.Log;
public class CustomOASFilter implements OASFilter {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public void filterOpenAPI(OpenAPI openAPI) {
//openApi.getComponents() will result in NULL as we don't have any openapi.yaml file.
Components defaultComponents = OASFactory.createComponents();
if (openAPI.getComponents() == null) {
openAPI.setComponents(defaultComponents);
}
generateExamples().forEach(openAPI.getComponents()::addExample);
openAPI.setPaths(OASFactory.createPaths()
.addPathItem(
"/hello/customer", OASFactory.createPathItem()
.GET(
OASFactory.createOperation()
.operationId("hello-customer-get")
.summary("A simple get call")
.description("Getting customer information")
.responses(
OASFactory.createAPIResponses()
.addAPIResponse(
"200", OASFactory.createAPIResponse()
.content(OASFactory.createContent()
.addMediaType("application/json", OASFactory.createMediaType()
.examples(generateExamples()))))))));
}
Map<String, Example> generateExamples() {
Map<String, Example> examples = new LinkedHashMap<>();
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String userJSON = new String(loader.getResourceAsStream("user.json").readAllBytes(), StandardCharsets.UTF_8);
String customerJson = new String(loader.getResourceAsStream("customer.json").readAllBytes(), StandardCharsets.UTF_8);
Example userExample = OASFactory.createExample()
.description("User JSON Example Description")
.value(objectMapper.readValue(userJSON, ObjectNode.class));
Example customerExample = OASFactory.createExample()
.description("Customer JSON Example Description")
.value(objectMapper.readValue(customerJson, ObjectNode.class));
examples.put("userExample", userExample);
examples.put("customerExample", customerExample);
} catch (IOException ioException) {
Log.error(ioException);
}
return examples;
}
}