服务于zip的JSP损坏文件
我在尝试在JSP中提供zip文件时遇到问题。服务于zip的JSP损坏文件
压缩文件在完成下载后总是损坏。我已经尝试了几种不同的阅读和写作方法,而且他们中的任何一个似乎都没有办法。
我想它可能是在ascii字符的某处添加文件将打开并显示所有文件名,但我无法提取任何文件。
这里是我的最新代码:
<%@ page import= "java.io.*" %>
<%
BufferedReader bufferedReader = null;
String zipLocation = "C:\\zipfile.zip";
try
{
bufferedReader = new BufferedReader(new FileReader(zipLocation));
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=zipfile.zip");
int anInt = 0;
while((anInt = bufferedReader.read()) != -1)
{
out.write(anInt);
}
}
catch(Exception e)
{
e.printStackTrace();
}
%>
编辑: 我感动的代码到一个servlet,它仍然没有工作。我改变了周围都是一些更多的东西,所以这里的最新非工作代码:
public void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
{
try
{
String templateLocation = Config.getInstance().getString("Site.templateDirectory");
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=output.zip;");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(baos);
FileInputStream fis = new FileInputStream(templateLocation);
int len;
byte[] buf = new byte[1024];
while ((len = fis.read(buf)) > 0)
{
bos.write(buf, 0, len);
}
bos.close();
PrintWriter pr = response.getWriter();
pr.write(baos.toString());
pr.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
EDIT2:
这是我的实际工作servlet代码。谢谢大家!
public void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
{
try
{
String templateLocation = Config.getInstance().getString("Site.templateDirectory");
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=output.zip;");
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
FileInputStream fis = new FileInputStream(templateLocation);
int len;
byte[] buf = new byte[1024];
while ((len = fis.read(buf)) > 0)
{
bos.write(buf, 0, len);
}
bos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
拉链是二进制文件,因此不适合作为字符数据传输。此外,代码外的文字可能会破坏文件。
使用普通的vanilla servlet代替JSP。
这个确切代码段中的问题在第二行 - JSP标签之外有一个空行,它以HTML(即HTML源代码中的空行)的形式发送到浏览器。
要非常小心从删除任何东西,是不是在<%%>,尤其是空白(即使是终端一行!),还是照做其他地方使用servlet :)
删除所有空白区域也不起作用。 我想,因为我把标题设置为附件,它会忽略空格。 – Jesse 2009-06-19 12:51:27
bufferedReader = new BufferedReader(new FileReader(zipLocation));
除了Servlet/JSP问题,这一行将以100%的确定性破坏您的数据。它会尝试使用默认的平台编码将二进制数据解释为文本,这意味着文件中大约一半的字节被替换为“未知字符”。
字节和字符串不是一回事!
我也建议使用普通的servlet,并认为Robert Munteanu's answer是正确的,但是您也可以在JSP中执行此操作。问题不是添加的空白,而是隐式变量“out”是JSPWriter的一个实例,Writer是用于字符的,而不是字节。尝试使用response.getOutputStream()和正确的,这应该工作。你会得到一个异常,说别人已经得到了OutputStream,但你可以忽略它。
但正如我所说的,使用Servlet会更干净。
您的servlet代码不起作用,因为您正在输出您的流到response.getWriter()
,正如其他人指出的那样,对于字符数据。我引述的Javadoc:
PrintWriter getWriter() throws IOException
返回一个PrintWriter对象,可以发送字符文本到客户端。该PrintWriter的使用)由getCharacterEncoding(返回的字符编码
不仅如此,但你甚至不写字节数组Writer
,你写的ByteArrayOutputStream.toString()
,也做了字符转换的结果〜
你想用response.getOutputStream(),是这样的:
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
然后你的文件的字节内容写入。
而且,看在上帝的份上,不要使用Reader来处理二进制数据。 – 2009-06-19 13:24:45