简体   繁体   English

在Xpages中使用Java下载多个文件

[英]Download multiple files using Java in Xpages

I use this code in my xpage to download a file from a remote server. 我在xpage中使用此代码从远程服务器下载文件。 When the user click a download button from the xpage a new download.xsp page opens up and runs the code below. 当用户单击xpage中的下载按钮时,将打开一个新的download.xsp页面,并运行以下代码。

#{javascript:
var exCon = facesContext.getExternalContext();
var response = exCon.getResponse();
var out = response.getOutputStream();

var zipfile = sessionScope.thezip;
var dname = zipfile.substring(zipfile.lastIndexOf("\\")+1);

dl.download(zipfile,dname);
sessionScope.thezip = null;

response.setContentType("application/zip, application/octet-stream");
response.addHeader("Content-disposition","attachment; filename="+dname);
response.setHeader("Cache-Control", "no-cache");

facesContext.responseComplete();
out.close();

Download method (db.download(string,string)) is a Java method which is brought up to the xpage as a managed bean. 下载方法(db.download(string,string))是一种Java方法,作为托管bean出现在xpage上。

public void download(String filepath, String dname){
        Connection con = null;
        PreparedStatement stm = null;
        ResultSet rs = null;
        try{
            Class.forName(jdbcClass);
            con = DriverManager.getConnection(url);

                String insSql = "INSERT INTO Cache(name,zip) SELECT '"+filepath+"',* FROM OPENROWSET(BULK N'"+filepath+"', SINGLE_BLOB) AS import;";
                stm = con.prepareStatement(insSql);
                stm.executeUpdate();

            String sql = "SELECT TOP 1 * FROM Cache where name = ?;";
            stm = con.prepareStatement(sql);
            stm.setString(1, filepath);
            rs = stm.executeQuery();

            while(rs.next()){
                InputStream zip = rs.getBinaryStream("zip");

                FacesContext facesContext = FacesContext.getCurrentInstance(); 
                ExternalContext externalContext = facesContext.getExternalContext();
                HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
                response.setContentType("application/zip, application/octet-stream");
                response.setHeader("Content-disposition","attachment; filename="+dname);
                response.setHeader("Cache-Control", "no-cache");

                byte[] buf = new byte[8192];
                int c = 0;

                while ((c = zip.read(buf, 0, buf.length)) > 0) {
                    OutputStream o = response.getOutputStream();
                    o.write(buf, 0, c);
                    o.close();
                }
                zip.close();
            }

        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                if(stm!=null){stm.close();}
                if(rs!=null){rs.close();}
                if(con!=null){con.close();}
            }catch(Exception ex){ex.printStackTrace();}
        }

    }

This java code runs an sql query to get a zip file as bytes and store it in a table. 此Java代码运行sql查询,以字节为单位获取zip文件并将其存储在表中。 Then it select this row and returns the bytes to the caller java method. 然后,它选择该行并将字节返回给调用方java方法。 This way i get the remote file because there is no webserver to provide a url. 这样我就可以获取远程文件,因为没有Web服务器可以提供URL。

My problem is how can i use the httpResponse outputStream so as to download 2 or 3 files? 我的问题是如何使用httpResponse outputStream来下载2或3个文件? if i copy-paste the code i get only the first file. 如果我复制粘贴代码,我只会得到第一个文件。 I i try not to close the outputStream i get an error that the stream is already in use. 我尝试不关闭outputStream,但收到一条错误消息,指出该流已在使用中。

Does anyone have any idea? 有人有什么主意吗?

PS: Above code is tested and works fine if i want to download 1 file only. PS:以上代码经过测试,如果我只想下载1个文件,则可以正常工作。

Your best bet would likely be to combine the multiple files into another ZIP file dynamically using the java.util.zip classes. 最好的选择是使用java.util.zip类将多个文件动态地组合成另一个ZIP文件。 You could wrap the output stream with ZipOutputStream and then loop through your ResultSet rows, creating ZipEntry objects to distinguish each file within it. 您可以使用ZipOutputStream包装输出流,然后循环遍历ResultSet行,创建ZipEntry对象以区分其中的每个文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM