文件开头的其他"2000"字符串([32 30 30 30] 字节)



我有一个非常奇怪的问题,我找不到解决方案。

我有一个简单的测试 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();
}
}

如果我用浏览器调用servlet url,curl,wget,一切都很好,但是当我用这样的简单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 客户端处理此问题(而不是通过关闭 Tomcat POV 中的分块传输编码(,您需要省略-channel选项以http::geturl

package require http;
set testUrl "http://localhost:8080/test/pdf"
set httpResponse [http::geturl "$testUrl"]
fconfigure stdout -translation binary; # turn off auto-encoding on the way out
puts -nonewline stdout [http::data $httpResponse]

这应该正确地将分块的内容转换为一个部分。背景是,当我上次检查时,对分块内容的处理不适用于-channel选项。

我从未使用过TCL,但这是您如何编写通用文件下载servlet的方法:

public class DownloadServlet extends HttpServlet {
private final int BUFFER_SIZE = 10000;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
String filename = "test.pdf";
String pathToFile = "..../" + filename;
resp.setContentType("application/pdf");
resp.setHeader("Content-disposition", "attachment; filename=" + filename);
try(InputStream in = req.getServletContext().getResourceAsStream(pathToFile);
OutputStream out = resp.getOutputStream()) {
byte[] buffer = new byte[BUFFER_SIZE];
int numBytesRead;
while ((numBytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, numBytesRead);
}
}
}
}

希望这段代码对您有所帮助。

最新更新