I have problem with file being downloaded from a mobile device is recognised as unknown.
Below is the code i have used, it works on a PC browser but when I try to access the app via a mobile device, the file gets downloaded as unknown and eventually the download will be unsuccessful.
After investigating i am getting the following error on the server log:
Oct 07, 2014 12:11:47 PM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE:
ClientAbortException: java.net.SocketException: Connection reset
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:346)
at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:306)
at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:101)
at com.vaadin.server.DownloadStream.writeResponse(DownloadStream.java:310)
at com.vaadin.server.FileDownloader.handleConnectorRequest(FileDownloader.java:158)
at com.vaadin.server.ConnectorResourceHandler.handleRequest(ConnectorResourceHandler.java:83)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1371)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:238)
at com.vaadin.addon.touchkit.server.TouchKitServlet.service(TouchKitServlet.java:58)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263)
at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:178)
at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:62)
at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:118)
at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462)
at org.apache.coyote.http11.InternalOutputBuffer.flush(InternalOutputBuffer.java:119)
at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:781)
at org.apache.coyote.Response.action(Response.java:170)
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:341)
… 31 more
The code that i have provided works but you will have to check if your app is not connecting to a proxy server.
In order to solve this problem:
For iOS it does not allow you to initialize the download, you will have to open the file in a new tab: e.g:
Link link = new Link(caption, new StreamResource(yourStreamSource));
link.setTargetName("_blank");
For chrome on the Android it does not work as there is a bug with the Android native file downloader. For more info refer to this ticket
http://dev.vaadin.com/ticket/13822
I am not too familiar with IOS developement, but i have read about ISO native app have their own specific storage area only, only the app has access to. I think by design Apple lock down on storage area on the phone I am not 100% sure.
It depends on your requirement, if your app is web base then FileDownloader is not appropriate as Safari browser does not have the ability to download files from the web, the best you can do is open the file on the browser.