JaxRS + RestEasy - 如何创建自己的 @Context 注入字段?

JaxRS + RestEasy - How do you create your own @Context injected field?

关于 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.
  }
}

按照目前的设置方式,每个休息方法都需要 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.
  }
}

我发现了大量链接暗示了一种方法,但我一无所获。

我不知道用 @Context 注入自定义 class instance/bean 的任何方法。我想概述取决于具体要求的替代方法。

A) 根本不需要注射。

使自定义上下文成为 JAX-RS 资源 class 的 class 成员(而不是每个方法中的局部变量)。一旦容器创建了一个已初始化的资源 class 实例,利用 @PostConstruct 实例化您的自定义上下文。资源 class 必须是具有请求范围的 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 旁边,CDI also provides a predefined bean for HttpServletRequest via @Inject。您也可以使自定义上下文成为 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 e.g. 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.
  }
}