在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