7

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

@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,但它给出的结果与上面的代码相同。任何建议都会有所帮助

4

6 回答 6

9

您无法下载文件并进行刷新/重定向。我会试着解释原因。请求流程如下所示: 在此处输入图像描述

黄色圆圈是您的控制器。当您返回视图名称时,前端控制器会查找适当的视图模板(简单的 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”。什么都不会改变。

于 2013-08-16T18:11:47.617 回答
3

你可以:

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

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

于 2016-02-15T13:54:05.893 回答
2

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

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

于 2013-08-16T15:20:59.553 回答
1

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

于 2017-04-12T14:15:49.550 回答
1

我使用以下结构来解决我的问题。该函数提交表单并返回,换句话说,您下载文件并刷新上一个链接。使用此解决方案,您甚至可以使用某些模板渲染显示和隐藏消息错误,在我的例子中,我使用了 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>
于 2019-09-19T17:54:00.463 回答
0

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参考这里

于 2019-09-16T08:34:53.830 回答