[undertow-dev] Sharing session attributes in NonBlocking Handlers and Traditional Servlets

Stuart Douglas sdouglas at redhat.com
Tue Mar 11 17:02:28 EDT 2014



Lightspoke Discussion wrote:
> Hi Stuart,
>
> It worked!  I was able to get the servletcontext and then pass it into
> the handler as you suggested.  Like this:
>
> ================================
> public class NonBlockingHandlerExtension implements ServletExtension {
>      @Override
>      public void handleDeployment(DeploymentInfo deploymentInfo,
> ServletContext servletContext) {
>          final ServletContextImpl srvctx = (ServletContextImpl)
> servletContext;
>          System.out.println("\n\n\n ... \n\n\n srvctx="+srvctx);
>          //returns non-null object
>
>          deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() {
>              @Override
>              public HttpHandler wrap(final HttpHandler handler) {
> HelloWorldHandler hwhandler = new HelloWorldHandler();
> hwhandler.setServletContext(srvctx);
>                  return new PathHandler()
> .addExactPath("/hello", hwhandler)
> .addPrefixPath("/", handler);
>              }
>          });
>      }
> }
>
>
> then the handler:
>
> public class HelloWorldHandler implements HttpHandler {
> public ServletContextImpl srvctx;
> public void setServletContext(ServletContextImpl _srvctx) {
> srvctx = _srvctx;
> }
>      @Override
>      public void handleRequest(final HttpServerExchange exchange) throws
> Exception {
>          HttpSessionImpl sessionimpl;
>          sessionimpl = srvctx.getSession(exchange, true);
>          System.out.println("sessionimpl(exchange)="+sessionimpl);
>          System.out.println("1. PRE session get
> coffee="+sessionimpl.getAttribute("coffee"));
>          sessionimpl.setAttribute("coffee", "Stumptown");
>          System.out.println("1. POST session get
> coffee="+sessionimpl.getAttribute("coffee"));
>
>
> ================================
>
> My only concern now is with thread safety and synchronization.
>
> Will instantiating a new handler and then passing the servlet context
> via a public set method be thread safe?  Will it introduce any kind of
> synchronization contention?


Because of the way deployment is done there will be a 'happens before' 
action when the handler chain is actually registered under the 
deployment path.

So basically it is fine, but in general it is better to use a final 
field and pass it in the constructor.

Stuart

>
> And is there a "better" way of passing that servlet context into the
> handler?
>
> Also, if it has been there this whole time, how come
>
>         ServletRequestContext reqctx =
> exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
>
> inside the handleRequest method does not work?
>
> Thanks!
>
>
>
>
>
>
>
> On Mon, Mar 10, 2014 at 1:37 PM, Stuart Douglas <sdouglas at redhat.com
> <mailto:sdouglas at redhat.com>> wrote:
>
>     Yes, if you are running handlers outside the servlet chain the
>     servlet request context does not get setup.
>
>     Because you are actually after the ServletContextImpl (which allows
>     you to get the session) you need to get a reference to this at
>     deployment time.
>
>     How are you setting up your non-blocking handler? Via ServletExtension?
>
>     If so then the ServletContext is just passed into the extension, so
>     you can just pass it directly to the handler (You will need to cast
>     it to ServletContextImpl though in order to use it to get the session).
>
>     Stuart
>
>     Lightspoke Discussion wrote:
>
>         Hi Stuart,
>
>         I have a regular servlet (the sample... public class
>         HelloWorldServlet
>         extends HttpServlet) running inside the same web context (in the
>         same
>         war).  In the HelloWorldServlet I can access the session object.
>           I ran
>         that first, but when I run the non-blocking servlet, my reqctx still
>         returns null.
>
>         I'm running Wildfly 8.0.0 final, in case that matters.
>
>         So is everything hinging on:
>
>
>         public class ServletInitialHandler implements HttpHandler,
>         ServletDispatcher {
>
>         ...
>         publicvoidhandleRequest(__finalHttpServerExchangeexchang__e)throwsIOException,__ServletException
>         ...
>
>         exchange.putAttachment(__ServletRequestContext.__ATTACHMENT_KEY,
>         servletRequestContext);
>
>         ...
>
>
>
>
>
>         On Sun, Mar 9, 2014 at 12:55 PM, Stuart Douglas
>         <sdouglas at redhat.com <mailto:sdouglas at redhat.com>
>         <mailto:sdouglas at redhat.com <mailto:sdouglas at redhat.com>>> wrote:
>
>              This will only be not null after the first servlet handler
>         has run.
>              If your handler is executing outside the scope of the servlet
>              deployment then you need to store a reference to the
>         ServletContext
>              somewhere (worst case = stick it in a static somewhere).
>              Stuart
>
>
>              Lightspoke Discussion wrote:
>
>                  If you are running before the initial handler you need
>         to store
>                  a reference to the servlet context or the Deployment
>         somewhere.
>
>
>
>
>         --
>         --
>         Matthew Ma
>         http://www.lightspoke.com
>         Lightspoke Web Based Database
>
>
>
>
> --
> --
> Matthew Ma
> http://www.lightspoke.com
> Lightspoke Web Based Database


More information about the undertow-dev mailing list