04. Download (Files, Streams...). Show PDFs. Anchor problem, Iframes

1. Introduction

It is important to download resources from the web (PDFs, CSVs, images..)

Let's follow these steps:


2. Prerequisites: Add dependencies

1. Add the reference to Apache commons-io in the build.gradle file


/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java library project to get you started.
 * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
 * User Manual available at https://docs.gradle.org/6.8/userguide/building_java_projects.html
 */

plugins {
    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
    id 'war'
}

repositories {
    // Use JCenter for resolving dependencies.
    jcenter()
}

dependencies {
    // Use JUnit test framework.
    testImplementation 'junit:junit:4.13'
    
    // JSP & SERVLETS
    compileOnly 'jakarta.servlet:jakarta.servlet-api:5.0.0'
    compileOnly 'jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.0.0'
    implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:2.0.0'
   
   //Apache
   implementation 'commons-io:commons-io:2.11.0' 
     
}


3. Option (1): Using Form

2. Create a Servlet ("DownloadServlet") that opens a File stream and redirects to the ServletOutputStream

package ximojsp;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;

import org.apache.commons.io.IOUtils;

import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * Dowload a resource
 */
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public DownloadServlet() {
		super();
		System.out.println("Creating Servlet");

		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String fileName = request.getParameter("filep");
		try {
                        response.setContentType("text/csv"); // or "application/pdf"
    		        response.setHeader("Content-disposition", "attachment; filename=hello.txt");
                        FileInputStream fileInputStream = new FileInputStream(fileName);
			ServletOutputStream outStrm=response.getOutputStream();
			IOUtils.copy(fileInputStream, outStrm);
			outStrm.close();
		} catch(Exception e) {
			e.printStackTrace();
			PrintWriter writer = response.getWriter();
			writer.println("<h1> Error downloading file </h1>");
			writer.println("<h2> Could not download the file " + fileName +"</h1>");
			writer.close();
		}
	}

}

To identify the content type and the name of file to be downloaded the look at the yellow highlited lines. (Take a look at Baelding for more details)

3. Create the index.html file to ask for the file

<!DOCTYPE html>
<html>
    <head>
     	<meta charset="UTF-8">
        <title>User login form</title>
    </head>
    <body>
        <!-- 
        <form action="login.jsp">
        <form action="helloServlet" method="post">
        --> 
        <form action="downloadServlet" method="post" target="_blank">
Please insert file: <input type="text" name="filep" /> <input type="submit" value="Download File" /> </form> </body> </html>

You should type the full path to the file. The target="_blank" is used to download the file in another page.

It is important to notice this sentence

response.setContentType("text/csv"); // or "application/pdf"


4. Option (2): Using an anchor instead of a form

The href of the anchor can only make requests with the method "get", so in the servlet should be added this method:

/**
 * Needed for href (only uses get)
 */
public void doGet(HttpServletRequest request, HttpServletResponse response) 
	    throws ServletException, IOException {
	    doPost(request, response);
}


The anchor element can be

<p><a id="myAnchor" href="downloadServlet?myIds=(1,2,3,4,5)" target="_blank"> prova link</a></p>

Where  ?myIds=(1,2,3,4,5) indicates a parameter that is not used in this case (only for exposing how to send parameters a request with method get)


If you want to download the file by clicking the anchor programmatically, take care! see Wolfss in stackoverflow ... 

$('#myAnchor').click();  //This is NOT working!!
$('#myAnchor')[0].click();  //This is working!! Note the "[0]"

You can use a button and by means of jquery, execute a click event on the anchor

The target of the anchor can be the id of an iframe instead of "_blank";

5. Option (3): Using an iframe

The "src" of the iframe has call to the servlet

<p><iframe="myIframe" src="downloadServlet?myIds=(1,2,3,4,5)"></iframe></p>


Comentarios

Entradas populares de este blog

15 Typescript (3) json ..

10. Some Javascript & JQuery concepts

14 Typescript (2) with jquery, bootstrap and other module stuff