Следующая XSnippet (из XAgent) дает вам немного идея о том, что делать. https://openntf.org/XSnippets.nsf/snippet.xsp?id=download-all-attachments
В приведенном выше XSnippet все вложения в документе зашифровываются, а затем отправляются в браузер в виде zip-файла. URL-адрес имеет некоторые параметры, например. documentID, который XAgent использует для определения того, какой документ нужно пропустить. XAgent получает дескриптор HttpServletResponse и настраивает его так, чтобы вместо отправки XPage он указывал, что он отправляет файл «application/zip».
Затем он находит документ с использованием documentId и застегивает его молнией, записывает содержимое в ответ и затем сообщает faceContext, что ответ завершен (больше не выполняйте рендеринг).
В вашем случае вы должны поместить параметр, который идентифицирует файл, который вы хотите загрузить. И вы можете ссылаться на этот XAgent, используя URL-адрес, например.
Download.xsp?fileId=somefileid
Ваш XAgent будет затем настроить ответ аналогичен выше, но тип контента не может быть "приложение/зип. Если вы не знаете тип файла, вы можете использовать «application/octet-sream», но если вы знаете, что это pdf-код, вы можете использовать подходящий Mime Type
Извлеките файл, используя любой код, который вы написали для доступа ваш вебсервис, декодировать его, и записать его в выходной поток данных в
пример Реализация в Java как управляемый компонент
Следующий пример выводит некоторый простой текст, который был первоначально в массиве байт base64. Он декодируется, а затем записывается в ответ. Все, что вам нужно сделать, это изменить тип контента на «application/octet-stream»
Создайте управляемый компонент в элементе дизайна Java.
package com.example;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;
import com.sun.faces.util.Base64;
public class DownloadBean implements Serializable {
private static final long serialVersionUID = 1L;
public DownloadBean() {
};
public void downloadFile() throws IOException {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext context = fc.getExternalContext();
String myFileName = "SomeFile.txt";
HttpServletResponse resp = (HttpServletResponse) context.getResponse();
resp.setHeader("Cache-Control", "no-cache");
resp.setDateHeader("Expires", -1);
// This example is just plain text but you would
// change this to 'application/octet-stream'
resp.setContentType("text/plain");
// Tell the browser it is an attachment with filename of <myFilename>
resp.setHeader("Content-Disposition", "attachment; filename="
+ myFileName);
OutputStream os = resp.getOutputStream();
// Somehow you need to get your byte[],
// that is up to you how you do that
// This example has just used base64 encoding of 'Hello Marcus'
byte[] base64bytes = "SGVsbG8gTWFyY3Vz".getBytes();
// Option 1 : use sun.misc.BASE64Decoder to decode with Streams
ByteArrayInputStream bais = new ByteArrayInputStream(base64bytes);
sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder();
dec.decodeBuffer(bais, os);
// Option 2 : use com.sun.faces.util.Base64 to decode to normal byte[]
//byte[] normalBytes = Base64.decode(base64bytes);
//os.write(normalBytes);
os.flush();
os.close();
fc.responseComplete();
}
}
Зарегистрировать его в faces-config.xml. Объем запроса должен быть достаточным. так, например, если вы назвали его «downloadBean», и он был класса com.example.DownloadBean, поместите эту запись в faces-config.XML
<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
<managed-bean>
<managed-bean-name>downloadBean</managed-bean-name>
<managed-bean-class>com.example.DownloadBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
Как использовать
Вы можете назвать это с помощью кнопки:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:button value="Download" id="buttonDownload">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" action="#{downloadBean.downloadFile}">
</xp:eventHandler>
</xp:button>
</xp:view>
Или вы можете создать XPage вроде XAgent, который просто загружает файл и ссылку к этому Xpage в новом окне.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
rendered="false" beforePageLoad="#{downloadBean.downloadFile}">
</xp:view>
Вы можете получить доступ к параметрам URL-адрес, если нужно использовать что-то вроде https://openntf.org/XSnippets.nsf/snippet.xsp?id=get-url-parameter-using-java
Здравствуйте! Спасибо за ответ! Вот некоторые сомнения: Я не понимаю, как я буду запускать xpage xagent, может быть, это через кнопку? Как я могу связать byte64, возвращаемый java-агентом для xagent? В своем ответе вы указываете в качестве параметра файл, который я хочу загрузить. На самом деле у меня нет файла, но массив байтов, который я преобразовываю в base64. Возможно ли, чтобы java-агент отображал этот массив байтов в форме браузера в форме содержимого PDF-файла? –
да, вы можете запустить его с помощью кнопки, которая использует действие «открытая страница», используя страницу XAgent. в отношении параметра URL я имел в виду, что это будет «fileIdentifier» некоторого описания, чтобы выбрать, какой файл получить. если у вас есть массив байтов, вам нужно записать его в ответ outputStream, то есть часть, которую я оставил пустой. проверьте переполнение стека на что-то вроде «напишите ByteArrayOutputStream для ответа». вам может потребоваться его буферизация, если это большой файл. если вам не нравится XAgent/SSJS, вы также можете сделать это с помощью метода управляемого Java-компонента, который вызывается с помощью кнопки. дайте мне знать больше вопросов –
Спасибо большое! И как интегрировать Java-агент, который использует веб-сервис с помощью xagents? –