Search code examples
javajsptomcatweb-applications

Java web app - downloaded file is unreadable


I'm developing a Java Web App on TomCat 9.0.29 (currently only on local 8080) and I would like to add the possibility to download a file. Here it is a simple download.jsp in which I try to download the imageimg.png that is on my Desktop. When i open this page on the browser it asks me to download or open the file as it is supposed to do. The problem is that the downloaded file is unreadable, even if its size is not 0. Why does it happen and how can i fix it?

Download.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String filename = "img.png";
    String filepath = "C:\\Users\\Utente\\Desktop\\";
    response.setContentType("APPLICATION/OCTET-STREAM");
    response.setHeader("Content-Disposition","attachment; filename=\"" + filename + "\"");

    java.io.FileInputStream fileInputStream=new java.io.FileInputStream(filepath + filename);

    int i;
    while ((i=fileInputStream.read()) != -1) {
        out.write(i);
    }
    fileInputStream.close();
%>

Size of the downloaded file

size on disk: 372KB
size of download: 556KB

Solution

  • Solved with File java class.

    <%@ page import="java.io.File" %>
    <%@ page import="java.io.PrintStream" %>
    <%@ page import="java.io.OutputStream" %>
    <%@ page import="java.io.FileInputStream" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%
        File file = new File("C:\\Users\\Utente\\Desktop\\img.png");
        response.setContentType("application/octet-stream");
        response.setContentLength((int) file.length());
        response.setHeader( "Content-Disposition",
                String.format("attachment; filename=\"%s\"", file.getName()));
    
        OutputStream out2 = response.getOutputStream();
        try (FileInputStream in = new FileInputStream(file)) {
            byte[] buffer = new byte[4096];
            int length;
            while ((length = in.read(buffer)) > 0) {
                out2.write(buffer, 0, length);
            }
        }
        out2.flush();
    %>
    

    Moreover, if you want to pass the filePath as a url parameter you can write something like this:

    Index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <a href="downloader.jsp?filePath=C://Users//Utente//Desktop//img.png">link</a>
    
    </body>
    </html>
    

    Downloader.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%
    
        String filePath = request.getParameter("filePath");
        File file = new File(filePath);
        response.setContentType("application/octet-stream");
        response.setContentLength((int) file.length());
        response.setHeader( "Content-Disposition",
                String.format("attachment; filename=\"%s\"", file.getName()));
    
        OutputStream out2 = response.getOutputStream();
        try (FileInputStream in = new FileInputStream(file)) {
            byte[] buffer = new byte[4096];
            int length;
            while ((length = in.read(buffer)) > 0) {
                out2.write(buffer, 0, length);
            }
        }
        out2.flush();
    %>