diff --git a/examples/src/main/java/net/sourceforge/stripes/examples/async/AsyncActionBean.java b/examples/src/main/java/net/sourceforge/stripes/examples/async/AsyncActionBean.java index 14423d6ae..bf62d7fe0 100644 --- a/examples/src/main/java/net/sourceforge/stripes/examples/async/AsyncActionBean.java +++ b/examples/src/main/java/net/sourceforge/stripes/examples/async/AsyncActionBean.java @@ -6,14 +6,13 @@ import org.apache.http.HttpHost; import javax.servlet.AsyncContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; @Public @UrlBinding("/async") public class AsyncActionBean implements ActionBean { + private static final String JSP_PATH = "/WEB-INF/async/async.jsp"; private ActionBeanContext context; public ActionBeanContext getContext() { return context; @@ -50,7 +49,8 @@ public Resolution asyncEvent() { return new AsyncResolution() { // only this method to implement. you must complete() or dispatch() yourself. - public void execute(final HttpServletRequest request, final HttpServletResponse response) throws Exception { + @Override + protected void executeAsync() throws Exception { // we use an Async Http Client in order to call the github web service as a demo. // the async http client calls on of the lambdas when he's done, and @@ -72,10 +72,10 @@ public void execute(final HttpServletRequest request, final HttpServletResponse } catch (Exception e) { clientException = e; } - dispatchToJsp(getAsyncContext()); + dispatch(JSP_PATH); } else { ghResponse = result.getStatusLine().getReasonPhrase(); - dispatchToJsp(getAsyncContext()); + dispatch(JSP_PATH); } }) @@ -83,14 +83,14 @@ public void execute(final HttpServletRequest request, final HttpServletResponse // http client failure clientException = ex; - dispatchToJsp(getAsyncContext()); + dispatch(JSP_PATH); }) .cancelled(() -> { // just for demo, we never call it... cancelled = true; - dispatchToJsp(getAsyncContext()); + dispatch(JSP_PATH); }) .get(); // trigger async request @@ -101,9 +101,10 @@ public void execute(final HttpServletRequest request, final HttpServletResponse @DontValidate public Resolution asyncEventThatTimeouts() { return new AsyncResolution() { - public void execute(final HttpServletRequest request, final HttpServletResponse response) throws Exception { + @Override + protected void executeAsync() throws Exception { getAsyncContext().setTimeout(1000); - getAsyncContext().getResponse().getWriter().write("OK"); + getResponse().getWriter().write("OK"); // never call complete/dispatch... } }; @@ -112,17 +113,13 @@ public void execute(final HttpServletRequest request, final HttpServletResponse @DontValidate public Resolution asyncEventThatThrows() { return new AsyncResolution() { - public void execute(final HttpServletRequest request, final HttpServletResponse response) throws Exception { + @Override + protected void executeAsync() throws Exception { throw new RuntimeException("WTF"); } }; } - // helper dispatch method - private void dispatchToJsp(AsyncContext asyncContext) { - asyncContext.dispatch("/WEB-INF/async/async.jsp"); - } - // getters for instance fields that have been set by event method public boolean isCancelled() { diff --git a/stripes/src/main/java/net/sourceforge/stripes/action/AsyncResolution.java b/stripes/src/main/java/net/sourceforge/stripes/action/AsyncResolution.java index d6d1a3da3..c050b9aaf 100644 --- a/stripes/src/main/java/net/sourceforge/stripes/action/AsyncResolution.java +++ b/stripes/src/main/java/net/sourceforge/stripes/action/AsyncResolution.java @@ -1,6 +1,8 @@ package net.sourceforge.stripes.action; import javax.servlet.AsyncContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; public abstract class AsyncResolution implements Resolution { @@ -14,4 +16,41 @@ public void setAsyncContext(AsyncContext asyncContext) { this.asyncContext = asyncContext; } + private ActionBeanContext context; + + public ActionBeanContext getContext() { + return context; + } + + public void setContext(ActionBeanContext context) { + this.context = context; + } + + private HttpServletRequest request; + private HttpServletResponse response; + + public HttpServletRequest getRequest() { + return request; + } + + public HttpServletResponse getResponse() { + return response; + } + + @Override + public final void execute(HttpServletRequest request, HttpServletResponse response) throws Exception { + this.request = request; + this.response = response; + executeAsync(); + } + + protected abstract void executeAsync() throws Exception; + + protected void dispatch(String path) { + getAsyncContext().dispatch(path); + } + + protected void complete() { + getAsyncContext().complete(); + } } diff --git a/stripes/src/main/java/net/sourceforge/stripes/controller/DispatcherServlet.java b/stripes/src/main/java/net/sourceforge/stripes/controller/DispatcherServlet.java index 10f4c2890..88a26ee24 100644 --- a/stripes/src/main/java/net/sourceforge/stripes/controller/DispatcherServlet.java +++ b/stripes/src/main/java/net/sourceforge/stripes/controller/DispatcherServlet.java @@ -238,6 +238,7 @@ public void onStartAsync(AsyncEvent event) throws IOException { }); AsyncResolution asyncResolution = (AsyncResolution)resolution; asyncResolution.setAsyncContext(asyncContext); + asyncResolution.setContext(ctx.getActionBeanContext()); } executeResolution(ctx, resolution); } diff --git a/stripes/src/test/java/net/sourceforge/stripes/mock/TestMockAsync.java b/stripes/src/test/java/net/sourceforge/stripes/mock/TestMockAsync.java index 96236e806..081b230b8 100644 --- a/stripes/src/test/java/net/sourceforge/stripes/mock/TestMockAsync.java +++ b/stripes/src/test/java/net/sourceforge/stripes/mock/TestMockAsync.java @@ -38,11 +38,11 @@ public void setContext(ActionBeanContext context) { @DefaultHandler public Resolution doAsync() { return new AsyncResolution() { - public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception { + @Override + protected void executeAsync() throws Exception { Thread.sleep(5000); - AsyncContext asyncContext = getAsyncContext(); - asyncContext.getResponse().getWriter().write("DONE"); - asyncContext.complete(); + getResponse().getWriter().write("DONE"); + complete(); } }; }