John Smith
John Smith

Reputation: 51

Clean way of injecting/checking for presence of a HttpServletRequest with CDI from code that can be called outside a request?

I have a piece of code that can be called both within and outside a HTTP request, but wants to access information in the HttpServletRequest if it is available. My first attempt was the following:

@Inject
private Instance<HttpServletRequest> httpReq;

void doSomethingIfInRequest(){
  if (httpReq.isUnsatisfied()){
    return;
  }
  httpReq.get()
  // ...
}

However, even outside a request, isUnsatisfied() returns false, leading get() to throw org.jboss.weld.exceptions.IllegalStateException: WELD-000710: Cannot inject HttpServletRequest outside of a Servlet request.

I can solve this by catching the exception or creating another class that holds the request but was wondering whether CDI/Weld offers something to deal with this.

Upvotes: 4

Views: 1364

Answers (2)

Raj Kumar
Raj Kumar

Reputation: 357

In addition to the solution by Siliarus, the following code can be used to check whether the current context is HttpServletRequestContext or not.

@Inject
BeanManager bm;

public boolean isHttpRequestScopeIsActive() {
        if (isHttpRequestScopeActive == null) {

            try {
                Context context = bm.getContext(RequestScoped.class);
                isHttpRequestScopeActive = context instanceof HttpRequestContextImpl;
            } catch (ContextNotActiveException e) {
                isHttpRequestScopeActive = false;
            }

        }
        return isHttpRequestScopeActive;

    }

Upvotes: 0

Siliarus
Siliarus

Reputation: 6753

HttpServletRequest is a so called built-in bean. CDI (Weld) provides it for you. It is always present and detected, hence Instance.isUnsatisfied() is going to be false.

You can glance at the implementation (for Weld 3) here. The short story is - context state (RequestScoped) is checked and based on the result, you either get your bean, or the exception you are seeing.

Solution - best way is probably to check whether context is active, but you probably cannot avoid catching the exception if it's not. This can be achieved for instance via BeanManager:

@Inject
BeanManager bm;

public boolean isReqScopeActive() {
  try {
    return bm.getContext(RequestScoped.class).isActive();
  } catch (ContextNotActiveException e) {
    // this is expected response to bm.getContext() if that context is inactive
    return false;
  }
}

Upvotes: 2

Related Questions