Results 1 to 7 of 7

Thread: Tapestry integration

  1. #1
    Join Date
    Feb 2005
    Posts
    9

    Default Tapestry integration

    Hi all,

    I am using Tapestry for my web framework and Spring for the backend. I wanted a clean way to access the ApplicationContext from within Tapestry. I wasn't really happy with the method described in the Spring docs, so I came up with something else. I think it is a bit cleaner and perhaps faster. I thought I would share it. The key is to use Tapestry's concept of an "extension": a globally-available resource.

    In my application, all backend functionality is exposed to the web tier via a "BookService" class. I had already configured a "bookService" bean in Spring. I wanted this bean available to my Tapestry Visit object as well as to pages/components. Here is my biblia.application file:

    Code:
    <application name="biblia" engine-class="com.pjungwir.biblia.web.MyEngine">
        <description>Library</description>
        <page name="Home" specification-path="Shelves.page"/>
        <extension name="appContext" class="com.pjungwir.spring.contrib.MyApplicationContext"/>
    </application>
    You can see I'm creating an Extension of the MyApplicationContext class. That is a very simple class:

    Code:
    package com.pjungwir.spring.contrib;
    
    import org.springframework.context.support.*;
    
    public class MyApplicationContext extends ClassPathXmlApplicationContext &#123;
    
        public MyApplicationContext&#40;&#41; &#123;
            super&#40;"applicationContext.xml"&#41;;
        &#125;
    
    &#125;
    My goal here was just to get a ClassPathXmlApplicationContext with a no-arg constructor. Indeed, it seems like such a constructor ought to already exist, since "applicationContext.xml" is a default filename in other parts of Spring. If this constructor were added, the MyApplicationContext class could just go away.

    Finally, I overrode the createVisit method in the MyEngine class. I couldn't just specify the visit-class property, because I wanted to set the BookService when a Visit is created (that IOC thing....):

    Code:
    package com.pjungwir.biblia.web;
    
    import com.pjungwir.biblia.BookService;
    import org.apache.tapestry.IRequestCycle;
    import org.apache.tapestry.engine.BaseEngine;
    import org.springframework.context.ApplicationContext;
    
    public class MyEngine extends BaseEngine &#123;
    
        private BookService _bookService;
        public BookService getBookService&#40;&#41; &#123; return _bookService; &#125;
    
        public MyEngine&#40;&#41; &#123;
            ApplicationContext ctx = &#40;ApplicationContext&#41;getSpecification&#40;&#41;.getExtension&#40;"appContext"&#41;;
            _bookService = &#40;BookService&#41;ctx.getBean&#40;"bookService"&#41;;
        &#125;
    
        protected Object createVisit&#40;IRequestCycle cycle&#41; &#123;
            Visit v = new Visit&#40;&#41;;
            v.setBookService&#40;getBookService&#40;&#41;&#41;;
            return v;
        &#125;
    
    &#125;
    The final change was that I had to start deploying my applicationContext.xml in WEB-INF/classes instead of just WEB-INF. This is because it was now getting loaded by an ClassPath loader instead of a Web loader.

    Once I made these changes, I could access my BookService instance from the visit or as ognlage.engine.bookService. Of course, if there are other beans in your ApplicationContext, it is easy to pull them out, too. You could even add a getApplicationContext method to your Engine class if you thought that would save you some typing.

    Paul
    __________________________
    Pulchritudo splendor veritatis.

  2. #2
    Join Date
    Feb 2005
    Posts
    9

    Default

    Hmm, this approach seems not to work so well after all. My BookService isn't serializable, so it really needs to go in the Global object. I suppose the same goes for the ApplicationContext. Also, ClassPathXmlApplicationContext seems to do bad things upon a Tomcat reload. So I am switching back to something much like what's in the Spring manual. . . .

  3. #3
    Join Date
    Mar 2005
    Posts
    2

    Default

    Doesn't the method suggested by Tapestry's documentation work?

    In your web.xml, use the ContextLoaderListener to load the ApplicationContext like this:

    <web-app>
    ..
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
    <listener-class>
    org.springframework.web.context.ContextLoaderListe ner
    </listener-class>
    </listener>
    </web-app>


    Then to access within your Tapestry pages, declare the beans in the page specification like this:

    <page-specification...>
    ..
    <property-specification name="accountDao" type="dao.IYourDAO">
    global.appContext.getBean("yourDao")
    </property-specification>
    </page-specification>


    good luck

  4. #4
    Join Date
    Aug 2004
    Posts
    6

    Default Tapestry31

    I have created a page about Tapestry+Spring+Hivemind integration. For me, it's better and clearer, but I left it to you for any comments.

    It doesn't use any extension to BaseEngine (will be deprecate in Tapestry 3.2 and also doesn't use any extension (also will be deprecated since the introduction of Hivemind in Tapestry).

    See:
    http://home.arcor.de/enefem

    Bad news is it only work with Tapestry31

  5. #5

    Default :(

    Quote Originally Posted by wchan
    Doesn't the method suggested by Tapestry's documentation work?

    In your web.xml, use the ContextLoaderListener to load the ApplicationContext like this:

    <web-app>
    ..
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
    <listener-class>
    org.springframework.web.context.ContextLoaderListe ner
    </listener-class>
    </listener>
    </web-app>


    Then to access within your Tapestry pages, declare the beans in the page specification like this:

    <page-specification...>
    ..
    <property-specification name="accountDao" type="dao.IYourDAO">
    global.appContext.getBean("yourDao")
    </property-specification>
    </page-specification>


    good luck
    Hi wchan:

    Your method work only in Tapestry3 not work in Tapestry4.
    I want to know how to inject spring bean to Tapestry4?Some good idea?Thks!

  6. #6
    Join Date
    Aug 2004
    Posts
    6

    Default Re: :(

    Hi wchan:

    Your method work only in Tapestry3 not work in Tapestry4.
    I want to know how to inject spring bean to Tapestry4?Some good idea?Thks!
    see this URL:

    http://wiki.apache.org/jakarta-tapestry/Tapestry4Spring

  7. #7

    Default Re: :(

    Quote Originally Posted by enefem
    Hi wchan:

    Your method work only in Tapestry3 not work in Tapestry4.
    I want to know how to inject spring bean to Tapestry4?Some good idea?Thks!
    see this URL:

    http://forum.springframework.org/showthread.php?t=17860
    Hi enefem:

    Thank your url.But it don't work for me I use JDK1.4, Tapestry4-beta5+Spring 1.2.
    I descripe my problem and attach my code here :
    http://forum.springframework.org/viewtopic.php?t=8545

    Please help
    Last edited by robyn; May 14th, 2006 at 08:16 PM.

Similar Threads

  1. Spring Web Flow + Spring Framewrk + Tapestry.
    By cspangen in forum Web Flow
    Replies: 1
    Last Post: Oct 14th, 2005, 02:39 AM
  2. Replies: 3
    Last Post: Sep 20th, 2005, 05:50 PM
  3. Acegi - Login Tapestry
    By john017 in forum Security
    Replies: 1
    Last Post: Feb 4th, 2005, 01:11 AM
  4. Separation of integration and unit test source
    By eliot in forum Architecture
    Replies: 4
    Last Post: Jan 30th, 2005, 01:27 PM
  5. Spring MVC with Tapestry [Solved]
    By GertThiel in forum Web
    Replies: 10
    Last Post: Aug 19th, 2004, 05:09 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •