我正在将旧的Quarkus项目从RESTEasy迁移到ResteasyReactive,我在迁移ResteasyContext.pushContext时遇到了一些困难,因为REST Easy中没有真正的1:1替代方案.

我使用ContainerRequestFilter中的ResteasyContext.pushContext将一些自定义对象推送到上下文,然后使用@Context检索它.

类似于我提供的这个最小示例中的内容.

过滤器:

package org.acme.filter;

import org.acme.pojo.CustomHttpRequest;
import org.jboss.resteasy.core.ResteasyContext;

import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;
import java.time.LocalDateTime;
import java.util.Random;

@Provider
@ApplicationScoped
public class HttpRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) {
        CustomHttpRequest request = CustomHttpRequest.builder()
                .headers(requestContext.getHeaders())
                .dateTime(LocalDateTime.now())
                .text("Some random text for example " + new Random().nextInt(100))
                .build();
        ResteasyContext.pushContext(CustomHttpRequest.class, request);
    }
}

我要推送到上下文的自定义对象:

package org.acme.pojo;

import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

import javax.ws.rs.core.MultivaluedMap;
import java.time.LocalDateTime;

@Getter
@Builder
@ToString
public class CustomHttpRequest {

    private String text;
    private LocalDateTime dateTime;
    private MultivaluedMap<String, String> headers;
    private boolean secured;
}

后者从我的REST端点的上下文中读取它:

package org.acme;

import org.acme.pojo.CustomHttpRequest;
import org.acme.pojo.ResponseData;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @GET
    @Path("{pathText}")
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseData testContext(@Context CustomHttpRequest httpRequest,
                                    @PathParam("pathText") String querryText) {

       return ResponseData.builder()
                .querryText(querryText)
                .httpRequestText(httpRequest.getText())
                .secured(httpRequest.isSecured())
                .build();
    }
}

以下是GitHub上的完整示例:https://github.com/pkristja/resteasy_context/tree/main

我发现了一些使用RestEasyReactive的替代方案,比如使用ContainerRequestContext并使用setProperty设置数据.

生成文件更改: 从implementation("io.quarkus:quarkus-resteasy-jackson")更改为implementation("io.quarkus:quarkus-resteasy-reactive-jackson")

用于将对象设置为上下文的筛选器:

package org.acme.filter;

import org.acme.pojo.CustomHttpRequest;

import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
import java.time.LocalDateTime;
import java.util.Random;

@Provider
@ApplicationScoped
public class HttpRequestFilter implements ContainerRequestFilter {

    @Context
    ContainerRequestContext crContext;

    @Override
    public void filter(ContainerRequestContext requestContext) {
        CustomHttpRequest request = CustomHttpRequest.builder()
                .headers(requestContext.getHeaders())
                .dateTime(LocalDateTime.now())
                .text("Some random text for example " + new Random().nextInt(100))
                .build();

        crContext.setProperty("customHttpRequest", request);
    }
}

正在从上下文中检索对象:

package org.acme;

import org.acme.pojo.CustomHttpRequest;
import org.acme.pojo.ResponseData;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @GET
    @Path("{pathText}")
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseData testContext(@Context ContainerRequestContext crContext,
                                    @PathParam("pathText") String querryText) {

        CustomHttpRequest httpRequest = (CustomHttpRequest) crContext.getProperty("customHttpRequest");

       return ResponseData.builder()
                .querryText(querryText)
                .httpRequestText(httpRequest.getText())
                .secured(httpRequest.isSecured())
                .build();
    }
}

有没有办法像您在使用ResteasyContext.pushContext的RestEasyReactive中那样在RestEasyReactive中获得相同的功能,因为从上下文中检索每个对象并强制转换它是非常繁琐和低效的,因为在我的真实示例中,我使用ResteasyContext.pushContext将多个自定义对象推送到上下文中.

谢谢!

推荐答案

在使用RESTEasy Active时,有一种简单得多的方法来完成这类工作:只需使用CDI请求作用域的Bean.

下面这样的内容应该就可以了:

@Singleton
public class CustomHttpRequestProducer {

    @RequestScoped
    @Unremovable
    public CustomHttpRequest produce(HttpHeaders headers) {
        return new CustomHttpRequest(headers.getRequestHeaders(), LocalDateTime.now(), "dummy");
    }
}

然后,您可以在JAX-RS资源中轻松地使用它,就像:

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello(@Context CustomHttpRequest customHttpRequest) {
    return customHttpRequest.getText();
}

请注意,只有在使用CustomHttpRequest 作为方法参数时才需要@Unremovable. 但是,如果您将其作为字段注入,则@Unremovable是不必要的.

UPDATE

https://github.com/quarkusio/quarkus/pull/33793成为Quarkus的一部分(可能在3.2中)之后,@Unremovable将不再是必需的,即使对于方法参数也是如此

Java相关问答推荐

使用Java Streams API比较两个不同的Java集合对象和一个公共属性

缩小画布比例后更改滚动窗格的内部大小

解析Javadoc时链接的全限定类名

我找不到&Quot;配置&的位置

这是什么Java构造`(InputStream Is)->;()->;{}`

Mapstruct不能正确/完全映射属性

计算两个浮点数之间的距离是否对称?

具有阻塞方法的开源库是否应该为执行提供异步选项?

匹配一组字符或另一组字符

如何在一行中使用Dijkstra中的Java Stream

带有Health Check的Spring Boot BuildPack打破了本机映像构建过程

如何在Cosmos DB(Java SDK)中增加默认响应大小

使用Jackson库反序列化json

有谁能帮我修一下这个吗?使输出变得更加整洁

如何调整JButton的大小以适应图标?

如何设计包含已知和未知键值对映射的Java类?

在单例类上获取Java锁,了解原因

Java返回生成器的实现

如何通过gradle命令行从build.gradle获得Java targetCompatibility

由于可为null,无法在kotlin中实现java接口