Spring 4 MVC Download File from Server

By Yashwant Chavan, Views 56191, Date 21-Dec-2016

In this tutorial, you will learn how to download a file using Spring 4 MVC application. This example will help how to download different files like PDF, TEXT, ZIP from the server location.

tags spring

Spring 4 Eclipse project set up

Spring 4 MVC Download File from Server - Eclipse project Setup

Tools and Technologies

  1. Apache Maven 3.0.4
  2. JDK 1.8
  3. Spring core, Spring webmvc, and Spring context (4.1.4.RELEASE)
  4. Javax Servlet (3.1.0)

pom.xml

As we are using Maven project. Let's define the spring 4 specific maven dependencies.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.technicalkeeda</groupId>
    <artifactId>Spring4Examples</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <name>Spring4Examples</name>
    <description></description>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <properties>
        <spring.version>4.1.4.RELEASE</spring.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>
    </dependencies>
</project>

Spring 4 Application Configuration

@Configuration annotation imports the Spring configuration. @Configuration objects are managed as Spring beans within the container, imported configurations are used to injected using @Autowired or @Inject.

@ComponentScan is equivalent to <context:component-scan base-package="..." used to lookup the beans and components classes in the spring context.

@EnableWebMvc annotation is used to enable Spring MVC.

To declare a bean, simply annotate a method with the @Bean annotation. When JavaConfig encounters such a method, it will execute that method and register the return value as a bean within a BeanFactory.

package com.technicalkeeda.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@ComponentScan(basePackages = "com.technicalkeeda")
@EnableWebMvc
public class ApplicationConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

}

WebApplicationInitializer Configuration

Earlier we used to define web.xml to declare the dispatcher related configurations. Now we are using 100% code base (annotation and java config ) approach to doing the application configuration.

WebApplicationInitializer interface is implemented in Servlet 3.0+, which is used to configure the ServletContext programmatically rather than traditional web.xml-based approach.

package com.technicalkeeda.configuration;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class ApplicationInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext container) throws ServletException {

        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(ApplicationConfig.class);
        ctx.setServletContext(container);

        ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));

        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
    }

}

File Download Controller

Let's create a simple controller class DownloadController and annotate it with @Controller. The @Controller annotation indicates that a particular class serves the role of a controller.

Now add downloader() method along with @RequestMapping annotation. The dispatcher will scan such annotated classes for mapped methods and detect the respected @RequestMapping annotation.

@Autowired ServletContext - ServletContext is the configuration object which is created when web application is started. It holds information about different initialization parameters which is configured in web application.

ServletContext.getRealPath(String path) method is used to get the real path of the resource. In our case we used to get the real path of the /WEB-INF/downloads folder.

ServletContext.getMimeType(String file) method returns the MIME type of the specified file, or null if the MIME type is not known. As we are downloading different files from server, So have to know the MIME type of the respected file.

Add an HTTP response header called as "Content-Disposition" and provide its value "attachment; filename=fileName" where fileName is name of the file e.g. hello.zip, hello.pdf etc.

Once you get the FileInputStream, Which helps you to obtain input bytes from a respected file. Then use OutputStream.write(byte[] b, int off, int len) method to write an array or part of an array of bytes to the OutputStream.

Finally close all the stream resources using close() method.

package com.technicalkeeda.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class DownloadController {
    @Autowired
    ServletContext context;

    @RequestMapping("/download/{fileName:.+}")
    public void downloader(HttpServletRequest request, HttpServletResponse response,
        @PathVariable("fileName") String fileName) {
        try {
            String downloadFolder = context.getRealPath("/WEB-INF/downloads");
            File file = new File(downloadFolder + File.separator + fileName);

            if (file.exists()) {
                String mimeType = context.getMimeType(file.getPath());

                if (mimeType == null) {
                    mimeType = "application/octet-stream";
                }

                response.setContentType(mimeType);
                response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
                response.setContentLength((int) file.length());

                OutputStream os = response.getOutputStream();
                FileInputStream fis = new FileInputStream(file);
                byte[] buffer = new byte[4096];
                int b = -1;

                while ((b = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, b);
                }

                fis.close();
                os.close();
            } else {
                System.out.println("Requested " + fileName + " file not found!!");
            }
        } catch (IOException e) {
            System.out.println("Error:- " + e.getMessage());
        }
    }
}

Default Page (index.jsp)

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Download File Using Spring 4 Mvc!!!</title>
    </head>

    <body>
        <h2><a href="download/hello.zip">Download hello.zip</a> | <a href="download/hello.txt">Download hello.txt</a> | <a href="download/hello.pdf">Download hello.pdf</a></h2>
    </body>

    </html>

Output

Enter the URI http://localhost:8080/Spring4Examples in your browser, It will render the index.jsp page. To download respected files from server, click on each link. Refer below images for more details.

Download ZIP File

Spring 4 MVC Download Zip File from Server

Download Text File

Spring 4 MVC Download TXT File from Server

Download PDF File

Spring 4 MVC Download Pdf File from Server
Yashwant Chavan

Yashwant Chavan

Hi there! I am founder of technicalkeeda.com and programming enthusiast. My skills includes Java,J2EE, Spring Framework, Nodejs, PHP and lot more. If you have any idea that you would want me to develop? Lets connect: yashwantchavan@gmail.com