2011-04-09 39 views
1

我正試圖找到一種方法在Stripes應用程序上下文中創建一個實例變量。 在使用手動編碼的servlet時,我會在使用Servlet的init()方法時做些什麼。 問題在於,由於每次訪問應用程序時都會創建ActionBean的實例,因此actionBean中的變量會多次創建。 我試圖通過ActionBeanContext.getServletContext()來試圖獲得一些合理的條件,試圖通過ActionBeanContext.getServletContext()調用ServletContext,但是從那裏沒有辦法訪問init()方法並在其中編寫一些代碼。Stripes中的實例變量

你有什麼建議嗎?

+0

難道你不只是問如何創建一個應用程序範圍的變量? (這是你通常在servlet的init()方法中做的)。這與實例變量完全不同。 – BalusC 2011-04-09 13:27:53

+0

嗨,Balus的確,你是否在Stripes中放置了一個應用程序變量,我仍在搜索,不知道 – JBoy 2011-04-09 15:38:19

回答

1

ActionBeanContext也是Stripes應用程序的上下文。此上下文可以自定義,並可以包含任何你想要的。一些示例代碼:

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; 
    } 
} 

要讓Stripes context factory知道你想要ActionBeanContext你需要一個init-PARAM添加到條紋過濾器在web.xml中使用自定義的:

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

你可以

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

例的ActionBean:

通過添加SerlvetContextListener初始化在服務器啓動你的對象
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.. 
    } 
} 

另一種解決方案在我看來是一個優秀的解決方案,就是使用dependency injection框架將(singleton)對象注入到actionbeans中。看到這裏條紋配置示例:Injecting Stripes ActionBeans with Guice DI

+0

您好KDeveloper和thx爲建議,我忘了關閉案件有一天,我實際上解決了它,只需插入我需要的對象在servlet上下文中,就像getContext()。getServletContext()。setAttribute(key,value); – JBoy 2011-04-12 21:20:00

+0

在這種情況下,請不要忘記setAttribute不是線程安全的,因此您需要在同步代碼中設置/獲取屬性,這就是爲什麼在任何請求之前運行ServletContextListener更安全的原因。 – Kdeveloper 2011-04-12 23:09:19

0

不是特定於Stripes的方式,但使用標準的Servlet API,您將執行ServletContextListener並執行contextInitialized()方法中的作業。如果您在web.xml中註冊爲<listener>(或者您已經在Java EE 6上,請使用@WebListener註釋),那麼它將在webapp啓動期間運行。

@Override 
public void contextInitialized(ServletContextEvent event) { 
    event.getServletContext().setAttribute("somename", new SomeObject()); 
} 

這種方式是可以在EL通過${somename},並通過ServletContext#getAttribute()一切行動豆。

+0

Thx,這看起來確實像是一個潛在的解決方案,問題是「在哪裏」實現cintextInitialized假設這應該在一個servlet中完成,這就是我的問題,因爲Stripes應用程序只包含ActionBeans,我不知道該把它放在哪裏。 Stripes在啓動時加載了1個servlet,DispatcherServlet,但它不可訪問 – JBoy 2011-04-09 16:30:37

+0

在您的'ServletContextListener'實現中。 – BalusC 2011-04-09 16:34:14

+0

現在我想要做的是從ActionBeanContext調用getServletContext()。setAttribute(「」,o),但它給了我null,那是如此奇怪,容器自動初始化一個ServletContext – JBoy 2011-04-09 19:46:42

0

@JBoy,你必須指定ServletContextListner的實施在web.xml中像下面

<listner> 
    <listner-class> 
     www.test.com.MyListner 
    </listner-class> 
</listner> 

感謝KDeveloper他的意見。我也在尋找解決方案。我發現他的博客上的信息

還有一種方法我找到了。爲此,您必須繼承「運行時配置」類

public class MyConfiguration extends RuntimeConfiguration { 
    @Override 
    public void init() { 
     getServletContext.setAttribute("myObject",new MyObject); 
     super.init(); 
    } 
} 

然後在web.xml中指定上述配置。

<init-param> 
    <param-name>Configuration.Class</param-name> 
    <param-value>www.test.com.MyConfiguration</param-value> 
</init-param> 

您還必須將ActionBeanContext繼承爲KDeveloper所說的;獲取ActionBeans中的對象

這是我的發現。我發現它正在工作。但我不知道它是否有任何副作用。如果有的話;請發表評論..