I am developing a new application in JavaEE 7 using WildFly 8. I am using JAX-RS to provide a RESTful service interface for remote applications.
Something like an
While lefloh's answer is definitely correct I'd like to elaborate on his 2nd approach which I find most convenient.
You're to create Interceptor(Filter) which implements ContainerRequestFilter.
import org.apache.commons.lang.StringUtils;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Provider
public class UserProvider implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
String userId = containerRequestContext.getHeaders().getFirst("User-Id");
if (StringUtils.isEmpty(userId)) {
Response response = Response
.status(Response.Status.BAD_REQUEST)
.type(MediaType.TEXT_PLAIN_TYPE)
.entity("User-Id header is missing.")
.build();
containerRequestContext.abortWith(response);
return;
}
//do your logic to obtain the User object by userId
ResteasyProviderFactory.pushContext(User.class, user);
}
}
You'd need to register it either by autodiscovering set up in web.xml
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
or in your app boot
ResteasyProviderFactory.getInstance().registerProvider(UserProvider.class);
Since all the logic behind fetching the user is in the UserProvider you can for example use it like this
@Path("/orders")
@GET
public List<Order> getOrders(@Context User user) {
return user.getOrders();
}
In my eyes this approach is valid as long as you don't try to build something like a session with this User Object.
As answered here you could use @Context and @Provider but that's not exactly what you want.
Directly injecting a Class per @Context is possible with the Resteasy Dispatcher.
But here you must register the Object which should be injected. I don't think that makes sense for request-scoped parameters.
What you could do is inject a provider like this:
// Constructor of your JAX-RS Application
public RestApplication(@Context Dispatcher dispatcher) {
dispatcher.getDefaultContextObjects().put(UserProvider.class, new UserProvider());
}
// a resource
public Response getById(@Context UserProvider userProvider) {
User user = userProvider.get();
}
Other ways to solve your problem:
I pushed examples to github.