Open PDF file on mobile devices

Hello,

I try to open a PDF file in a browser that I get from a database as a stream. It works well on my Laptop, but when I try to open the PDF file on a mobile device it doesn’t work. (“source not found”).

Here is my code:

Kunde kunde = new KundeDAO().find(Authentication.getUser().name());

StreamSource streamSource = new StreamSource() {
public InputStream getStream() {
byte bas = (byte) kunde.getPDF();
if (bas != null) {
return new ByteArrayInputStream(bas);
} else {
return null;
}
}
};

if (streamSource.getStream() != null) {
StreamResource resource = new StreamResource(streamSource, “”);
resource.setMIMEType(“application/pdf”);
resource.getStream().setParameter(
“Content-Disposition”,
“attachment; filename=” );

        Window window = new Window();
        window.setWidth("90%");
        window.setHeight("90%");

        BrowserFrame e = new BrowserFrame();
        
        e.setWidth("100%");
        e.setHeight("100%");
        e.setSource(resource);
        
        window.setContent(e);
        window.center();
        window.setModal(true);
        this.getUI().addWindow(window);
    } 

Maybe someone can help me!?

Thanks Christian

What’s the mobile device? iOS or Android?
Chrome for Android does not have an integrated PDF viewer, so tap the link a longer time and download.
Did you have a look at FileDownloader in the API?

HTH, Best,
–Enver

Thanks for your reply!

I tested the app on an Anroid device.

I had a look at the FileDownloader. And here is the changed the code:

Kunde kunde = new KundeDAO().find(Authentication.getUser().name());

StreamSource streamSource = new StreamSource() {
public InputStream getStream() {
byte bas = (byte) kunde.getPDF();
if (bas != null) {
return new ByteArrayInputStream(bas);
} else {
return null;
}
}
};

Resource res = new StreamResource(streamSource, “name.pdf”);
FileDownloader fileDownloader = new FileDownloader(res);
fileDownloader.extend(buttonLoadPDF);

Now it works and I can download the file. But I got an Exception:

Nov 04, 2016 12:37:17 PM com.vaadin.server.DefaultErrorHandler doDefault
SCHWERWIEGEND:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Eine vorhandene Verbindung wurde vom Remotehost geschlossen
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:396)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:344)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:421)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:409)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:97)
at com.vaadin.server.DownloadStream.writeResponse(DownloadStream.java:306)
at com.vaadin.server.FileDownloader.handleConnectorRequest(FileDownloader.java:163)
at com.vaadin.server.ConnectorResourceHandler.handleRequest(ConnectorResourceHandler.java:90)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1100)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:687)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: Eine vorhandene Verbindung wurde vom Remotehost geschlossen
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(Unknown Source)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(Unknown Source)
at sun.nio.ch.IOUtil.write(Unknown Source)
at sun.nio.ch.SocketChannelImpl.write(Unknown Source)
at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:124)
at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101)
at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:172)
at org.apache.coyote.http11.InternalNioOutputBuffer.writeToSocket(InternalNioOutputBuffer.java:139)
at org.apache.coyote.http11.InternalNioOutputBuffer.addToBB(InternalNioOutputBuffer.java:197)
at org.apache.coyote.http11.InternalNioOutputBuffer.access$000(InternalNioOutputBuffer.java:41)
at org.apache.coyote.http11.InternalNioOutputBuffer$SocketOutputBuffer.doWrite(InternalNioOutputBuffer.java:320)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:121)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:256)
at org.apache.coyote.Response.doWrite(Response.java:491)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:391)
… 31 more

Maybe you can help me!?

Thanks!

Christian

And the exception is only thrown on the Android device. On my laptop it is fine.

This now is an exception that occurs in the guts of your Tomcat.
Either that or the Android device is closing the connection even though not all bytes were received yet.
Seems to happen to others as well: http://stackoverflow.com/questions/2953550/servlet-ioexception-when-streaming-a-byte-array

Mind that above Tomcat is a version 5.5 – are you going with the latest version?
Is using a different server (e.g. jetty) an option for you?

Could there be any firewall issue, do you control the network where the server and the client is connected to 100% yourself?
http://stackoverflow.com/questions/4629704/if-a-tomcat-server-says-client-aborted-and-the-client-says-premature-eof-w

People here found they only needed their Java version - so please make sure you’re running the latest version there as well if at all possible.
http://touchtipps.de/internal-exception-java-io-ioexception-eine-vorhandene-verbindung-wurde-vom-remotehost-geschlossen/

Hope to give you an idea, but sorry, not a known working solution.

Best Regards,
–Enver

Hi, Actually we are having a very similar issue. Vaadin 7.6.8 Tomcat 8.0.37 Java 8. Do we have any progress about this problem @Christian Hüppe ?

Best Regards,
Mihaly

http://stackoverflow.com/questions/4629704/if-a-tomcat-server-says-client-aborted-and-the-client-says-premature-eof-w

Maybe this solution helps for naughty clients:
“I was having similar problem while ago and I solved it by not using BufferedReader but reading one byte at a time and put the read in a try-catch for EOFException. Hope this helps.”

Best,
–Enver