Đặt tiêu đề HTTP Content-Disposition
để attachment
. Thao tác này sẽ bật một hộp thoại Lưu dưới dạng. Bạn có thể làm điều đó bằng cách sử dụng HttpServletResponse#setHeader()
. Bạn có thể nhận phản hồi servlet HTTP từ bên dưới mũ trùm JSF bằng ExternalContext#getResponse()
.
Trong ngữ cảnh JSF, bạn chỉ cần đảm bảo rằng bạn gọi FacesContext#responseComplete()
sau đó để tránh việc bay IllegalStateException
.
Kickoff dụ:
public void download() throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
response.reset(); // Some JSF component library or some Filter might have set some headers in the buffer beforehand. We want to get rid of them, else it may collide.
response.setContentType("application/xml"); // Check http://www.iana.org/assignments/media-types for all types. Use if necessary ServletContext#getMimeType() for auto-detection based on filename.
response.setHeader("Content-disposition", "attachment; filename=\"name.xml\""); // The Save As popup magic is done here. You can give it any filename you want, this only won't work in MSIE, it will use current request URL as filename instead.
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(getYourXmlAsInputStream());
output = new BufferedOutputStream(response.getOutputStream());
byte[] buffer = new byte[10240];
for (int length; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
} finally {
close(output);
close(input);
}
facesContext.responseComplete(); // Important! Else JSF will attempt to render the response which obviously will fail since it's already written with a file and closed.
}
cảm ơn rất nhiều. Tôi đặt mã trong và bây giờ, khi tôi nhấp vào liên kết, trình duyệt (FF) sẽ thay thế trang hiện tại bằng một trang chứa nội dung tệp thay vì bật lên cửa sổ tải xuống. Tôi có thể làm gì sai? – volvox
Hãy thử trong một trình duyệt khác (IE, Chrome) hoặc khởi động lại FF với cấu hình sạch sẽ. Có thể xảy ra một webbrowser được cấu hình là ứng dụng mặc định cho các tệp XML và các tệp XML sẽ được mở tự động khi được tải xuống. – BalusC
Ồ, cũng đảm bảo rằng đây không phải là yêu cầu không đồng bộ (ajaxical), mà chỉ là một yêu cầu đồng bộ ("plain vanilla"). I E. chỉ cần sử dụng 'h: commandLink' hoặc' h: commandButton', nhưng không phải là các thành phần 'UICommand' được hỗ trợ bởi RichFaces, Ajax4jsf, IceFaces, vv. – BalusC