java JSP 下载 - 应用程序/八位字节流
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1936615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSP download - application/octet-stream
提问by Hubert Perron
I have a page in JSP that list some file that could be downloaded by a user. Thoses files are not on the local server, they are on a remote file server.
我在 JSP 中有一个页面,其中列出了一些用户可以下载的文件。这些文件不在本地服务器上,它们在远程文件服务器上。
When the user click to download a file, the webserver connect via TCP to the file server. The web server download the file and create a HTTP response for the client.
当用户点击下载文件时,网络服务器通过 TCP 连接到文件服务器。Web 服务器下载文件并为客户端创建 HTTP 响应。
Here is my code:
这是我的代码:
<%@page language="java"%>
<%@page import="sun.misc.Request"%>
<%@page import="listing.ClientTCPStockage"%>
<%@page import="java.net.InetAddress"%>
<%
out.clearBuffer();
String nomFichier = request.getParameter("fichier");
String adresseStockage = request.getParameter("adresseStockage");
ClientTCPStockage clientStockage = new ClientTCPStockage(InetAddress.getByName(adresseStockage), 2004);
byte donneeFichier[] = clientStockage.getDonneesFichier(nomFichier);
response.setHeader("Content-Disposition", "attachment;filename=\"" + nomFichier + "\"");
response.setHeader("Content-Type", "application/octet-stream;");
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Length", String.valueOf(donneeFichier.length));
for(int i = 0; i < donneeFichier.length; i++){
out.write(donneeFichier[i]);
}
%>
This is working perfectly fine for text-based file, like .csv or normal .txt but It doesnt work for other type like .mp3 or .jpeg.. the files end up corrupt.
这对于基于文本的文件(如 .csv 或普通 .txt)非常有效,但不适用于其他类型(如 .mp3 或 .jpeg)。文件最终会损坏。
I think there is a problem with my encoding but I can't find where..
我认为我的编码有问题,但我找不到在哪里..
Here is the HTTP Header response:
这是 HTTP 标头响应:
HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Disposition: attachment;filename="test.mp3"
Accept-Ranges: bytes
Content-Type: application/octet-stream;
Content-Length: 5387668
Date: Sun, 20 Dec 2009 18:52:18 GMT
Thanks.
谢谢。
回答by BalusC
JSP is a view technology. Everything outside the scriptlets <% %>will be printedto the response, including whitespace characters such as newlines. It would surely corrupt binary files.
JSP 是一种视图技术。脚本之外的所有内容都<% %>将打印到响应中,包括换行符等空白字符。它肯定会损坏二进制文件。
You could trim the whitespace in the JSP file, but scriptlets are discouraged since a decade and nowadays considered bad practice. Raw Java code belongs in Java classes, not in JSP files. The real solution is to use a Servletfor this.
您可以修剪 JSP 文件中的空格,但 10 年来不鼓励使用 scriptlet,现在被认为是不好的做法。原始 Java 代码属于 Java 类,而不属于 JSP 文件。真正的解决方案是为此使用 a Servlet。
Create a class which extends HttpServlet, implement the doGet()method, move the Java code from the JSP file into this method, map this servlet on a certain url-patternand your problem should disappear. You can find herea basicexample of such a servlet.
创建一个类extends HttpServlet,实现该doGet()方法,将 JSP 文件中的 Java 代码移动到该方法中,将该 servlet 映射到某个对象上url-pattern,您的问题应该会消失。您可以在此处找到此类 servlet的基本示例。
Apart from this problem is that you're storing the entire file in a byte[]instead in an InputStream. I am not sure what your ClientTCPStockageactually is doing, but I'd suggest to fix that as well. This because every byteof a byte[]costs effectively one byte of JVM's memory. Imagine that you have 128MB of JVM memory and that there are more than 10 users concurrently running this piece code with a file of larger than 12.8MB. Yes, OutOfMemoryError.
除了这个问题之外,您将整个文件存储byte[]在一个InputStream. 我不确定你ClientTCPStockage实际上在做什么,但我建议也解决这个问题。这是因为每byte一个都byte[]有效地消耗了一个字节的 JVM 内存。想象一下,您有 128MB 的 JVM 内存,并且有 10 多个用户同时运行这个文件大于 12.8MB 的片段代码。是的,OutOfMemoryError。
回答by Bozho
If forced to use jsp (and not a servlet), you may take a look at this how-to
如果被迫使用jsp(而不是servlet),你可以看看这个how-to
It uses the ServletOutputStream, which is more appropriate for binary content, rather than a JspWriter.
它使用ServletOutputStream更适合二进制内容的 ,而不是JspWriter。
Also note the settings for trimming the whitespaces.
还要注意修剪空格的设置。

