【问题标题】:Spring - download file and redirectSpring - 下载文件并重定向
【发布时间】:2013-08-16 13:56:22
【问题描述】:

我的页面上有一个下载链接,它可以正常工作,但它不会刷新/重定向我的页面。这是我的代码。

@RequestMapping(method = RequestMethod.POST, params = "exportToXML")
public String exportToXML(HttpServletResponse response, Model model, @ModelAttribute(FILTER_FORM) ScreenModel form,
        BindingResult result, OutputStream out,
        HttpSession session) throws IOException {
    ZipOutputStream zipout;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();


        zipout = new ZipOutputStream(baos);
        ZipEntry ze = new ZipEntry("file.xml");
        zipout.putNextEntry(ze);
        zipout.write(string.getBytes());
        zipout.closeEntry();
        zipout.close();
        baos.close();


    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-disposition", "attachment; filename=xx.zip");
    response.getOutputStream().write(baos.toByteArray());
    response.getOutputStream().close();
    response.getOutputStream().flush();
    return VIEW_NAME;
}

我删除了一些不相关的代码,使其更短一些。我也尝试过使用@ResponseBody,但它给出的结果与上面的代码相同。 任何建议都会有所帮助

【问题讨论】:

    标签: spring redirect spring-mvc download zip


    【解决方案1】:

    您无法下载文件并进行刷新/重定向。 我会试着解释原因。请求流程如下所示:

    黄色圆圈是您的控制器。当您返回视图名称时,前端控制器会查找适当的视图模板(简单的 jsp、tile 或其他,具体取决于配置的视图解析器)获取响应并向其写入生成的 html(或非 html)代码。

    在您的情况下,您执行操作:

    response.getOutputStream().write(baos.toByteArray());
    response.getOutputStream().close();
    response.getOutputStream().flush();
    

    在此操作之后,spring 无法打开响应并将刷新的页面写入其中(因为您之前这样做过)。 因此,您可以将方法签名更改为:

    public void exportToXML(HttpServletResponse response, Model model, @ModelAttribute(FILTER_FORM) ScreenModel form,
            BindingResult result, OutputStream out,
            HttpSession session) throws IOException {
    

    并删除最后一个“返回 VIEW_NAME”。什么都不会改变。

    【讨论】:

      【解决方案2】:

      你可以:

      response.setHeader("Refresh", "1; url = index");
      

      这会在响应 URL:“index”后 1 秒后刷新页面。

      【讨论】:

      • 这不会为我刷新页面...我将 index 替换为我的控制器响应的 URL。怎么了?
      【解决方案3】:

      不会的。浏览器会在新窗口中打开ms-excel contentType,或者您会收到下载提示。启动下载的页面永远没有机会处理重定向或页面转换。

      如果需要下载 + 页面刷新,JavaScript 函数可以启动下载并将用户引导到下一页,该页面可以说“您的下载将很快开始”或类似的内容。

      【讨论】:

        【解决方案4】:

        您可以在下载后调用一个 javascript 函数提交给您的控制器,然后它们会显示不同的页面。

        【讨论】:

          【解决方案5】:

          我使用以下结构来解决我的问题。该功能提交表单并返回,换句话说,您下载文件并刷新上一个链接。使用这个解决方案,你甚至可以通过一些模板渲染来显示和隐藏消息错误,在我的例子中,我使用了 Thymeleaf

          为了使代码更具可读性,我删除了 Thymeleaf 标签。

          JS文件:

          function submitAndBack(formId) {
              let formDoc = document.getElementById(formId);
              formDoc.submit();
              sleep(1000).then(function() {
                  window.history.back();
              });
          }
          
          function sleep(milliseconds) {
              return new Promise(function (resolve) {
                  setTimeout(resolve, milliseconds);
              });
          }
          

          HTML 形式:

          <form id="myForm" method="POST" action="/some/url">
                <label for="inputText">Some info</label>
                <input id="inputText" name="inputText" type="text">
                <button onclick="submitAndBack('myForm')">
                    Submit
                </button>
          </form>
          

          【讨论】:

            【解决方案6】:

            LottaLava的回答中,我得到了解决类似问题的想法。

            在 JavaScript 中,表单提交后,我等待一秒半然后重新加载页面。等待时间是后端下载文件(此处为exportToXML)并返回响应然后在 JavaScript 中刷新页面的时间。

            form.submit();
            sleep(1500).then(function() {
                 document.location.reload();
            });
            

            这里form.submit() 调用控制器操作,在您的情况下为exportToXML

            sleep函数如下:

            function sleep(milliseconds) {
                return new Promise(function (resolve) {
                    setTimeout(resolve, milliseconds);
                });
            }
            

            sleep 函数指的是here

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-08-30
              • 2011-10-17
              • 2011-05-21
              • 2020-06-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多