【问题标题】:How to create a file with content and download it with THYMELEAF如何创建包含内容的文件并使用 THYMELEAF 下载
【发布时间】:2020-09-17 22:35:24
【问题描述】:

我正在使用 thymeleaf 开发一个 Spring Boot 项目,我需要创建一个文件并在上面放置一些行,然后将其发送给用户下载。

@PostMapping("/filegenerator")
public String createFile(@ModelAttribute("page") Page page, Model model) {
    List<String> lines = new ArrayList<String>();

    //Some code ..........

    lines.forEach(l->{
        System.out.println(l);
    });

    //Here I need to create a file with the List of lines

    //And also put some code to download it        

    return "filegenerator";
}

【问题讨论】:

  • 请分享更多信息。这个文件是什么(文本文件?图片?pdf?)?它只能由这个单个用户下载吗?是否有任何时间限制,在此之后文件不再可下载(也许在 1 小时后保留此文件只会浪费磁盘空间?)?您是在某个云中运行您的应用程序还是对对象存储桶具有其他类型的访问权限?
  • 感谢您的评论。文件的类型是 sql 脚本(.sql),是的,只有该用户可以下载,他将填写表格并提交,他将获得文件下载。只是本地和即时我不需要云或存储

标签: java spring-boot thymeleaf eclipse-jee


【解决方案1】:

因此,如果您想返回一个文件,您可能希望将其流式传输以限制使用的内存量(或者至少这可能是 Spring 框架创建者的推理)。在您的情况下,我了解该文件相当小,实际上不必在任何地方保留。根据上传的表格,它只是一次下载,对吧?

所以这种方法适用于我的电脑:

@PostMapping("/filegenerator")
public void createFile(HttpServletResponse response) throws IOException {
    List<String> lines = Arrays.asList("line1", "line2");
    InputStream is = new ByteArrayInputStream(lines.stream().collect(Collectors.joining("\n")).getBytes());
    IOUtils.copy(is, response.getOutputStream());
    response.setContentType("application/sql");
    response.setHeader("Content-Disposition", "attachment; filename=\"myquery.sql\"");
    response.flushBuffer();
}

注意content-disposition 标头。它明确指出您不想在浏览器中显示该文件,而是希望将其作为文件下载,myquery.sql 是要下载的文件的名称。

【讨论】:

  • 是的,它可以按我的意愿完美运行.. 但是它给出了一个例外java.lang.IllegalStateException: getOutputStream() has already been called for this response .. 有什么可做的吗?
  • 恐怕我帮不了你。我没有得到那个例外。我将不得不看到更多的代码,比如这个函数的最终版本现在是什么样的?
【解决方案2】:

@Kamil janowski

这就是现在的样子

@PostMapping("/filegenerator")
public String createFile(@ModelAttribute("page") Page page, Model model,HttpServletResponse response) throws IOException{

    List<String> lines = new ArrayList<String>();
    if(page.getTables().get(0).getName()!="") {
    List<String> output = so.createTable(page.getTables());
    output.forEach(line -> lines.add(line));
    }
    if(page.getInserttables().get(0).getName()!="") {
        List<String> output = so.insert(page.getInserttables());
        output.forEach(line -> lines.add(line));
    }
    if(page.getUpdatetables().get(0).getName()!="") {
        List<String> output = so.update(page.getUpdatetables());
        output.forEach(line -> lines.add(line));
    }

    lines.forEach(l->{
        System.out.println(l);
    });

    InputStream is = new ByteArrayInputStream(lines.stream().collect(Collectors.joining("\n")).getBytes());
    IOUtils.copy(is, response.getOutputStream());
    response.setContentType("application/sql");
    response.setHeader("Content-Disposition", "attachment; filename=\"myquery.sql\"");
    response.flushBuffer();

    model.addAttribute("page", getPage());
    return "filegenerator";
}       

【讨论】:

  • 可能是返回类型的原因吧?您不能同时返回文件和网站。每个方法只有一种返回类型。在该注释上,您可以添加 Location 标头以将用户重定向到不同的网站
  • 啊,好吧,我会尽力做到这一点.. 非常感谢你拯救了我的一天
猜你喜欢
  • 2023-03-25
  • 2023-01-14
  • 2021-11-14
  • 1970-01-01
  • 2020-09-13
  • 2015-07-01
  • 1970-01-01
  • 2023-01-27
  • 1970-01-01
相关资源
最近更新 更多