java - 为什么Quarkus应用程序的相同RestApi在 'native'或 'jvm'模式下有不同的响应?

标签 java native quarkus

描述

下面的简单代码是 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”替换为普通类型,它们的行为相同。所以我想知道原生功能是如何让 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/

相关文章:

quarkus - 在 @ApplicationScoped bean 中注入(inject)实体管理器

java - 启动 Quarkus

java - 无法立即在 Facebook 中看到发布的消息

java - 为什么我不能将 List<X<Long>> 作为 List<X<?>> 的参数

java - 连接到远程主机时 VisualVM 的问题

c++ - 在 C++ 中创建 WinAPI GUI 应用程序的现代 native 方式

java - 将表面拟合到 java 中的 3D 数据点集合

c++ - 创建 CoApp .autopkg 将文件从 redist 包文件复制到 $(TargetDir) 的子目录

.net - 在 Powershell v3 中无需调用外部 EXE 即可确定 .NET 程序集是否为混合模式

java - 在 Quarkus 应用程序中注入(inject) ServletContext