Jar包中的文件下载(web层框架-Restlet)

以前没有写博客的习惯,今天开始把工作遇到的问题和总结的经验做个记录

  • 问题描述,可忽略
    项目是模型驱动架构,可以针对不同客户需求以配置文件的方式将不同的模块拼接到一起构建成一个完整的项目,今天为uam(模块名)写了一个简单的批量导入功能,需要从服务器下载模板提供给客户,问题是整个项目只有一个war包,各种功能模块都通过maven以jar包的形式整合,因为该模板不是通用模板,要求从war包的项目中拆出来,放到相应模块打进jar包,这样一来就无法通过new File(path)这种方式获取
  • 解决思路
    先贴一段原来通用下载程序的代码
//各种校验代码已省略,web层框架为Restlet
public class ExportDocumentResource extends AbstractResource {
    @Get
    public Representation getResourceXls() {
        try {
            //获取url中参数map
            Map attributes = getAttribute();
            //获取文件路径参数
            String moduleName = (String) attributes.get("moduleName");
            //获取文件名
            String fileName = (String) attributes.get("fileName");
            //获取文件扩展名
            String extensionName = (String) attributes.get("extensionName");
            //拼接文件相对路径
            String attachPath = "此处是写死的war包项目根路径" + moduleName + "/";
            //创建文件对象
            File file = new File(attachPath + fileName + extensionName);
            //return一个FileRepresentation对象,里面封装了file
            Representation r = new FileRepresentation(file, MediaType.APPLICATION_ALL);
            //省略一堆FileRepresentation的Api
            return r;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

上面这个方法是各模块通用的,为了是降低代码冗余,需要沿用该方法,在参数和返回值不变的情况下进行代码增强,但可以肯定的是通过具体路径无法拿到对应的jar包中的文件,jar包是文件,不是文件夹,没有路径肯定不存在File的对象,返回值类型不能为FileRepresentation,思考到这里正向走不通,倒推一下,文件下载实质是是服务端向客户端输出一个io流,查了一下Api,Representation的子类中有InputRepresentation可供选择,直接传一个流过去,这样返回值类型就确定了,接下来只要拿到输入流即可,jar包编译之后也都是.class字节码文件,jvm能拿到这些东西也是通过类的加载器,顺着这个思路也用类的加载器来获取jar包中指定文件,不要路径名,换成全类名即可,啰嗦了这么多,下面贴上代码来实现

//各种校验代码已省略
public class ExportDocumentResource extends AbstractResource {
    @Get
    public Representation getResourceXls() {
        try {
            Map attributes = getAttribute();
            String moduleName = (String) attributes.get("moduleName");
            String fileName = (String) attributes.get("fileName");
            String extensionName = (String) attributes.get("extensionName");
            String attachPath = "此处是写死的war包项目根路径" + moduleName + "/";
            //以上不变,在url中增加一个basepath键值对 basepath=com.xxx.xxx.文件名.xls
            String basePath = (String) attributes.get("basePath");
            //为保证原有功能可用,增加if判断分别处理两种请求
            Representation r = null;
            if (basePath != null && !basePath.equals("")) {// 读取jar包中的资源文件
                //拼接全类名
                attachPath = "/" + basePath.replace(".", "/") + "/";
                //用类加载器获取jar包中文件的输入流
                InputStream is = this.getClass().getResourceAsStream(attachPath + fileName + extensionName);
                r = new InputRepresentation(is);//省略一堆InputRepresentation的Api
            } else {// 读取项目路径资源文件
                File file = new File(attachPath + fileName + extensionName);
                r = new FileRepresentation(file, MediaType.APPLICATION_ALL);//省略一堆FileRepresentation的Api    
            }
            return r;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

至此在不增加方法,不改变原有功能的前提下,jar包中的资源也可以被顺利下载

你可能感兴趣的:(文件下载,Restlet,服务器,文件下载,jar包)