Spring4 MVC文件下載實例
這篇文章將向您展示如何使用Spring MVC4執行文件下載,我們將看到應用程序從文件系統內部以及外部文件下載文件。
本教程的主要亮點:
下載文件是相當簡單的,涉及以下步驟。
創建一個InputStream到文件用於下載。
查找MIME類型下載文件的內容。
–可以是application/pdf, text/html,application/xml,image/png等等。將內容類型與上述發現的MIME類型響應(HttpServletResponse)。
response.setContentType(mimeType);針對以上找到MIME類型設置內容長度。
response.setContentLength(file.getLength());//length in bytes爲響應設置內容處理標頭。
response.setHeader(「Content-Disposition」, 「attachment; filename=」 + fileName); //隨着「附件」文件將下載。可能會顯示一個「另存爲」基於瀏覽器的設置對話框。response.setHeader(「Content-Disposition」, 「inline; filename=」 + fileName);//通過「內聯」瀏覽器將嘗試顯示內容到瀏覽器中(圖片,PDF,文本,...)。對於其他內容類型,文件將直接下載。
從InputStream中複製字節響應到 OutputStream。
一旦複製完成後,關閉輸入輸出流。
完整實施例在下面討論。
使用到以下技術:
- Spring 4.2.0.RELEASE
- Bootstrap v3.3.2
- Maven 3
- JDK 1.7
- Tomcat 8.0.21
- Eclipse JUNO Service Release 2
現在讓我們開始
項目結構
在pom.xml中聲明依賴關係
<properties>
<springframework.version>4.2.0.RELEASE</springframework.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.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>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>Spring4MVCFileDownloadExample</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<finalName>Spring4MVCFileDownloadExample</finalName>
</build>
創建控制器
package com.yiibai.springmvc.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.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 String INTERNAL\_FILE="irregular-verbs-list.pdf";
private static final String EXTERNAL\_FILE\_PATH="C:/mytemp/SpringMVCHibernateManyToManyCRUDExample.zip";
@RequestMapping(value={"/","/welcome"}, method = RequestMethod.GET)
public String getHomePage(ModelMap model) {
return "welcome";
}
/\*
\* Download a file from
\* - inside project, located in resources folder.
\* - outside project, located in File system somewhere.
\*/
@RequestMapping(value="/download/{type}", method = RequestMethod.GET)
public void downloadFile(HttpServletResponse response, @PathVariable("type") String type) throws IOException {
File file = null;
if(type.equalsIgnoreCase("internal")){
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
file = new File(classloader.getResource(INTERNAL\_FILE).getFile());
}else{
file = new File(EXTERNAL\_FILE\_PATH);
}
if(!file.exists()){
String errorMessage = "Sorry. The file you are looking for does not exist";
System.out.println(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){
System.out.println("mimetype is not detectable, will take default");
mimeType = "application/octet-stream";
}
System.out.println("mimetype : "+mimeType);
response.setContentType(mimeType);
/\* "Content-Disposition : inline" will show viewable types \[like images/text/pdf/anything viewable by browser\] right on browser
while others(zip e.g) will be directly downloaded \[may provide save as popup, based on your browser setting.\]\*/
response.setHeader("Content-Disposition", String.format("inline; filename=\\"" + file.getName() +"\\""));
/\* "Content-Disposition : attachment" will be directly download, may provide save as popup, based on your browser setting\*/
//response.setHeader("Content-Disposition", String.format("attachment; filename=\\"%s\\"", file.getName()));
response.setContentLength((int)file.length());
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
//Copy bytes from source to destination(outputstream in this example), closes both streams.
FileCopyUtils.copy(inputStream, response.getOutputStream());
}
}
該控制器包括兩個文件。一個文件是內部應用(內部資源),和其他文件位於外部的應用程序的文件系統。您的項目一定要改變外部文件的路徑。僅用於演示的目的,我們已在路徑一個額外的路徑變量(內部/外部)。我們正在使用Spring FileCopyUtils工具類流從源複製到目的地。
配置
package com.yiibai.springmvc.configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.yiibai.springmvc")
public class HelloWorldConfiguration extends WebMvcConfigurerAdapter{
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/\*\*").addResourceLocations("/static/");
}
}
初始化
package com.yiibai.springmvc.configuration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>\[\] getRootConfigClasses() {
return new Class\[\] { HelloWorldConfiguration.class };
}
@Override
protected Class<?>\[\] getServletConfigClasses() {
return null;
}
@Override
protected String\[\] getServletMappings() {
return new String\[\] { "/" };
}
}
添加視圖
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Welcome to FileDownloader Example
Click on below links to see FileDownload in action.<br/><br/>
<a href="<c:url value='/download/internal' />">Download This File (located inside project)</a>
<br/>
<a href="<c:url value='/download/external' />">Download This File (located outside project, on file system)</a>
</div>
構建,部署和運行應用程序
現在構建war(在前面的Eclipse教程)或通過Maven的命令行( mvn clean install)。部署 war 到Servlet3.0容器。或:
打開瀏覽器,瀏覽 http://localhost:8080/Spring4MVCFileDownloadExample
點擊第二個鏈接。外部文件應被下載。
點擊第一個鏈接。內部文件[這是一個PDF]應該顯示在瀏覽器中,這是由於 Content-Disposition: inline. 通過內聯,如果內容可以通過瀏覽器顯示,它會顯示它在瀏覽器中。
現在從內聯更改內容處置備註。構建並部署。點擊第一個鏈接。這個時候您應該看到 PDF文件被下載。
就這樣,完成!