背景介绍
项目中用jasperreport做报表,模板文件为web资源,不在classpath之中。class又需要获取模板文件,结合数据源,生成pdf格式的报表。
之前的做法是定义一个public static byte[] getPdfBytes(HttpServletRequest request)
的接口,以request.getServletContext().getRealPath(String relativePath)
的方式获取web资源的绝对路径,再根据绝对路径获取资源。
这样一来,这个方法的调用者就直接或者间接的受限于Servlet,或者说这个方法就是专门为Servlet而准备的。
我们理想中的接口是这样的public InputStream getResource(String relativePath),只需要正确的相对路径,就可以获取对应资源的内容。
基于Servlet的方案
1、定义ServletContextListener,缓存ServletContext
package cn.ljl.javaweb.demo.util; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * 用于缓存并提供当前{@link ServletContext}. * @author lijinlong * */ @WebListener public class ServletContextHolder implements ServletContextListener { private static ServletContext context; /** * @return the context */ public static ServletContext getContext() { return context; } @Override public void contextInitialized(ServletContextEvent sce) { context = sce.getServletContext(); } @Override public void contextDestroyed(ServletContextEvent sce) { context = null; } }
批注:
在警综新框架中,监听器和上下文持有工具类是分开的:监听器为cn.sinobest.jzpt.framework.exception.web.WebContextListener,持有工具类为cn.sinobest.jzpt.framework.exception.web.WebContextHolderUtil。同事们只需直接使用,不用再另行定义了。
2、通过ServletContext获取web资源
package cn.ljl.javaweb.demo.util; import java.io.InputStream; import javax.servlet.ServletContext; /** * web资源获取工具类. * @author lijinlong * */ public class WebResourceUtil { /** * 根据相对路径,获取web资源输入流. * @param realPath 资源的相对路径. * @return */ public static InputStream getResource(String realPath) { ServletContext context = ServletContextHolder.getContext(); InputStream is = context.getResourceAsStream(realPath); return is; } }
基于Spring的方案
1、定义ApplicationContextAware的实现类
package cn.sinobest.jzpt.framework.utils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class ApplicationContextManagement implements ApplicationContextAware{ private static ApplicationContext appContext; public static void init(ApplicationContext appContext){ ApplicationContextManagement.appContext = appContext; } public static ApplicationContext getApplicationContext(){ return appContext; } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { appContext = applicationContext; } }
需要基于上述类,定义spring的bean。
批注:
上述类是警综新框架中的真实工具类,同事们可以直接使用。
2、基于spring ServletContextResource获取资源
org.springframework.web.context.WebApplicationContext wac = (org.springframework.web.context.WebApplicationContext) cn.sinobest.jzpt.framework.utils.ApplicationContextManagement.getApplicationContext(); resource = new org.springframework.web.context.support.ServletContextResource( wac.getServletContext(), path); java.io.InputStream is = resource.getInputStream();
批注:
第1步的作用依然是获取ServletContext,第2步根据ServletContext和相对路径获取资源。
总结
两种方式,分两步,可得四种组合。
Technorati 标签: web资源获取