问题
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?
回答1:
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
回答2:
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()
.
回答3:
@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..
来源:https://stackoverflow.com/questions/5604976/instance-variable-in-stripes