Non-Web Threads and Reverse Ajax

It's easy to use DWR and Reverse Ajax from a thread outside of DWR. You can't use WebContext though because it is only available to threads under the control of DWR.

You have three options:

  1. Use the Browser API.

    It is important to note that a few Browser methods required a WebContext meaning the requests come from a DWR thread. Currently the methods that require this are - withCurrentPageFiltered, withCurrentPage, and getTargetSessions. All other methods can be called safely from non-DWR threads.

  2. Obtain the ScriptSessionManager, which will provide access to the ScriptSessions:
    Container container = ServerContextFactory.get().getContainer();
    ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);
    
  3. Use ServerContext (most of the methods here have been deprecated, although they are still available).

PageNormalizers

It is possible that you may get a message like this when you first start to use reverse ajax:

Can't find ServletContext to check for <welcome-file-list> in web.xml. Assuming defaults.
- To prevent this message from happening, either call the PageNormalizer from a DWR Thread
- Or seed the PageNormalizer with a ServletContext before access from outside a DWR thread

Reverse Ajax has a problem - calls to getScriptSessionsForPage() need to know that index.html resolves to the same thing as index.htm (for example), but the only way they can do this is to know the "welcome-files" setting in web.xml. This is all the responsibility of the PageNormalizer.

That's OK - it can parse web.xml to read the information, but to do that we need to know the ServletContext, and that isn't available to you if you are starting from nothing.

In essence, how does a PageNormalizer that does not know anything about the web, get in contact with a ServletContext.

There are 2 options:

Take a look at the source to Publisher.java - it has this same problem. From the constructor:

WebContext webContext = WebContextFactory.get();
ServletContext servletContext = webContext.getServletContext();

serverContext = ServerContextFactory.get(servletContext);

// A bit nasty: the call to serverContext.getScriptSessionsByPage()
// below could fail because the system might need to read web.xml which
// means it needs a ServletContext, which is only available using
// WebContext, which in turn requires a DWR thread. We can cache the
// results simply by calling this in a DWR thread, as we are now.
webContext.getScriptSessionsByPage("");