• 在class中获取web资源


    背景介绍

    项目中用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 标签:
  • 相关阅读:
    php注释规范
    Jquery元素选取、常用方法
    pdo 添加数据
    pdo 访问数据库
    session / cookie 区别与应用
    注册审核
    分页 --条件查询再分页
    Python 第二十九章 socket通信
    Python 第二十八章 网络初识+五层协议+三次握手四次挥手
    Python 第二十六章 面向对象 元类+反射+双下方法
  • 原文地址:https://www.cnblogs.com/ywjy/p/5044225.html
Copyright © 2020-2023  润新知