2016-03-08 2 views
2

Я использую этот код на своей xpage для загрузки файла с удаленного сервера. Когда пользователь нажимает кнопку загрузки с xpage, открывается новая страница download.xsp и запускается код ниже.Загрузите несколько файлов с помощью Java в Xpages

#{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(); 

Метод загрузки (db.download (строка, строка)) представляет собой метод Java, который доводится до 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();} 
     } 

    } 

Этот Java-код запускает SQL запрос, чтобы получить почтовый файл в байтах и ​​хранить его в таблице. Затем он выбирает эту строку и возвращает байты в java-метод вызывающего. Таким образом я получаю удаленный файл, потому что нет веб-сервера для предоставления URL-адреса.

Моя проблема заключается в том, как я могу использовать выходной поток httpResponse, чтобы загрузить 2 или 3 файла? если я копирую-вставляю код, я получаю только первый файл. Я пытаюсь не закрывать outputStream, я получаю сообщение об ошибке, что поток уже используется.

У кого-нибудь есть идеи?

P.S: Выше код проверен и работает нормально, если я хочу загрузить только 1 файл.

ответ

6

Лучше всего будет комбинировать несколько файлов в другой ZIP-файл динамически, используя классы java.util.zip. Вы можете обернуть выходной поток с помощью ZipOutputStream, а затем прокрутить строки ResultSet, создав объекты ZipEntry, чтобы различать каждый файл внутри него.

+0

Это именно тот подход, который мы используем для нескольких конкретных случаев использования на моей дневной работе. Пользователь обычно знает, что делать с 'zip'file (и, вероятно, содержит более одного файла), а один сетевой ответ намного проще управлять. –

+0

В OpenNTF.org есть отличный xSnippet, который показывает, как создать zip вложений. https://openntf.org/XSnippets.nsf/snippet.xsp?id=download-all-attachments-java –

Смежные вопросы