Get HttpServletRequest in RequestHandledEvent Spring

1.5k views Asked by At

I have a real nice application listener registered as seen below.

@Component
public class MyLogger implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        // not doing anything here
        // Check out the 'RequestHandledEvent' below though.
    }

    @EventListener(RequestHandledEvent.class)
    public void onApplicationEvent(RequestHandledEvent event) {
        // I'd like to get the HttpServletRequest that was just handled.
        // Furthermore, I'd really like to get the userPrincipal that was
        // on the request, so that I can know made the request

        // it seems I can do this
        // but the principal seems to already have been cleared.
        // is there a more straightforward way to get the request?
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

}

I feel like I should be able to do something like

event.getRequest()

But I haven't found a successful way to do so.

Long story short, I'd like like ONE PLACE in my application that I can get at the request that came in, and the principal that was on that request, so that I can do some logging, etc.

Should I be looking at a different application event maybe?

1

There are 1 answers

4
Alexander Yanyshin On

You can get request with proper security principal by registering servlet filter like:

@Component
public static class RequestLoggingFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        final Principal userPrincipal = request.getUserPrincipal();
        // ...do what you want with principal and request info here
        filterChain.doFilter(request, response);
    }
}

To control order of fiters in filter chain you can either annotate your filter class with @Order annotation or register filter like this:

@Bean
public FilterRegistrationBean filterRegistrationBean() {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    RequestLoggingFilter filter = new RequestLoggingFilter();
    registrationBean.setFilter(flter);
    registrationBean.setOrder(Ordered.LOWEST_PRECEDENCE);
    return registrationBean;
}