또한 컴포넌트 시스템 이벤트, 특히 PreRenderViewEvent를 사용하여 JSF 2.0에서이를 해결할 수 있습니다.
렌더링하기 전에 다운로드 수신기를 시작하는 다운로드보기 (/download.xhtml)를 작성하기 만하면됩니다.
<?xml version="1.0" encoding="UTF-8"?>
<f:view
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core">
<f:event type="preRenderView" listener="#{reportBean.download}"/>
</f:view>
그런 다음 보고서 bean (JSR-299를 사용하여 정의 됨)에서 파일을 누르고 응답을 완료로 표시하십시오.
public @Named @RequestScoped class ReportBean {
public void download() throws Exception {
FacesContext ctx = FacesContext.getCurrentInstance();
pushFile(
ctx.getExternalContext(),
"/path/to/a/pdf/file.pdf",
"file.pdf"
);
ctx.responseComplete();
}
private void pushFile(ExternalContext extCtx,
String fileName, String displayName) throws IOException {
File f = new File(fileName);
int length = 0;
OutputStream os = extCtx.getResponseOutputStream();
String mimetype = extCtx.getMimeType(fileName);
extCtx.setResponseContentType(
(mimetype != null) ? mimetype : "application/octet-stream");
extCtx.setResponseContentLength((int) f.length());
extCtx.setResponseHeader("Content-Disposition",
"attachment; filename=\"" + displayName + "\"");
// Stream to the requester.
byte[] bbuf = new byte[1024];
DataInputStream in = new DataInputStream(new FileInputStream(f));
while ((in != null) && ((length = in.read(bbuf)) != -1)) {
os.write(bbuf, 0, length);
}
in.close();
}
}
그게 전부입니다!
다운로드 페이지 (/download.jsf)에 링크하거나 HTML 메타 태그를 사용하여 스플래시 페이지로 리디렉션 할 수 있습니다.
이 솔루션을 사용해보십시오. 페이지에 다른 컨트롤이없는 경우에만 작동합니다. 페이지에 드롭 다운 상자 선택과 같은 다른 컨트롤이 있고 페이지가 몇 번 앞뒤로왔다면'download()'가 계속 호출하고 값은 영원히 리셋됩니다. 따라서 그 실행을 영원히 한 번만 지켜줄 수있는 방법이 있습니까? – huahsin68