本教學的主要亮點:
下載檔案是相當簡單的,涉及以下步驟。
response.setHeader(「Content-Disposition」, 「inline; filename=」 + fileName);//通過「內聯」瀏覽器將嘗試顯示內容到瀏覽器中(圖片,PDF,文字,...)。對於其他內容型別,檔案將直接下載。
完整實施例在下面討論。
使用到以下技術:
現在讓我們開始
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yiibai.springmvc</groupId> <artifactId>Spring4MVCFileDownloadExample</artifactId> <packaging>war</packaging> <version>1.0.0</version> <name>Spring4MVCFileDownloadExample Maven Webapp</name> <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> </project>
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" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Spring 4 MVC File Download Example</title> <link href="<c:url value='/static/css/bootstrap.css' />" rel="stylesheet"></link> <link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link> </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' />">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> </body> </html>
現在構建war(在前面的Eclipse教學)或通過Maven的命令列( mvn clean install)。部署 war 到Servlet3.0容器。或:
開啟瀏覽器,瀏覽 http://localhost:8080/Spring4MVCFileDownloadExample
點選第二個連結。外部檔案應被下載。
點選第一個連結。內部檔案[這是一個PDF]應該顯示在瀏覽器中,這是由於 Content-Disposition: inline. 通過內聯,如果內容可以通過瀏覽器顯示,它會顯示它在瀏覽器中。
現在從內聯更改內容處置備註。構建並部署。點選第一個連結。這個時候您應該看到 PDF檔案被下載。
就這樣,完成!
下載程式碼:http://pan.baidu.com/s/1c1lmeL6