2

I'm writing a JUL logging Handler and I'd like to augment the logged messages with information about the current request, if we're currently handling a request. To accomplish this, I've injected a Provider<Thing> into the Handler, where Thing is @RequestScoped.

However, calling provider.get() throws an OutOfScopeException if the logging happens while we're not handling a request. I feel like catching the OutOfScopeException would be bad form. Is there a better way to determine whether or not a request is currently executing?

Tavian Barnes
  • 12,477
  • 4
  • 45
  • 118

2 Answers2

2

With wicket I used a little trick. This should be framework independent. I made a request filter and put a public static ThreadLocal in it. So if current thread is born from request, threadlocal will be set.

public class SessionContext implements Filter {

    private static final ThreadLocal<HttpSession> session = new ThreadLocal<HttpSession>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        return;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        session.set(((HttpServletRequest)servletRequest).getSession());
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        return;
    }

    public static HttpSession getSession(){
        return session.get();
    }

    public static User getUser(){
        return (User) session.get().getAttribute(UserService.USER);
    }
}

and in web.xml:

<filter>
    <filter-name>session</filter-name>
    <filter-class>SessionContext</filter-class>
</filter>
Mikhail
  • 4,175
  • 15
  • 31
  • That's a good idea! In fact, you don't even have to mess with web.xml, you can use the `filter("/*").through(MyFilter.class)` syntax: https://code.google.com/p/google-guice/wiki/ServletModule#Filter_Mapping – Tavian Barnes Jul 02 '13 at 14:39
0

As far as I know, there is no elegant way to do this. The Guice API is tight and will not grant access to the thread-local needed to make such a test. As of version 3, the thread-local in question sits on com.google.inject.servlet.GuiceFilter#localContext. You could access it by reflection but it is arguably even worse style than catching the exception.

I would stick on caching the exception... or hack into that class and add an static boolean test method.

HMM
  • 2,987
  • 1
  • 20
  • 30
  • Yeah I looked at the code in GuiceFilter and ServletScopes and figured I couldn't use them for the check. There's no built-in Guice way to check if the caller is inside a scope? If not I guess I'll just make my own ThreadLocal. – Tavian Barnes Jun 27 '13 at 20:57