This post shows you how to implement File Download using Spring MVC 4. We will see file download for file internal to application as well external file from file system.
Create Controller
package com.npf.controller;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection;
import java.nio.charset.Charset;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class FileDownloadController {
private static final Logger logger = LoggerFactory.getLogger(FileDownloadController.class);
@RequestMapping(value={"/","/download"}, method = RequestMethod.GET)
public String getHomePage(ModelMap model) {
return "download";
}
@RequestMapping(value="/download/internal/{filename:.+}", method = RequestMethod.GET)
public void downloadFileInternal(HttpServletResponse response,@PathVariable("filename") String filename) throws IOException {
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
File file = new File(classloader.getResource(filename).getFile());
if(!file.exists()){
String errorMessage = "Sorry. The file you are looking for does not exist";
logger.info(errorMessage);
OutputStream outputStream = response.getOutputStream();
outputStream.write(errorMessage.getBytes(Charset.forName("UTF-8")));
outputStream.close();
return;
}
String mimeType = URLConnection.guessContentTypeFromName(file.getName());
if(mimeType == null){
logger.info("mimetype is not detectable, will take default");
mimeType = "application/octet-stream";
}
System.out.println("mimetype : "+mimeType);
response.setContentType(mimeType);
//will direct opened in browser
//response.setHeader("Content-Disposition", String.format("inline; filename=\"" + file.getName() +"\""));
response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getName()));
response.setContentLength((int)file.length());
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
FileCopyUtils.copy(inputStream, response.getOutputStream());
}
@RequestMapping(value="/download/external/{filename}", method = RequestMethod.GET)
public void downloadFileExternal(HttpServletResponse response,@PathVariable("filename") String filename) throws IOException {
File dir = new File(System.getProperty("catalina.home") + File.separator + "tmpFiles");
File file = new File(dir.getAbsolutePath() + File.separator + filename);
if(!file.exists()){
String errorMessage = "Sorry. The file you are looking for does not exist";
logger.info(errorMessage);
OutputStream outputStream = response.getOutputStream();
outputStream.write(errorMessage.getBytes(Charset.forName("UTF-8")));
outputStream.close();
return;
}
String mimeType = URLConnection.guessContentTypeFromName(file.getName());
if(mimeType == null){
logger.info("mimetype is not detectable, will take default");
mimeType = "application/octet-stream";
}
System.out.println("mimetype : "+mimeType);
response.setContentType(mimeType);
//will direct opened in browser
//response.setHeader("Content-Disposition", String.format("inline; filename=\"" + file.getName() +"\""));
response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getName()));
response.setContentLength((int)file.length());
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
FileCopyUtils.copy(inputStream, response.getOutputStream());
}
}
This Controller involves two files. One file is internal to application (inside resources), and other file is located on file system external to application. Be sure to change external file path for your project. Only for demonstration purpose, we have included an extra path variable(internal/external) in path. We are using Spring
FileCopyUtils
utility class to copy stream from source to destination.
Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.npf.controller"/>
<mvc:annotation-driven />
<mvc:resources location="/resources/" mapping="/resources/**"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Add View
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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</title>
</head>
<body>
<div class="form-container">
<h1>Welcome to FileDownloader Example</h1>
Click on below links to see FileDownload in action.<br/><br/>
<a href="<c:url value='/download/internal/mongoDB-in-action.pdf' />">
Download This File (located inside project)</a> <br/>
<a href="<c:url value='/download/external/Java RESTful Web Service.pdf' />">
Download This File (located outside project, on file system)</a>
</div>
</body>
</html>
Open browser and browse at http://localhost:8080/springmvc-download-file/
Clink on First link. Internal file should be downloaded.
the source code link :
springmvc-download-file
ref link :
http://websystique.com/springmvc/spring-mvc-4-file-download-example/ ref link :
http://stackoverflow.com/questions/16332092/spring-mvc-pathvariable-with-dot-is-getting-truncated ref link:
http://www.codejava.net/frameworks/spring/spring-mvc-sample-application-for-downloading-files ref link :
http://crunchify.com/simplest-spring-mvc-hello-world-example-tutorial-spring-model-view-controller-tips/ ref link :
http://howtodoinjava.com/spring/spring-mvc/spring-mvc-download-file-controller-example/