-
-
Save rmannibucau/d55fce47b001185dca3e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package spec.demo; | |
import javax.annotation.Resource; | |
import javax.enterprise.concurrent.ManagedExecutorService; | |
import javax.enterprise.context.RequestScoped; | |
import javax.inject.Inject; | |
import javax.servlet.AsyncContext; | |
import javax.servlet.AsyncListener; | |
import javax.servlet.Filter; | |
import javax.servlet.FilterChain; | |
import javax.servlet.FilterConfig; | |
import javax.servlet.ServletContext; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.annotation.WebFilter; | |
import javax.servlet.annotation.WebServlet; | |
import javax.servlet.http.HttpServlet; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletRequestWrapper; | |
import javax.servlet.http.HttpServletResponse; | |
import java.io.IOException; | |
import java.security.Principal; | |
@WebServlet(urlPatterns = "/demo", asyncSupported = true) | |
public class LongService extends HttpServlet { | |
@Resource(name = "httpES") | |
private ManagedExecutorService mes; | |
@Override | |
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | |
AsyncContext ctx = req.startAsync(); | |
mes.submit(() -> { | |
try { | |
resp.getOutputStream().write("done".getBytes()); | |
ctx.complete(); | |
} catch (final IOException e) { | |
throw new IllegalStateException(e); | |
} | |
}); | |
} | |
@WebFilter(urlPatterns = "/*", asyncSupported = true) | |
public static class MyAuditFilter implements Filter { | |
@Inject | |
private MyAuditContext auditContext; | |
@Override | |
public void init(FilterConfig filterConfig) throws ServletException { | |
// no-op | |
} | |
@Override | |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { | |
HttpServletRequest httpServletRequest = HttpServletRequest.class.cast(request); | |
auditContext.setPrincipal(httpServletRequest.getUserPrincipal()); | |
try { | |
chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) { | |
@Override | |
public AsyncContext startAsync() throws IllegalStateException { | |
return wrapAsync(super.startAsync()); | |
} | |
@Override | |
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException { | |
return wrapAsync(super.startAsync(servletRequest, servletResponse)); | |
} | |
}, response); | |
} finally { | |
if (!httpServletRequest.isAsyncSupported()) { | |
auditContext.end(); | |
} | |
} | |
} | |
private AsyncContext wrapAsync(final AsyncContext asyncContext) { | |
return new AsyncContext() { | |
public void complete() { | |
try { | |
asyncContext.complete(); | |
} finally { | |
auditContext.end(); | |
} | |
} | |
// from here we 100% delegate | |
public ServletRequest getRequest() { | |
return asyncContext.getRequest(); | |
} | |
public ServletResponse getResponse() { | |
return asyncContext.getResponse(); | |
} | |
public boolean hasOriginalRequestAndResponse() { | |
return asyncContext.hasOriginalRequestAndResponse(); | |
} | |
public void dispatch() { | |
asyncContext.dispatch(); | |
} | |
public void dispatch(String path) { | |
asyncContext.dispatch(path); | |
} | |
public void dispatch(ServletContext context, String path) { | |
asyncContext.dispatch(context, path); | |
} | |
public void start(Runnable run) { | |
asyncContext.start(run); | |
} | |
public void addListener(AsyncListener listener) { | |
asyncContext.addListener(listener); | |
} | |
public void addListener(AsyncListener listener, ServletRequest request, ServletResponse response) { | |
asyncContext.addListener(listener, request, response); | |
} | |
public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException { | |
return asyncContext.createListener(clazz); | |
} | |
public void setTimeout(long timeout) { | |
asyncContext.setTimeout(timeout); | |
} | |
public long getTimeout() { | |
return asyncContext.getTimeout(); | |
} | |
}; | |
} | |
@Override | |
public void destroy() { | |
// no-op | |
} | |
} | |
@RequestScoped | |
public static class MyAuditContext { | |
private Principal principal; // using Principal and not name directly to show we can get a hidden injection graph | |
public Principal getPrincipal() { | |
return principal; | |
} | |
public void setPrincipal(Principal principal) { | |
this.principal = principal; | |
} | |
public void end() { | |
System.out.println("Request done for "+ principal.getName()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment