我想编写代码来下载保存在我的系统中的文件
这是我的代码:
在控制器类中,我有以下映射
@RequestMapping(value = "/processFile", method = RequestMethod.POST)
public @ResponseBody ModelAndView downloadFileProcess(
@RequestParam("file") File originalFile,
@RequestParam("action") String action, HttpServletResponse response) {
ModelAndView model = new ModelAndView();
model.setViewName("error");
System.out.println("");
System.out.println("Action: "+action);
model.addObject("message", "Action:" + action);
try {
utility.downloadFile(originalFile, response);
message = "The file was downloaded successfully";
} catch (IOException e) {
e.printStackTrace();
message = "The process failed due to following reason: "
+ e.getMessage();
} catch (Exception e) {
e.printStackTrace();
message = "The process failed due to following reason: "
+ e.getMessage();
}
model.setViewName("success");
model.addObject("message", message);
return model;
}
实用程序类中的方法如下:
public void downloadFile(File originalFile, HttpServletResponse response)
throws FileNotFoundException, IOException {
response.setHeader("Content-Disposition", "attachment; filename="
+ originalFile.getName());
IOUtils.copy(
new FileInputStream(new File(String.valueOf(originalFile))),
response.getOutputStream());
response.flushBuffer();
}
由于我想下载文件,我必须使用response.getoutputstream()
。
但是我得到以下例外:
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:482) at org.springframework.web.servlet.view.RedirectView.sendRedirect(RedirectView.java:548) at org.springframework.web.servlet.view.RedirectView.renderMergedOutputModel(RedirectView.java:279) at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) 2015-05-31 12:42:07.547 ERROR 15009 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet dispatcherServlet threw exception java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.catalina.connector.Response.getWriter(Response.java:678) at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213) at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:104) at org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView.render(ErrorMvcAutoConfiguration.java:187) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748) at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604) at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543) at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:467) at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:342) at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:434) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:205) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) 2015-05-31 12:42:07.551 ERROR 15009 --- [nio-8080-exec-4] o.a.c.c.C.[Tomcat].[localhost] : Exception Processing ErrorPage[errorCode=0, location=/error] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748) at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604) at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543) at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:467) at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:342) at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:434) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:205) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.catalina.connector.Response.getWriter(Response.java:678) at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213) at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:104) at org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView.render(ErrorMvcAutoConfiguration.java:187) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) ... 27 common frames omitted
答案 0 :(得分:4)
您希望单个请求有两种不同的响应:
这没有意义。它只能是一个或另一个。如果您希望请求下载文件,则不应返回ModelAndView。该方法应返回void。
此外,不应使用import java.util.Scanner;
import java.util.Random;
public class cominback{
public static void main(String args[]){
Scanner key = new Scanner(System.in);
System.out.println(" please enter a password:");
String x = key.nextLine();
System.out.println("Connfirm your password:");
String y = key.nextLine();
if ( x == null)
System.out.println("please restart the program:");
if (x != y)
System.out.println("wrong password");
if (x == y )
System.out.println("you are logged in");
}
}
注释该方法。
AFAIK,下载网站同时生成成功页面和文件下载的方式只是响应包含iframe的HTML页面,并让iframe指向实际文件下载的URL。
答案 1 :(得分:2)
HttpServletResponse.getOutputStream()
IllegalStateException
。HttpServletResponse.getWriter()
IllegalStateException
2之间的一个关键用法区别是getOutputStream()用于向客户端发送二进制数据,getWriter()用于发送编码的文本数据。
底线:上述两种方法中的任何一种都应该用于将数据刷新到客户端,而不是两者都是,并且开发人员必须确保正确处理它,特别是在处理非servlet类。
答案 2 :(得分:0)
这是PrintWriter.getWriter()
和HttpServletResponse.getOutputStream()
的问题,两者都试图将数据刷新到客户端。
您已经在使用response.getOutputStream()
和response.flushBuffer()
,这意味着您正在尝试将内容刷新到客户端,最后当您的downloadFileProcess()返回时,Springs也尝试刷新内容使用PrintWriter.getWriter()
,所以你得到了
java.lang.IllegalStateException:getOutputStream()已经存在 呼吁这个回应
使用下面的代码将一些内容发送到客户端,而不会将您的方法视为无效,这应该会有所帮助。
String content = null;
IOUtils.copy(new FileInputStream(new File(String.valueOf(originalFile))), content );
PrintWriter out = response.getWriter();
out.println(content);
在旁注中,为什么你在开始时model.setViewName("error");
和model.addObject("message", "Action:" + action);
?我认为你不应该拥有它,因为你最终会压倒一切,或者它们更适合CATCH区块。
答案 3 :(得分:0)
我解决了这个问题:
ApplicationContext context = new FileSystemXmlApplicationContext();
Resource resource = context.getResource("file:" + exFile.getPath());
File file = new File(exFile.getPath());
try {
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
InputStream is = resource.getInputStream();
IOUtils.copy(is, response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}