Spring MVC sample application for downloading files


        

In this article, we are going to show you how to implement file download functionality in a Spring MVC application. The solution is similar to the one described in the article: Send files from servlet to client for downloading, but is implemented in a Spring MVC application.

The following picture depicts workflow of the sample application we are going to build:

application workflow

Project structure (Eclipse project):

project structure of FileDownloadSpringMVC application

The file to be downloaded in this application is SpringProject.zip file which resides in the downloads directory which is relative to the application’s directory.

1. Code of download page

Create index.jsp file under WebContent directory with the following HTML code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ 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 Page</ title >
</ head >
< body >
     < center >
         < h2 >< a href = "/download.do" >Click here to download file</ a ></ h2 >
     </ center >
</ body >
</ html >

This page simply shows a link “Click here to download file” with URL points to the relative path: download.do. We’ll configure Spring controller class to handle this URL.


2. Code of Spring controller class

Create FileDownloadController.java file under the source package net.codejava.spring with the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package net.codejava.spring;
 
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.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
@Controller
@RequestMapping ( "/download.do" )
public class FileDownloadController {
     
     /**
      * Size of a byte buffer to read/write file
      */
     private static final int BUFFER_SIZE = 4096 ;
             
     /**
      * Path of the file to be downloaded, relative to application's directory
      */
     private String filePath = "/downloads/SpringProject.zip" ;
     
     /**
      * Method for handling file download request from client
      */
     @RequestMapping (method = RequestMethod.GET)
     public void doDownload(HttpServletRequest request,
             HttpServletResponse response) throws IOException {
 
         // get absolute path of the application
         ServletContext context = request.getServletContext();
         String appPath = context.getRealPath( "" );
         System.out.println( "appPath = " + appPath);
 
         // construct the complete absolute path of the file
         String fullPath = appPath + filePath;      
         File downloadFile = new File(fullPath);
         FileInputStream inputStream = new FileInputStream(downloadFile);
         
         // get MIME type of the file
         String mimeType = context.getMimeType(fullPath);
         if (mimeType == null ) {
             // set to binary type if MIME mapping not found
             mimeType = "application/octet-stream" ;
         }
         System.out.println( "MIME type: " + mimeType);
 
         // set content attributes for the response
         response.setContentType(mimeType);
         response.setContentLength(( int ) downloadFile.length());
 
         // set headers for the response
         String headerKey = "Content-Disposition" ;
         String headerValue = String.format( "attachment; filename=\"%s\"" ,
                 downloadFile.getName());
         response.setHeader(headerKey, headerValue);
 
         // get output stream of the response
         OutputStream outStream = response.getOutputStream();
 
         byte [] buffer = new byte [BUFFER_SIZE];
         int bytesRead = - 1 ;
 
         // write bytes read from the input stream into the output stream
         while ((bytesRead = inputStream.read(buffer)) != - 1 ) {
             outStream.write(buffer, 0 , bytesRead);
         }
 
         inputStream.close();
         outStream.close();
 
     }
}

This is a typical Spring controller class which is annotated by Spring MVC annotation types. The method doDownload() will receive requests from the client, read the file on server and send it to the client for downloading. Note that, unlike traditional Spring controller’s methods, the method doDownload()does not return a view name, because our purpose is to send a file to the client. The method exits as soon as the file is completely transferred to the client.

Recommended Book: Getting started with Spring Framework


3. Code of Spring configuration file

Create spring-mvc.xml file under WebContent\WEB-INF directory with the following content:

1
2
3
4
5
6
7
8
9
10
11
12
13
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "http://www.springframework.org/schema/beans"
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context = "http://www.springframework.org/schema/context"
     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">
 
     < context:component-scan base-package = "net.codejava.spring" />
 
     <!-- your beans declaration goes here -->
</ beans >

This is a deadly simple Spring configuration file which tells the framework to scan the package net.codejava.spring for annotated types (element <context:component-scan />). Of course your application will have some bean definitions, but for the purpose of this application, such configuration is enough to work.

 

Related Course: The Java Spring Tutorial


4. Code of web.xml

