描述
下面的简单代码是 quarkus Rest api 使用响应式方法的演示:
@Consumes
@Produces(MediaType.APPLICATION_JSON)
@Path("/api/v1/datasource")
public class DatasourceResource {
@Inject
DatabaseBoundary databaseBoundary;
@POST
@Path("/query")
public Uni<Response> query(DatasourceQuery param) {
DatasourceRecordDTO result = new DatasourceRecordDTO();
result.setId("888");
List<String> header = Arrays.asList("id", "name", "age");
DatasourceRecordItem item = new DatasourceRecordItem();
item.setKey("888");
item.setValueList(Arrays.asList("123", "wkx", "26"));
result.setHeader(header);
result.setRows(List.of(item));
result.setContent("ok");
return Uni.createFrom().item(Response.ok(result).build());
}
}
我尝试用两种方式运行它:
- 1)直接在Intelij Idea中运行或构建后运行'quarkus-run.jar'
- 2)使用二进制可执行文件“xxx-SNAPSHOT-runner”运行或构建镜像以在 docker/k8s 中运行
使用第一种方式,我可以获得内容为“{xx:xx,xx:xx}”的正确响应:
但是,使用 The Seconde,我只能得到一个空响应“{}”:
问题
为什么在这两种运行模式下响应表现不同?
- Quarkus 版本:2.12.3.Final
- quarkus-resteasy-reactive-jackson:2.12.3.Final
- graalvm 版本:22.1.0-java11
- 系统:MacOS x86 64
我尝试将返回类型“Uni
最佳答案
这是不同的,因为 DatasourceRecordDTO
的序列化需要使用反射,GraalVM 默认情况下不启用反射。
因此,在您的情况下,如果您注释 DatasourceRecordDTO
与 @RegisterForReflection
,那么一切都应该按预期进行。
此外,如果您正在使用 RESTEasy Reactive,则可以使用 RestResponse<DatasourceRecordDTO>
而不是Response
,这将指示 Quarkus 自动注册 DatasourceRecordDTO
供反射(reflection)。
只是为了详细说明 Uni<Response>
:Quarkus 检查 JAX-RS 方法的返回类型(除其他外)以确定要注册反射的类型。自 Response
不包含通用类型,Quarkus 无法知道添加了什么类型的响应,因此无法自动注册该类型以进行反射。 RestResponse
另一个确实有一个泛型类型,因此 Quarkus 可以确定在这种情况下要做什么。
关于java - 为什么Quarkus应用程序的相同RestApi在 'native'或 'jvm'模式下有不同的响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74338101/