在SSH(struts2.21+hibernate3.3.2+spring2.5)整合中遇到一个问题:

在SSH(struts2.21+hibernate3.3.2+spring2.5)整合中遇到一个问题:
菜鸟求解~~知道的大师们给个解决方案把~~~
目的:在容器启动后,自动从数据库中读出数据然后在WEB的application范围内写入数据 ,这样在index.jsp,里只要直接读取application数据就行了,不每次都过action。(都是一些一般不变的数据。且数据不多)
试验:1、在把Action设为单例后,容器启动后会自动运行,不能访问spring里的bean,及在构造方法里打印ActionContext.getContext()为空值。找不到办法~~
2、继承ApplicationListener类容器启动后会自动运行,可以访问spring里的bean,但打印ActionContext.getContext()为空值。还是找不到办法。
3、使用hibernate的EhCache,使用二级缓存及查询缓存能实现,但每次都要过action.不能在容器启动后就在application写入数据。
4、ServletContextListener等也试了下,好像都差不多。
我想问下。有没有其它的办法能解决问题。还是只能每次都过action?在网上也没查到相关的问题。

通过ServletContextListener应该是可以实现的
这个是通过容器初始化时获取数据库的url实例 ssh实现

web.xml配置
[code="java"]


ServletContextLoaderListener


[/code]
ServletContextLoaderListener类
[code="java"]

import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.web.context.support.WebApplicationContextUtils;

//只是一个接口,具体实现看自己需要。
import UrlManager;

public class ServletContextLoaderListener implements ServletContextListener {

/* (non-Javadoc)
 * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
 */
public void contextInitialized(ServletContextEvent servletContextEvent) {
    ServletContext servletContext = servletContextEvent.getServletContext();
    UrlManager urlManager = this.getUrlManager(servletContext);

    List<?> urlAuthorities = urlManager.loadUrlAuthorities();
    servletContext.setAttribute("urlAuthorities", urlAuthorities);


}
/* (non-Javadoc)
 * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
 */
public void contextDestroyed(ServletContextEvent servletContextEvent) {
    servletContextEvent.getServletContext().removeAttribute("urlAuthorities");
}

/**
 * Get UrlManager from ApplicationContext
 * 
 * @param servletContext
 * @return UrlManager
 */
protected UrlManager getUrlManager(ServletContext servletContext) {
   return (UrlManager) WebApplicationContextUtils.getWebApplicationContext(servletContext).getBean("urlManager"); 
}

}

[/code]

不通过action的话,

可以初始化页面index时,用jstl标签采用jdbc方式获得初始化数据。

:D 在页面上 用$ 调用action 中的方法是不是可以, 写在action父类中
通过action返回这些值, 值就可以不用存application中了 设置成静态就行了, 不知道理解lz意思没 呵呵

你为什么一定要用Action去完成全局数据的初始化呢?
你完成可以用Servlet的过虑器完成啊!
先取出你放在Application中的数据,如果为空就拿着Spring里配置好的数据源去数据库查,将查到的数据扔到Application。
如果不空就跳过,执行下一个过滤器。

在过虑器中获得Spring容器和数据源的方法:
[code="java"]
// 获得Spring容器
ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
// 获得数据源
DataSource dataSource = ctx.getBean("dataSource");
[/code]

当然你也可以去拿Spring容器中的Service或DAO。
其实更好的方法是写一个Servlet的listener,在服务启动的时候加载一次,以后就可以直接用了,不过一定要放在Spring的listener之后执行。

额。index.jsp 通过小脚本获得hibernate查询数据源的结果。 spring注入业务逻辑和数据库层。因为用不到action所以不用注入action。这样初始化index.jsp时就调用业务逻辑类查询数据库。获得结果返回出来。

其实你就是想要一个全局的Bean是吗?

[code="java"]
public Class Cache{

private static Map<String,Object> cacheMap;
private Cache(){ throw new AssertionError();}

static{ initCacheMap();}

private static initCacheMap(){
        if(cacheMap == null) cacheMap = new HashMap<String,Object>();
        cacheMap.put("mydata1","value1");
}

public static Object get(String key){ return cacheMap != null ? cacheMap.get(key) : null ;}

}
[/code]

直接建一个Servlet 随容器初始化,如果你要一个线程安全的集合就改成 ConcurrencyMap