问题描述
在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?在网上也没查到相关的问题。 问题补充:yuyuypjk 写道
解决方案
通过ServletContextListener应该是可以实现的这个是通过容器初始化时获取数据库的url实例 ssh实现web.xml配置<listener> <listener class> ServletContextLoaderListener </listener-class></listener>ServletContextLoaderListener类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"); }}
解决方案二:
其实你就是想要一个全局的Bean是吗?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 ;}}直接建一个Servlet 随容器初始化,如果你要一个线程安全的集合就改成 ConcurrencyMap
解决方案三:
额。index.jsp 通过小脚本获得hibernate查询数据源的结果。 spring注入业务逻辑和数据库层。因为用不到action所以不用注入action。这样初始化index.jsp时就调用业务逻辑类查询数据库。获得结果返回出来。
解决方案四:
你为什么一定要用Action去完成全局数据的初始化呢?你完成可以用Servlet的过虑器完成啊!先取出你放在Application中的数据,如果为空就拿着Spring里配置好的数据源去数据库查,将查到的数据扔到Application。如果不空就跳过,执行下一个过滤器。在过虑器中获得Spring容器和数据源的方法:// 获得Spring容器ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);// 获得数据源DataSource dataSource = ctx.getBean("dataSource");当然你也可以去拿Spring容器中的Service或DAO。其实更好的方法是写一个Servlet的listener,在服务启动的时候加载一次,以后就可以直接用了,不过一定要放在Spring的listener之后执行。
解决方案五:
在页面上 用$ 调用action 中的方法是不是可以, 写在action父类中 通过action返回这些值, 值就可以不用存application中了 设置成静态就行了, 不知道理解lz意思没 呵呵
解决方案六:
不通过action的话,可以初始化页面index时,用jstl标签采用jdbc方式获得初始化数据。