Question about RestEASY 3.6.2 on JBoss 7.1.0.
I have the following working JaxRS service:
@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.
}
}
With the way this is currently set up, every rest method requires a MyCustomContext customContext = new MyCustomContext(request);
. That is annoying.
Is there some way to inject the 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.
}
}
I have found a ton of links hinted towards a way to do this, but I am coming up empty.
I do not know any way of injecting a custom class instance/bean with @Context. I would like to outline alternative approaches that depend on the concrete requirement.
A) No injection needed at all.
Make your custom context a class member of your JAX-RS resource class (instead of local variable within each method). Utilize @PostConstruct to instantiate your custom context once the container has created an initialized your resource class instance. The resource class must be a CDI-bean with request scope for this to work.
@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) Your custom context requires an HttpServletRequest instance only
Beside JAX-RS via @Context, CDI also provides a predefined bean for HttpServletRequest via @Inject. You can make your custom context a CDI-bean also and inject that predefined CDI-bean. Afterwards you are able to inject your custom context into your JAX-RS resource (regardless of whether it is an EJB or 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) Your custom context requires an instance exclusiveley provided via provider specific @Context e.g. Request
If you inject an instance via @Context into your non JAX-RS custom context CDI-bean it will be null. You need some mechanism to provide the injected instance from your JAX-RS resource. Making CDI responsible for the injection via @Inject on your custom context and adding a producer method via @Produces to your JAX-RS resource will do the job.
@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.
}
}