The Spring dispatcher servlet is configured to handle requests in the web.xml file as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<? xml version = "1.0" encoding = "UTF-8" ?>
< web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xmlns = "http://java.sun.com/xml/ns/javaee"
     xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     id = "WebApp_ID" version = "3.0" >
     < display-name >FileDownloadSpringMVC</ display-name >
     < servlet >
         < servlet-name >SpringController</ servlet-name >
         < servlet-class >org.springframework.web.servlet.DispatcherServlet</ servlet-class >
         < init-param >
             < param-name >contextConfigLocation</ param-name >
             < param-value >/WEB-INF/spring-mvc.xml</ param-value >
         </ init-param >
         < load-on-startup >1</ load-on-startup >
     </ servlet >
 
     < servlet-mapping >
         < servlet-name >SpringController</ servlet-name >
         < url-pattern >*.do</ url-pattern >
     </ servlet-mapping >
</ web-app >

 Recommended Book: Spring in Action


5. Required jar files

Add the following jar files into the WebContent\WEB-INF\lib directory:

    1. commons-logging-1.1.1.jar
    2. spring-beans-3.2.1.RELEASE.jar
    3. spring-context-3.2.1.RELEASE.jar
    4. spring-core-3.2.1.RELEASE.jar
    5. spring-expression-3.2.1.RELEASE.jar
    6. spring-web-3.2.1.RELEASE.jar
    7. spring-webmvc-3.2.1.RELEASE.jar

The Commons Logging jar files can be downloaded from Apache Commons Logging, other jar files come from Spring framework 3.2.1 RELEASE download.

 

Related Course: The Java Spring Tutorial


6. Testing the application

Deploy the application on localhost Tomcat server, type the following URL into browser’s address bar:

http://localhost:8080/FileDownloadSpringMVC/

The download page is displayed:

test download page

Click on the link, the browser will ask to download the file:

download dialog

You can download Eclipse project for this application as well as deployable WAR file in the attachment section below.

NOTES: One may ask why not just putting a file somewhere on the server and give the users a link to download it? Of course that will work, however that is a static way. By handling the file to be downloaded programmatically, we can obtain the following benefits:

    • Delivering the files dynamically, based on user’s requests.
    • Controlling access to the files: who can download and when the download is available.
    • Hiding the actual location of files on the server.


Recommended Book: Spring in Practice

### 下载 Xcode 支持的 iOS 18.2 版本 为了下载并安装适用于 iOS 18.2 的 Xcode 支持文件,开发者需要遵循特定的操作流程来确保其开发环境能够适配最新的 iOS 设备版本。以下是关于如何操作的相关说明: #### 配置 Xcode 和 DeviceSupport 文件 Xcode 中的 `DeviceSupport` 文件夹位于路径 `/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport`[^1]。此目录存储了用于调试运行最新 iOS 版本设备所需的必要支持文件。 当新的 iOS 测试版或正式版发布时,Apple 可能不会立即更新 Xcode 来包含这些新版本的支持文件。因此,在某些情况下,可能需要手动获取和配置对应于目标 iOS 版本(如 iOS 18.2)的 `DeviceSupport` 文件。 #### 手动添加 DeviceSupport 文件的方法 如果当前使用的 Xcode 不支持 iOS 18.2,则可以通过以下方式解决: 1. **查找官方资源**:访问 Apple 开发者网站或其他可信渠道,寻找与 iOS 18.2 对应的 `DeviceSupport` 文件包。 2. **解压并放置文件**:将下载到的 `.dmg` 或其他形式的压缩包中的内容复制至上述指定路径下的 `DeviceSupport` 文件夹中。 3. **重启 Xcode**:完成文件部署之后重新启动 IDE,以便加载新增加的内容及其关联功能。 另外值得注意的是,对于更深入的技术细节或者遇到具体问题时寻求解答途径之一便是利用内置文档系统;例如通过按下键盘上的 Alt 键再点击函数名称(像 didMoveToParentViewController 这样的方法),即可调阅有关该 API 更详尽的信息描述以及实例演示等内容[^2]。 ```bash # 示例命令行操作以验证是否存在对应的iOS版本支持文件 ls /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport | grep "18.2" ``` 以上脚本可以帮助确认本地已有的 Xcode 是否已经包含了针对 iOS 18.2 的支持情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值