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 action开发者_开发技巧Bean 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?
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
Not a Stripes-specific way, but using the standard Servlet API you'd implement ServletContextListener
and do the job in contextInitialized()
method. If you register it as <listener>
in web.xml
(or when you're already on Java EE 6, annotate using @WebListener
), then it'll run during webapp's startup.
@Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("somename", new SomeObject());
}
This way it's available in EL by ${somename}
and in all action beans by ServletContext#getAttribute()
.
@JBoy, You have to specify your implementation of ServletContextListner in the web.xml like below
<listner>
<listner-class>
www.test.com.MyListner
</listner-class>
</listner>
Thanks KDeveloper for his advice. I was also searching for the solution. I found the information from his blog
There is one more method I have found out. For that you have to subclass the "RuntimeConfiguration" class
public class MyConfiguration extends RuntimeConfiguration {
@Override
public void init() {
getServletContext.setAttribute("myObject",new MyObject);
super.init();
}
}
After that in the web.xml specify the above configuration.
<init-param>
<param-name>Configuration.Class</param-name>
<param-value>www.test.com.MyConfiguration</param-value>
</init-param>
You also have to subclass the ActionBeanContext as KDeveloper said; to get the object in ActionBeans
This is my finding. I found out it is working. But I don't know whether it has any side effects. If it has any; please comment..
精彩评论