Search code examples
instance-variablesinitstripes

Instance variable in Stripes


I'm trying to find a way to create an instance variable within the Stripes application context. Something that i would do in the init() method of a Servlet while using hand-coded servlets. The problem is that since an instance of the ActionBean is created each time the application is accessed, the variable in the actionBean is created multiple time. I have tried to get some reasonable place withing Stripes trying to call the ServletContext via ActionBeanContext.getServletContext(), but from there there is no way to access the init() method and write some code in it.

Do you have any suggestions?


Solution

  • The ActionBeanContext is also Stripes application context. This context can be customized and can contain whatever you want. Some example code:

    package my.app;
    
    public class CustomActionBeanContext extends ActionBeanContext {
      public CustomActionBeanContext() {
        super();
      }
    
      public MyObject getMyObject() {
          return (MyObject) getServletContext().getAttribute(“myObject”);
      }
    
      // Alternative solution without ServletContextListner
      private static MyObject2 myObject2;
      static {
         myObject2 = new MyObject2();
      }
    
      public MyObject2 getMyObject2() {
          return myObject2;
      }
    }
    

    To let the Stripes context factory know you want to use a custom ActionBeanContext you need to add an init-param to the Stripes filter in the web.xml:

        <init-param>
            <param-name>ActionBeanContext.Class</param-name>
            <param-value>my.app.CustomActionBeanContext</param-value>
        </init-param>
    

    You can initialize your object at server start by adding a SerlvetContextListener:

    Public class MyServletContextListener implements ServletContextListener {
    @Override
      public void contextInitialized(ServletContextEvent event) {
        event.getServletContext().setAttribute("myObject", new MyObject());
    }
    

    Example ActionBean:

    public class MyAction implements ActionBean {
      private CustomActionBeanContext context;
    
      @Override
      public CustomActionBeanContext getContext() {
        return context;
      }
    
      @Override
      public void setContext(ActionBeanContext context) {
        this.context = (CustomActionBeanContext) context;
      }
    
      @DefaultHandler
      public Resolution view() {
        MyObject  myObject = getContext().getMyObject();
        // doing something usefull with it..
      }
    }
    

    An alternative solution, in my opinion a superiour solution, is to use a dependency injection framework for injecting the (singleton) objects into your actionbeans. See Stripes configuration example here: Injecting Stripes ActionBeans with Guice DI