Переменная экземпляра в полосах
Я пытаюсь найти способ создания переменной экземпляра в контексте приложения Stripes. Что-то, что я бы сделал в init()
метод сервлета при использовании сервлетов с ручной кодировкой. Проблема в том, что, так как экземпляр ActionBean
создается при каждом доступе к приложению, переменная в actionBean создается несколько раз. Я пытался найти какое-то разумное место в полоску, пытаясь вызвать ServletContext
с помощью ActionBeanContext.getServletContext()
но оттуда нет возможности получить доступ к init()
метод и написать код в нем.
У вас есть какие-нибудь предложения?
3 ответа
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, что вы хотите использовать пользовательский ActionBeanContext, вам нужно добавить init-param в фильтр Stripes в файле web.xml:
<init-param>
<param-name>ActionBeanContext.Class</param-name>
<param-value>my.app.CustomActionBeanContext</param-value>
</init-param>
Вы можете инициализировать ваш объект при запуске сервера, добавив SerlvetContextListener:
Public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("myObject", new MyObject());
}
Пример 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..
}
}
Альтернативное решение, на мой взгляд, превосходящее решение, заключается в использовании структуры внедрения зависимостей для внедрения ( singleton) объектов в ваши bean-компоненты action. См. Пример конфигурации Stripes здесь: Внедрение Stripes ActionBeans с Guice DI
@JBoy, Вы должны указать свою реализацию ServletContextListner в web.xml, как показано ниже
<listner>
<listner-class>
www.test.com.MyListner
</listner-class>
</listner>
Спасибо KDeveloper за его совет. Я также искал решение. Я нашел информацию из его блога
Есть еще один метод, который я обнаружил. Для этого вы должны создать подкласс класса "RuntimeConfiguration"
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
Это моя находка. Я узнал, что это работает. Но я не знаю, есть ли у него побочные эффекты. Если оно есть; Прокомментируйте, пожалуйста..
Не для Stripes, а с использованием стандартного API сервлета, который вы реализуете ServletContextListener
и делать работу в contextInitialized()
метод. Если вы зарегистрируете его как <listener>
в web.xml
(или когда вы уже находитесь в Java EE 6, аннотируйте с помощью @WebListener
), то он запустится во время запуска веб-приложения.
@Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("somename", new SomeObject());
}
Таким образом, это доступно в EL ${somename}
и во всех бобах действия ServletContext#getAttribute()
,