Я использую этот код на своей 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 файл.
Это именно тот подход, который мы используем для нескольких конкретных случаев использования на моей дневной работе. Пользователь обычно знает, что делать с 'zip'file (и, вероятно, содержит более одного файла), а один сетевой ответ намного проще управлять. –
В OpenNTF.org есть отличный xSnippet, который показывает, как создать zip вложений. https://openntf.org/XSnippets.nsf/snippet.xsp?id=download-all-attachments-java –