【发布时间】:2019-01-17 18:34:38
【问题描述】:
我有一个非常奇怪的问题,我找不到解决方案。
我有一个简单的测试 servlet,它在响应中流式传输一个小的 pdf 文件:
public class TestPdf extends HttpServlet implements Servlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
File file = new File(getServletContext().getRealPath("/lorem.pdf"));
response.setContentType("application/pdf");
ServletOutputStream out = response.getOutputStream();
InputStream in = new FileInputStream(file);
byte[] bytes = new byte[10000];
int count = -1;
while ((count = in.read(bytes)) != -1) {
out.write(bytes, 0, count);
}
in.close();
out.flush();
out.close();
}
}
如果我用浏览器、curl、wget 调用 servlet url,一切都很好,但是当我用这样的简单 TCL 脚本调用它时:
#!/usr/bin/tclsh8.5
package require http;
set testUrl "http://localhost:8080/test/pdf"
set httpResponse [http::geturl "$testUrl" -channel stdout]
文件的开头有一个“2000”字符串会损坏 pdf。
这个问题似乎与 Tomcat 或 JDK 版本无关,因为我能够在我的开发环境 (Ubuntu 16.04) 上使用 JDK 1.5.0_22 Tomcat 5.5.36 和 JDK 1.8.0_74 和 Tomcat 8.5.15 重现它.
【问题讨论】:
-
没用过TCL,不就是http代码200加个0然后你的文件吗?
-
感谢您的评论。我只是尝试将HTTP响应代码更改为201,但“2000”仍然相同。
-
您是否尝试过使用您的 TCL 脚本访问“已知良好”的 URL(例如 stackoverflow.com/robots.txt)?这样您就可以确定问题是来自 Java 代码还是 TCL。
-
好的,我尝试使用示例 PDF (unec.edu.az/application/uploads/2014/12/pdf-sample.pdf) 并且下载的文件是正确的,所以问题与 Java/Tomcat 相关...
-
servlet 是否可能使用分块传输编码,而您的脚本不支持这种情况?在分块传输编码中,数据以块的长度为前缀(在 ASCII 中编码为十六进制,因此 2000 表示块为 8192 字节)以块的形式发送,然后是 CRLF 序列,然后是 8192 字节的数据,然后是CRLF,然后是下一个块,等等。
标签: java tomcat servlets tcl activetcl