HTTP status is 404 when trying to download a file from the server where tomcat runs

Hi guys,

I have some code that generates small zip archives on the server in a temp folder. I want the user to download these archives right after they are generated and then deleted.

In order to download them I wrote a code like this:

    // obviously this line is simplified for this post
    File file = new File("C:\\work\\studio-projects\\scope-fb\\temp\\result.zip");

    if (!file.exists()) {
        throw new FileNotFoundException(file.getAbsolutePath());
    }

    SimpleFileDataProvider simpleFileDataProvider = new SimpleFileDataProvider(file.getAbsolutePath());

    ExportFormat exportFormat =
            new ExportFormat("Content-Disposition = attachment", "zip");
    AppConfig.createExportDisplay(this).show(simpleFileDataProvider, "result.zip", exportFormat);

I got an exception from running the above code:

RuntimeException: Unable to download file 'C:\work\studio-projects\scope-fb\temp\result.zip': HTTP status is 404

Here’s the code stack:

java.lang.RuntimeException: Unable to download file 'C:\Users\andrei\Downloads\EDSmith&SonsLtd--112e9d01-5e6c-c90f-3d63-8ee99087bcd1--15-01-2019--21-25-45-548.zip': HTTP status is 404
at com.haulmont.cuba.gui.export.SimpleFileDataProvider.provide(SimpleFileDataProvider.java:103)
at com.vaadin.server.StreamResource.getStream(StreamResource.java:143)
at com.haulmont.cuba.web.toolkit.ui.CubaFileDownloader.handleConnectorRequest(CubaFileDownloader.java:109)
at com.vaadin.server.ConnectorResourceHandler.handleRequest(ConnectorResourceHandler.java:90)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1435)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:361)
at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:324)
at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:210)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:107)
at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:73)
at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

Thank you in advance,
Andrei

Hi Andrei

SimpleFileDataProvider allows you to download files only from a set of predefined folders listed in the cuba.download.directories application property. So add this property to your app.properties file with your folder after the defaults:

cuba.download.directories=${cuba.tempDir};${cuba.logDir};C:\\work\\studio-projects\\scope-fb\\temp

Regards,
Konstantin

1 Like

Hi Konstantin,

I’ve followed your steps and I got the same error.

I’ve created a test project (82.2 KB) in order for you to reproduce it.

In PropertyManager file I’ve updated the cuba.download.directories property, please update it according to your environment (I’ve hardcoded the path to the resources folder). In resources folder there is an archive named testFile.zip which should be downloaded.

Then log in as admin, go on the upper buttons tab -> Application -> Screen -> click on download button.

Thank you in advance,
Andrei

You cannot override the property this way. In a config interface, you can define your own property, bu if you need to specify a value to a framework property, follow this instruction.

In your case, it’s as simple as adding the line to app.properties which I suggested above.