Re: [picocontainer-dev] Storing Cached items in HttpSession?
Paul Hammant <[email protected]>
| Newsgroups | gmane.comp.java.picocontainer.devel |
|---|---|
| Message-ID | <[email protected]> |
Jörg,
scopes.html talks of a rudimentary web framework. Here's the bit for
web frameworks.
> Web Containers / Web Frameworks
>
> There are only about a million for the Java servlet container.
> There more recent and sophisticated ones try to do Dependency
> Injection for 'actions' or 'controllers'. If you want to use
> PicoContainer for a web framework, then you're likely to end up
> with three container levels. The root container would be common to
> all and known as the application-level container. One level further
> would be a session-level one, with the app one marked as its
> parent. One level further would be a request level one, with the
> session on marked as its parent. There are two not so subtle
> varations on how they would be used. One, we poineered with
> PicoContainer 1.x in 2003, the other inroduced with PicoContainer
> 2.x in 2007.
>
> PicoContainer and web frameworks - the old way.
>
> You make one instance of the app container. For each new HTTP
> Session you make a new session level container, and put it into the
> session itself - refer HttpSession.setAttribute(key,val). For each
> request, you make a new Request level container and discard it at
> the end of the request. For as long as it lives, the request level
> container's parent would be the session container.
>
> There are two downsides of this approach. 1) you have to repeatedly
> add components to the session and request containers as they are
> instantiated. 2) the serialization of the session (by Tomcat etc)
> might cause more things to be serialized than you intend - i.e. the
> session container refers to the application container.
>
> PicoContainer and web frameworks - the new way.
>
> You make one instance of the app, session and request container on
> servlet load. For the Application one, you choose Caching as the
> behavior factory. For the session and request level ones, you
> choose Storing instead. You wrap the Storing behavior factory
> instances in HttpSessionStoring and reprogram each http request
> like so:
>
>
> public class MyTinyPicoServlet extends HttpServlet {
>
> private DefaultPicoContainer requestContainer;
>
> private HttpSessionStoring sessionStoring;
> private HttpSessionStoring requestStoring;
>
> public void init(ServletConfig cfg) throws ServletException {
>
> PicoContainer appContainer = new DefaultPicoContainer(new
> Caching());
>
> Storing sessionStore = new Storing();
>
> PicoContainer sessionContainer = new DefaultPicoContainer
> (sessionStore, appContainer);
>
> sessionStoring = new HttpSessionStoring(sessionStore,
> "sessionStore");
>
> Storing requestStore = new Storing();
> requestContainer = new DefaultPicoContainer(requestStore,
> sessionContainer);
> requestStoring = new HttpSessionStoring(requestStore,
> "requestStore");
>
> // populate app, session and request scoped containers.
> // appContainer.addComponent(HibernateManager.class,
> MyHibernateManager.class); // all users/people share one
> HibernateManager
> // sessionContainer.addComponent(ShoppingCart.class,
> FifoCart.class); // a new cart per person
> // requestContainer.addComponent("/addToCart.do",
> AddToCart.class);
> // requestContainer.addComponent("/removeFromCart.do",
> RemoveFromCart.class);
> // etc
>
> }
>
> protected void service(HttpServletRequest req,
> HttpServletResponse resp)
> throws ServletException, IOException {
>
> sessionStoring.retrieveStoreFromHttpSession(req);
> requestStoring.flushStore();
>
> Action action = (Action) requestContainer.getComponent
> (req.getPathTranslated());
>
> action.execute(req, resp); // yeah yeah, this is pretty basic
>
> sessionStoring.putStoreInHttpSession(req);
>
> sessionStoring.invalidateStore();
> requestStoring.invalidateStore();
> // trying to retrieve components from at session or request
> scopes here will result in an UnsupportedOperationException
> }
>
> }
>
>
>
>
> HttpSessionStoring is not in the core jar, its in the 'gems' one.
link to that source is -
http://svn.picocontainer.codehaus.org/browse/picocontainer/java/
2.x/trunk/pico/gems/src/test/org/picocontainer/gems/web/
Pico2ServletExample.java
Can you help me understand what the Tiny Web-action servlet would
look like for the old way? I'm thinking with the new way, we can
step away from ContainerBuilder etc for servlets.
Thoughts?
- Paul
On Aug 27, 2007, at 11:06 PM, Jörg Schaible wrote:
>> ========== After some thoughts ======
>>
>> However, I am curious how we use this impl now in nanowar.
>> Jake's problem was the Session-Pico and (Request-Pico). Since
>> they build a hierarchy, you cannot but the session Pico into
>> the session without having an implicit reference to the
>> parent. With the current impl we try to solve the problem ...
>> but now you do not know, how you can retrieve and put back
>> the StoreWrapper! Therefore I believe the impl is still not
>> right. The store must be retrieved automatically from the
>> session to get this working. Funny thing is: We have that
>> already! It's the SessionReference!
>>
>> Therefore I'd propose to drop the StoreThreadLocal at all.
>> Keep the Map in an ordinary ObjectReference<Map> provided by
>> the ctor. This means you may use the SessionReference within
>> nanowar (or a specialized version that keeps the Map into an
>> unaccessible wrapper). Additionally you don't have (resp. you
>> don't have to expose) a superfluous type like StoreWrapper
>> and can omit this ugly getter/setter in the StoreCaching (may
>> be Storing only now ?). With such a setup you can recreate
>> your pico hierarchy in nanowar easily and the cached
>> instances are automatically used from the session - and
>> that's what we tried to do, isn't it? ;-)
>>
>> - Jörg
>>
>> BTW: The current unit tests should still work with such an
>> impl by providing a ThreadLocalObjectReference (currently located in
>> gems).
>>