【问题标题】:JaxRS + RestEasy - How do you create your own @Context injected field?JaxRS + RestEasy - 如何创建自己的 @Context 注入字段?
【发布时间】:2020-03-08 08:39:36
【问题描述】:

关于 JBoss 7.1.0 上的 RestEASY 3.6.2 的问题。

我有以下可用的 JaxRS 服务:

@Path("my-service")
public class MyResource {
  @Context
  HttpServletRequest request;

  @GET
  @Path("get-stuff")
  @Produces(MediaType.APPLICATION_JSON)
  public Response doStuff() {
    MyCustomContext customContext = new MyCustomContext(request);
    // ... use the customContext here.
  }
}

按照目前的设置方式,每个 rest 方法都需要一个MyCustomContext customContext = new MyCustomContext(request);。这很烦人。

有没有办法注入MyCustomContext

@Path("my-service")
public class MyResource {
  @Context
  MyCustomContext context;

  @GET
  @Path("get-stuff")
  @Produces(MediaType.APPLICATION_JSON)
  public Response doStuff() {
    // ... use the customContext here.
  }
}

@Producer // ???
public class MyCustomContext {
  @Context
  HttpServletRequest request;

  public MyCustomContext() {
    // construct with request object.
  }
}

我发现大量链接暗示了一种方法可以做到这一点,但我没有找到。

【问题讨论】:

  • 请在您的问题中至少添加前 5 个“大量链接”。

标签: java jboss jax-rs resteasy


【解决方案1】:

我不知道用@Context 注入自定义类实例/bean 的任何方法。我想根据具体要求概述替代方法。

A) 根本不需要注射。

使您的自定义上下文成为您的 JAX-RS 资源类的类成员(而不是每个方法中的局部变量)。一旦容器创建了一个已初始化的资源类实例,就使用@PostConstruct 实例化您的自定义上下文。资源类必须是具有请求范围的 CDI-bean 才能工作。

@Path("my-service")
@RequestScoped // CDI-bean with request scope only
public class MyResource {

  @Context
  private HttpServletRequest request;

  private MyCustomContext customContext;

  @PostConstruct
  public void initialize() {
    this.customContext = new MyCustomContext(this.request); // request is initialized by the container already at this point
  }

  @GET
  @Path("get-stuff")
  @Produces(MediaType.APPLICATION_JSON)
  public Response doStuff() {
    // ... use the customContext here.
  }
}

B) 您的自定义上下文仅需要 HttpServletRequest 实例

除了通过@Context 的JAX-RS,通过@Inject 用于HttpServletRequest 的CDI also provides a predefined bean。您也可以使您的自定义上下文成为 CDI-bean 并注入该预定义的 CDI-bean。之后,您可以将您的自定义上下文注入您的 JAX-RS 资源(无论它是 EJB 还是 CDI-bean)。

@Dependent // make your custom context a CDI-bean
public class MyCustomContext {

  @Inject // inject predefined CDI-bean
  private HttpServletRequest request;
}
@Path("my-service")
@RequestScoped // either CDI-bean
//@Stateless // or EJB
public class MyResource {

  @Inject // inject custom context via CDI
  private MyCustomContext customContext;

  @GET
  @Path("get-stuff")
  @Produces(MediaType.APPLICATION_JSON)
  public Response doStuff() {
    // ... use the customContext here.
  }
}

C) 您的自定义上下文需要通过 provider specific @Context 提供的独占实例,例如Request

如果您通过 @Context 将实例注入到您的非 JAX-RS 自定义上下文 CDI-bean 中,它将是 null。您需要一些机制来从您的 JAX-RS 资源中提供注入的实例。通过 @Inject 在您的自定义上下文中让 CDI 负责注入,并通过 @Produces 向您的 JAX-RS 资源添加生产者方法将完成这项工作。

@Dependent // make your custom context a CDI-bean
public class MyCustomContext {

  //@Context // in non JAX-RS context the instance will be null
  @Inject // instead inject the JAX-RS context instance via CDI
  private Request request;
}
@Path("my-service")
@RequestScoped // either CDI-bean
//@Stateless // or EJB
public class MyResource {

  @Context // in JAX-RS context the instance will not be null
  private Request request;
  @Inject
  private MyCustomContext customContext;

  @Produces // provide the JAX-RS context instance for injection via CDI
  @RequestScoped
  public Request getContextRequest() {
    return this.request;
  }

  @GET
  @Path("get-stuff")
  @Produces(MediaType.APPLICATION_JSON)
  public Response doStuff() {
    // ... use the customContext here.
  }
}

【讨论】:

    猜你喜欢
    • 2019-08-31
    • 1970-01-01
    • 2014-12-04
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 2017-06-18
    相关资源
    最近更新 更多