How to upgrade filters to support Servlet 3.0 asynchronous servlet
Asked Answered
M

3

9

I have a servlet which is used to fetch data from many third party REST datapoints, integrate all the data and report the data in a HTML format. I also have a filter which has the following flow -

  1. Create an event record when the request hits the filter and add the eventrecord object to the request
  2. perform chain.doFilter - which allows the servlet to add more details to the eventrecord
  3. on the way back to the browser, filter gets the eventrecord object and logs it.

Now if I use Asynchronous servlet using AsyncContext context = request.getAsyncContext();, which will talk to the same REST datapoints but as and when data is ready, it will write to the response stream instead of waiting for all the REST data points to respond, how would I re write my filter ? Would it be attached to the thread which is responsible for flushing data from the REST data points so that once all the data is processed and flused, it will log the eventrecord ? Is there any common pattern that I can study to understand how such use cases can be handled with Servlet 3.0's asynchronous servlets ? I am using JDK 6.0, Tomcat 7.0.

Morningglory answered 28/5, 2012 at 21:50 Comment(0)
C
6

Just add @WebFilter(urlPatterns = {"/*" }, asyncSupported = true) in web-xml for your filter.

Or add <async-supported>true</async-supported>

Crash answered 4/7, 2012 at 12:2 Comment(2)
is this all for upgrading the filter to async? In the question, the filter will handle response as well. no need to change the filter to use AsyncContext? I'm confused.Singletary
This doesn't help for the processing "on the way back" (see third item of the question), to IMHO this doesn't answer the question.Incoming
L
2

I have put a bounty as I'm unsure myself how to properly support instrumenting or diagnostic filters (e.g. Codahales metrics filters).

While adding <async-supported>true</async-supported> to your filters will certainly make them appear to work it may not get the results you expect (in the case of metrics all your requests will appear to be very fast).

It may seems like a good idea to get the AsyncContext right away in the filter to bind metric data but various containers apparently have issues with this and I believe frameworks like Spring have issues as well (this might just be my older version of Spring). That is most frameworks expect the first half of the request handling to be synchronous (I maybe massively wrong on this).

Consequently it seems like the only fool proof way is to integrate filters at the framework level. For example Spring offers org.springframework.web.context.request.async.DeferredResultProcessingInterceptor which is somewhat analogous to the AsyncContext events.

This is somewhat unfortunate as not all request maybe handled by the web framework but then again there is difference between handling the first portion of the request and actually fulfilling (ie that is now two metrics you might want to monitor).

Lannylanolin answered 7/7, 2016 at 16:30 Comment(0)
S
0

@WebFilter Annotation has been introduced in Java EE 6. It defines different element like filterName, asyncSupported and servletNames etc. @WebFilter cannot be used without web.xml because @WebFilter does not define order. @WebFilter reduces the other configuration in web.xml.

@WebFilter(filterName="filterOne")
public class FilterOne implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("Inside filter one.");
        chain.doFilter(request, response);
    }
    @Override
    public void destroy() {
    }
} 
Su answered 14/7, 2016 at 8:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.