展示如何使用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。
- 一旦复制完成后,关闭输入输出流。
内部文件下载:通过Thread.currentThread.getContextClassLoad()类来加载文件
//内部文件 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); file = new File(classLoader.getResource(INTERNAL_FILE).getFile());
获取文件类型mimeTyp:URLConnection.guessContentTypeFromName(file.getName())
String mimeType = URLConnection.guessContentTypeFromName(file.getName()); response.setContentType(mimeType);
输出文件类型/文件下载路径:
//文件类型 response.setContentType(mimeType); //文件地址 response.setHeader("Content-Disposition", String.format("inline; filename="" + file.getName() +""")); //文件大小 response.setContentLength((int)file.length());
通过FileCopyUtils.copy(springmvc)复制文件流下载输出:
InputStream inputStream = new BufferedInputStream(new FileInputStream(file)); FileCopyUtils.copy(inputStream, response.getOutputStream());
完整实施例在下面讨论。
pom.xml配置
<properties> <springVersion>4.3.5.RELEASE</springVersion> </properties> <dependencies> <!-- spring模块库 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springVersion}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springVersion}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springVersion}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --> <!-- transaction事务 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springVersion}</version> </dependency> <!-- Servlet dependencies --> <!-- servlet(HttpServletRequest,HttpServletResponse) --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/jstl/jstl --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <finalName>gugua14</finalName> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <warSourceDirectory>src/main/webapp</warSourceDirectory> <warName>gugua14</warName> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </pluginManagement> </build> </project>
HelloWorldConfiguration.java
package springmvc.configuration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ComponentScan; 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.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration @EnableWebMvc @ComponentScan(basePackages="springmvc") public class HelloWorldConfiguration extends WebMvcConfigurerAdapter{ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // TODO Auto-generated method stub //super.addResourceHandlers(registry); //设置静态目录 registry.addResourceHandler("/static/**").addResourceLocations("/static/"); } @Override public void configureViewResolvers(ViewResolverRegistry registry) { // TODO Auto-generated method stub //super.configureViewResolvers(registry); InternalResourceViewResolver viewReslover = new InternalResourceViewResolver(); viewReslover.setViewClass(JstlView.class); viewReslover.setPrefix("/WEB-INF/views/"); viewReslover.setSuffix(".jsp"); registry.viewResolver(viewReslover); } }
dispatcherServlet转发配置
package springmvc.configuration; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class HelloWorldIntializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { // TODO Auto-generated method stub return new Class[] {HelloWorldConfiguration.class}; } @Override protected Class<?>[] getServletConfigClasses() { // TODO Auto-generated method stub return null; } @Override protected String[] getServletMappings() { // TODO Auto-generated method stub return new String[] {"/"}; } }
controller代码
package 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.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 HelloWorldController { private static final String FILE_1 = "APICloud-basic-2.2.1.zip"; private static final String FILE_2 ="D:/download/APICloud-basic-2.2.1.zip"; @RequestMapping(value="/down", method=RequestMethod.GET) public String index() { return "index"; } @RequestMapping(value="/download/{type}", method=RequestMethod.GET) public void download(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(FILE_1).getFile() ); }else { //外部地址 file = new File(FILE_2); } //文件是否存在 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."); mimeType = "application/octet-stream"; } System.out.println("mimeType:" + mimeType); //输出类型 response.setContentType(mimeType); //mime协议:默认文件名 response.setHeader("Content-Disposition", String.format("inline: filename=""+file.getName()+""")); //mime协议:以附件形式下载 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()); } }
访问地址:http://localhost:8080/gugua14/down