我有一个要求,我需要从网站上下载PDF.PDF需要在代码中生成,我认为这将是freemarker和像iText这样的PDF生成框架的组合.有更好的方法吗?
但是,我的主要问题是如何允许用户通过Spring Controller下载文件?
当我尝试从服务器下载260MB的大文件时,我收到此错误:java.lang.OutOfMemoryError: Java heap space.我确定我的堆大小小于252MB.有没有办法在不增加堆大小的情况下下载大文件?
如何在不解决此问题的情况下下载大文件?我的代码如下:
String path= "C:/temp.zip";
response.addHeader("Content-Disposition", "attachment; filename=\"test.zip\"");
byte[] buf = new byte[1024];
try {
File file = new File(path);
long length = file.length();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
ServletOutputStream out = response.getOutputStream();
while ((in != null) && ((length = in.read(buf)) != -1)) {
out.write(buf, 0, (int) length);
}
in.close();
out.close();
Run Code Online (Sandbox Code Playgroud) 我尝试下载文件.该操作由ajax()发布请求触发.请求以json格式将数据发送到控制器.控制器生成文件(字节)并将其发回.
java脚本:
function getLicenseFile() {
$.ajax({
type: 'POST',
url: '<%=request.getContextPath()%>/licenses/rest/downloadLicenseFile',
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
data: ko.mapping.toJSON(licenseModel),
success: function (data) {
console.log("in sucess")
},
error:function (xhr, ajaxOptions, thrownError){
console.log("in error")
}
});
}
Run Code Online (Sandbox Code Playgroud)
控制器:
@RequestMapping(value = "/licenses/rest/downloadLicenseFile", method = RequestMethod.POST)
@ResponseStatus(value=HttpStatus.OK)
@ResponseBody
public void createLicenseFile(@Valid @RequestBody License license, HttpServletResponse response) throws Exception {
logger.debug("Contoller License in: "+ license);
byte[] licensedata = licenseEncodeDefaultService.createLicenseFile(license);
logger.debug("licenseData: " + new String(licensedata));
response.setHeader("Content-Disposition", "attachment; filename=\"" + license.getCustomer() + ".license\"");
response.getOutputStream().write(licensedata);
response.flushBuffer();
}
Run Code Online (Sandbox Code Playgroud)
问题:
*浏览器应该打开一个下载框,但它不会发生
*响应是在错误中处理的:ajax函数的一部分(但是http状态是OK)
那么我错了什么或者这样做的正确方法是什么?
我测试HttpResponse#flushBuffer及PrintWriter#flush上Tomcat 7下方,但它似乎是回应,而忽略了他们比尽快冲洗过线的内容符合市场预期.
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
pw.println("say hi now");
pw.flush();
response.flushBuffer();
try {
Thread.sleep(5000);
} catch (Exception e) {
}
pw.println("say bye in 5 seconds");
}
}
Run Code Online (Sandbox Code Playgroud)
在延迟之后,浏览器一起显示"hi"和"bye".这是不正当行为还是打算?
@编辑
根据@Tomasz Nurkiewicz我的建议,我再次测试,curl然后问题就消失了.似乎标准的浏览器和tcp/ip …
java ×3
controller ×1
download ×1
file ×1
javascript ×1
jquery ×1
servlets ×1
spring ×1
spring-mvc ×1
tomcat ×1
tomcat7 ×1