我目前使用以下代码使用户能够从inputStream下载文件。我正在使用Liferay 6.1 GA2和JSF 2.0。
有问题的文件是一张只有1.33kb的图片,我从服务器打开它没有任何问题。它也在xhtml页面中显示正常。但是,当使用此代码将其下载到客户端计算机时,它最终会成为36.7 kb的文件。然后无法打开此下载的文件。
即使文件大小为558KB的图像,生成的下载文件也只有36.7kb。
FacesContext facesContext = FacesContext.getCurrentInstance();
OutputStream outputStream = null;
try{
ExternalContext externalContext = facesContext.getExternalContext();
ActionResponse actionResponse = (ActionResponse) externalContext.getResponse();
HttpServletResponse response = PortalUtil.getHttpServletResponse(actionResponse);
outputStream = externalContext.getResponseOutputStream();
//Set the information needed in the response
String contentType = MimeTypesUtil.getContentType(fileName);
response.reset();
response.setBufferSize(BUFFER_SIZE);
externalContext.setResponseBufferSize(BUFFER_SIZE);
response.setContentType(contentType);
response.setContentLength((int)fileSize);
response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
InputStream inputStream = getImageInputStream();
int read = 0;
byte[] bytes = new byte[BUFFER_SIZE];
int count = 0;
while ((read = inputStream.read(bytes)) != -1) {
count++;
outputStream.write(bytes, 0, read);
}
//The following always outputs the right size
System.out.println("Wrote " + count + "x" + BUFFER_SIZE + "b");
} catch (Exception ex){
ex.printStackTrace();
} finally {
if (outputStream != null)
IOUtils.closeQuietly(outputStream);
facesContext.responseComplete();
}
有没有人知道这段代码会出现什么问题?
尝试了其他代码
我也尝试使用此代码设置响应数据。页面自行刷新,方法被调用,但没有下载文件。
String contentType = MimeTypesUtil.getContentType(fileName);
externalContext.responseReset();
externalContext.setResponseBufferSize(BUFFER_SIZE);response.setContentType(contentType);
externalContext.setResponseContentLength((int)fileSize);
externalContext.setResponseHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
当我得到outputStream时,采用以下方式:
outputStream = response.getOutputStream();
我收到错误,说它无法获取Writer,因为OutputStream正在使用中:
java.lang.IllegalStateException: Cannot obtain Writer because OutputStream is already in use
com.liferay.portal.kernel.servlet.StringServletResponse.getWriter(StringServletResponse.java:102)
org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
org.apache.jasper.runtime.JspWriterImpl.write(JspWriterImpl.java:221)
org.apache.jsp.html.common.themes.portal_jsp._jspService(portal_jsp.java:297)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:72)
...
非常感谢任何帮助或推动正确的方向!
答案 0 :(得分:0)
您正在使用的portlet生命周期部分(操作阶段)与您期望使用的portlet生命周期部分(资源阶段)之间存在轻微的不匹配。为了更好地利用您期望能够使用的生命周期的一部分,只需快速查看jsf2-export-pdf-portlet。这个portlet使用一个称为ResourceHandler的东西来检索pdf文档,在这种情况下,它可能会重新获取图像。
在the jsf2-export-pdf-portlet code here中,您将找到一个名为getInputStream()的方法,其中包含的代码与您上面显示的用于获取InputStream的代码非常相似。
getInputStream方法是在JSF应用程序中创建ResourceHandler时需要覆盖的方法之一。您应该发现直接更改jsf2-export-pdf-portlet中的代码以使用您用于在其ResourceHandler模式之后生成InputStream的方法,并生成指向图像reather的链接而不是指向a的链接。 pdf文件。
希望有所帮助。在taking a look at the demo之后告诉我们您的行为。