我的页面上有一个下载链接可以正常工作,但它不会刷新/重定向我的页面。这是我的代码。
@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,但它给出了与上面代码相同的结果。 任何建议都会有所帮助
答案 0 :(得分:8)
您无法下载文件并进行刷新/重定向。 我会尝试解释原因。请求流程如下所示:
其中黄色圆圈是您的控制器。当您返回视图名称时,前端控制器会查找相应的视图模板(只需jsp,tiles或其他,具体取决于已配置的视图解析器)获取响应并将生成的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"。什么都不会改变。
答案 1 :(得分:3)
你可以:
response.setHeader("Refresh", "1; url = index");
在URL响应后1秒后刷新页面:"索引"。
答案 2 :(得分:1)
不会。浏览器在新窗口中打开ms-excel contentType
,或者您会收到下载提示。启动下载的页面永远不会有机会处理重定向或页面转换。
如果需要下载+页面刷新,JavaScript函数可以启动下载并将用户引导到下一页,该页面可能会说“您的下载将很快开始”或类似的内容。
答案 3 :(得分:0)
您可以在下载后调用javascript函数向您提交控制器并显示其他页面。
答案 4 :(得分: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
函数引用here
答案 5 :(得分:0)
我使用以下结构来解决我的问题。该函数提交表单并返回,换句话说,您下载文件并刷新上一个链接。使用此解决方案,您甚至可以使用某些模板渲染来显示和隐藏消息错误,在我的情况下,我使用的是 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>