blog.christianbauer.name

JAX-RS, CDI
August 31, 2013

Accessing request details with JAX-RS and CDI

Now that Seam/Solder is dead, and doesn't work with CDI 1.1, and Deltaspike seems to be stuck in some fantasy world where "repository patterns" are important, even trivial things with JAX-RS and CDI are surprisingly difficult.

For example, you probably want to access the HTTP request details in your managed beans or in EL expressions. This JAX-RS 2.0 provider will produce the (named) CDI context variables in the request scope, so you can easily @Inject them or reference them in EL:

@Provider
@PreMatching
@RequestScoped
@Priority(10) // Run before other filters
public class PrepareContextRequestFilter implements ContainerRequestFilter {

    @Context
    protected UriInfo uriInfo;

    @Context
    protected HttpServletRequest request;

    @Produces
    @Named("uriInfo")
    public UriInfo produceUriInfo() {
        return uriInfo;
    }

    @Produces
    @Named("requestHost")
    public String produceRequestHost() {
        return uriInfo.getBaseUri().getHost();
    }

    @Produces
    @Named("requestPort")
    public Integer produceRequestPort() {
        return uriInfo.getBaseUri().getPort() != -1
            ? uriInfo.getBaseUri().getPort()
            : request.getServerPort();
    }

    @Produces
    @Named("requestPath")
    public String produceRequestPath() {
        return uriInfo.getPath(false);
    }

    @Produces
    @Named("requestQuery")
    public String produceRequestQuery() {
        return request.getQueryString();
    }

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        // Nothing to do here, this filter only produces (named) context variables
    }
}

If you need a more type-safe approach, you can add some qualifier annotations on the producer methods.