上一文《SpringMVC上传文件的三种方式》中,我们知道有三种方式可以实现文件的上传,其中,使用Spring MVC框架可以做到这一点,因为Spring MVC为文件的上传提供了直接的支持,但需要依赖Apache提供Commons FileUpload组件jar包。
下面将继续和大家介绍使用Spring MVC框架来实现文件的上传和下载,本文将做一个项目案例来完整的使用Spring MVC框架实现文件的上传和下载。
一.文件上传概述
文件上传是项目开发中最常见的功能。为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器。
一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择。
Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。而Spring MVC则提供了更简单的封装。
Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。
本项目作为测试案例,在此我就不创建Maven项目了,我直接创建的是一个Dynamic Web Project(动态的web项目),采用Tomcat 8作为web服务器,我们需要在项目中引入以下jar包,如下图:
下面我们在WebContent/WEB-INF下创建一个content文件夹,用于放文件的上传、下载等jsp文件,下面我们创建uploadForm.jsp文件,演示Spring MVC的文件上传:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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=UTF-8"> <title>文件上传</title> </head> <body> <h2>文件上传</h2> <form action="upload" enctype="multipart/form-data" method="post"> <table> <tr> <td>文件描述:</td> <td><input type="text" name="description"></td> </tr> <tr> <td>请选择文件:</td> <td><input type="file" name="file"></td> </tr> <tr> <td><input type="submit" value="上传"></td> </tr> </table> </form> </body> </html>
负责上传文件的表单和一般表单有一些区别,负责上传文件的表单的编码类型必须是"multipart/form-data"。
我们在src下创建一个包"com.bijian.study.controller",然后创建一个FileUploadController类,用于实现文件的上传和下载功能。以下是负责上传文件的表单功能代码:
//上传文件会自动绑定到MultipartFile中 @RequestMapping(value="/upload",method=RequestMethod.POST) public String upload(HttpServletRequest request, @RequestParam("description") String description, @RequestParam("file") MultipartFile file) throws Exception { System.out.println(description); //如果文件不为空,写入上传路径 if(!file.isEmpty()) { //上传文件路径 String path = request.getServletContext().getRealPath("/images/"); //上传文件名 String filename = file.getOriginalFilename(); File filepath = new File(path,filename); //判断路径是否存在,如果不存在就创建一个 if (!filepath.getParentFile().exists()) { filepath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文件当中 file.transferTo(new File(path + File.separator + filename)); return "success"; } else { return "error"; } }
Spring MVC会将上传的文件绑定到MultipartFile对象中。MultipartFile提供了获取上传文件内容、文件名等方法。通过transferTo()方法还可以将文件存储到硬件中,MultipartFile对象中的常用方法如下:
a.byte[] getBytes():获取文件数据
b.String getContentType[]:获取文件MIME类型,如image/jpeg等
c.InputStream getInputStream():获取文件流
d.String getName():获取表单中文件组件的名字
e.String getOriginalFilename():获取上传文件的原名
f.Long getSize():获取文件的字节大小,单位为byte
g.boolean isEmpty():是否有上传文件
h.void transferTo(File dest):将上传文件保存到一个目录文件中
SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。在hbatis-servlet.xml进行配置文件如下:
<?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" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 注册RequestMappingHandlerMapping, RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver以提供对@RequestMapping,@ExceptionHandler等注解的支持 --> <mvc:annotation-driven /> <!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件, 如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean --> <context:component-scan base-package="com.bijian.study.controller" /> <!-- 视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 --> <property name="prefix"> <value>/WEB-INF/content/</value> </property> <!-- 后缀 --> <property name="suffix"> <value>.jsp</value> </property> </bean> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 上传文件大小上限,单位为字节(10MB) --> <property name="maxUploadSize"> <value>10485760</value> </property> <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 --> <property name="defaultEncoding"> <value>UTF-8</value> </property> </bean> </beans>部署FileUpload这个Web应用,在浏览器中输入如下URL来测试应用,输入文件描述信息并选择上传文件,如下图:
点上传按钮,这是已将上传的文件通过二进制保存到web服务器上去了,如下图:
二.使用对象接收上传文件
上面我们通过案例演示了Spring MVC上传文件,接下来,我们演示使用对象接收上传文件。
在实际项目的开发中,很多时候上传的文件会作为对象的属性被保存。SpringMVC的处理也非常的简单。
下面我们在content文件夹创建registerForm.jsp文件,演示接收文件上传:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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=UTF-8"> <title>用户注册</title> </head> <body> <h2>用户注册</h2> <form action="register" enctype="multipart/form-data" method="post"> <table> <tr> <td>用户名:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>请上传头像:</td> <td><input type="file" name="image"></td> </tr> <tr> <td><input type="submit" value="注册"></td> </tr> </table> </form> </body> </html>
我们在src下面创建一个名叫“com.bijian.study.dto”包,然后再创建一个User类,必须要实现序列化接口,如下案例代码:
package com.bijian.study.dto; import java.io.Serializable; import org.springframework.web.multipart.MultipartFile; /** * 域对象,实现序列化接口 */ public class User implements Serializable { private String username; private MultipartFile image; public User() { super(); } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public MultipartFile getImage() { return image; } public void setImage(MultipartFile image) { this.image = image; } }
我们在刚才创建的FileUploadController类继续写用于接收文件的上传和下载功能。以下是负责接收文件的表单功能代码:
@RequestMapping(value="/register") public String register(HttpServletRequest request, @ModelAttribute User user) throws Exception { System.out.println(user.getUsername()); //如果文件不为空,写入上传路径 if(!user.getImage().isEmpty()) { //上传文件路径 String path = request.getServletContext().getRealPath("/images/"); //上传文件名 String filename = user.getImage().getOriginalFilename(); File filepath = new File(path,filename); //判断路径是否存在,如果不存在就创建一个 if (!filepath.getParentFile().exists()) { filepath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文件当中 user.getImage().transferTo(new File(path + File.separator + filename)); //将用户添加到model //model.addAttribute("user", user); return "userInfo"; } else { return "error"; } }
在content文件夹下创建userInfo.jsp文件,该页面主要是文件的下载页面,如下jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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=UTF-8"> <title>文件下载</title> </head> <body> <h3>文件下载</h3> <a href="download?filename=${requestScope.user.image.originalFilename}">${requestScope.user.image.originalFilename }</a> </body> </html>
在浏览器中输入如下URL来测试应用,输入用户名并上传刚才上传的文件。如下图:
单击“注册”按钮上传文件,然后就会跳转到下载页面。如下图:
三.文件下载
上面我们通过案例演示了使用对象接收上传文件,接下来,我们演示Spring MVC的下载文件。
文件下载比较简单,直接在页面给出了一个超链接,该链接href的属性等于要下载文件的文件名,就可以实现文件下载了。但是如果该文件的文件名为中文文件名,在某些早起的浏览器上就会导致下载失败;如果使用最新的Firefox、Chrome、Opera、Safari则都可以正常下载文件名为中文的文件了。
SpringMVC提供了一个ResponseEntity类型,使用它可以很方便地定义返回的HttpHeaders和HttpStatus。以下代码演示文件的下载功能:
@RequestMapping(value="/download") public ResponseEntity<byte[]> download(HttpServletRequest request, @RequestParam("filename") String filename)throws Exception { //下载文件路径 String path = request.getServletContext().getRealPath("/images/"); File file = new File(path + File.separator + filename); HttpHeaders headers = new HttpHeaders(); //下载显示的文件名,解决中文名称乱码问题 String downloadFielName = new String(filename.getBytes("UTF-8"),"iso-8859-1"); //通知浏览器以attachment(下载方式)打开图片 headers.setContentDispositionFormData("attachment", downloadFielName); //application/octet-stream : 二进制流数据(最常见的文件下载)。 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED); }
download处理方法接收页面传递的文件名filename后,使用Apache Commons FileUpload组件的FileUtils读取项目的上传文件,并将其构建成ResponseEntity对象返回客户端下载。
使用ResponseEntity对象,可以很方便的定义返回的HttpHeaders和HttpStatus。上面代码中的MediaType,代表的是Internet Media Type,即互联网媒体类型,也叫做MIME类型。在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。HttpStatus类型代表的是Http协议中的状态。有关MediaType和HttpStatus类可以参考Spring MVC的API文档。
点击下载页面的超链接,显示文件正在下载,如下图所示:
PS:本文中的一些功能案例代码和配置文件不是很完整,下面附上完整代码
FileUploadController.java
package com.bijian.study.controller; import java.io.File; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.FileUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import com.bijian.study.dto.User; @Controller public class FileUploadController { //上传文件会自动绑定到MultipartFile中 @RequestMapping(value="/upload",method=RequestMethod.POST) public String upload(HttpServletRequest request, @RequestParam("description") String description, @RequestParam("file") MultipartFile file) throws Exception { System.out.println(description); //如果文件不为空,写入上传路径 if(!file.isEmpty()) { //上传文件路径 String path = request.getServletContext().getRealPath("/images/"); //上传文件名 String filename = file.getOriginalFilename(); File filepath = new File(path,filename); //判断路径是否存在,如果不存在就创建一个 if (!filepath.getParentFile().exists()) { filepath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文件当中 file.transferTo(new File(path + File.separator + filename)); return "success"; } else { return "error"; } } @RequestMapping(value="/register") public String register(HttpServletRequest request, @ModelAttribute User user) throws Exception { System.out.println(user.getUsername()); //如果文件不为空,写入上传路径 if(!user.getImage().isEmpty()) { //上传文件路径 String path = request.getServletContext().getRealPath("/images/"); //上传文件名 String filename = user.getImage().getOriginalFilename(); File filepath = new File(path,filename); //判断路径是否存在,如果不存在就创建一个 if (!filepath.getParentFile().exists()) { filepath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文件当中 user.getImage().transferTo(new File(path + File.separator + filename)); //将用户添加到model //model.addAttribute("user", user); return "userInfo"; } else { return "error"; } } @RequestMapping(value="/download") public ResponseEntity<byte[]> download(HttpServletRequest request, @RequestParam("filename") String filename)throws Exception { //下载文件路径 String path = request.getServletContext().getRealPath("/images/"); File file = new File(path + File.separator + filename); HttpHeaders headers = new HttpHeaders(); //下载显示的文件名,解决中文名称乱码问题 String downloadFielName = new String(filename.getBytes("UTF-8"),"iso-8859-1"); //通知浏览器以attachment(下载方式)打开图片 headers.setContentDispositionFormData("attachment", downloadFielName); //application/octet-stream : 二进制流数据(最常见的文件下载)。 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED); } }
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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=UTF-8"> <title>测试文件上传</title> </head> <body> 恭喜,您的上传文件成功! </body> </html>
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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=UTF-8"> <title>测试文件上传</title> </head> <body> 上传文件失败! </body> </html>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>SpringMVC</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> <!-- 监听容器事件,初始化和关闭Web应用上下文并调用ContextCleanupListener清理资源 --> </listener> <listener> <listener-class>org.springframework.web.context.ContextCleanupListener</listener-class> <!-- Web应用关闭时,清理ServletContext中spring相关的可销毁资源 --> </listener> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>hbatis</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--<init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/hbatis-servlet.xml</param-value> </init-param>--> <!-- 未配置时,SpringMVC会到WEB-INF目录下找${servlet-name}-servlet.xml --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hbatis</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
完整工程项目见附件。
相关推荐
以上就是使用 Spring MVC 实现文件上传和下载的基本步骤。实际应用中,你可能还需要考虑其他因素,比如文件大小限制、文件类型检查、异常处理、安全性(防止路径遍历攻击)等。通过这些方法,你可以构建一个完整的...
在Spring MVC框架中,实现文件上传和下载是常见的功能需求。以下将详细讲解如何使用Spring MVC来处理这两种操作,特别是图片的上传和多图片同时上传。 首先,为了启用Spring MVC对文件上传的支持,我们需要在配置...
通过阅读"Spring MVC 文件上传下载 后端 - Java.doc"文档,你可以深入理解如何在实际项目中实现这些功能,包括具体的代码示例、配置细节和最佳实践。这份文档可能会涵盖以上所有知识点,帮助开发者更好地掌握Spring ...
Spring MVC 是一个强大的Java Web开发框架,用于构建可维护、高性能和灵活的Web应用程序。它在Spring框架的基础上,为...开发者可以通过此副本学习和理解Spring MVC项目的组织方式,以及文件上传下载功能的实现细节。
总的来说,实现Spring MVC文件上传的进度条功能需要前端和后端的紧密配合。前端负责用户交互和进度信息的显示,后端则需处理分块上传、进度跟踪和异步响应。通过这样的方式,我们可以在不阻塞用户界面的情况下,提供...
在"ssm框架--spring mvc实现文件上传"这个项目中,我们将重点探讨如何在Spring MVC中实现实现文件上传的功能。 文件上传是Web应用中的常见需求,Spring MVC提供了便捷的API来处理这一任务。首先,你需要在表单中...
总的来说,这个项目展示了Spring MVC在实际应用中处理文件上传下载的基本流程,以及与IDEA的集成和项目构建过程。通过对源代码的学习和理解,开发者可以进一步掌握Spring MVC的核心特性和实践技巧,提升Web应用的...
在本文中,我们将深入探讨如何使用Spring MVC框架与Ajax技术...通过这些步骤,你可以实现一个简单的Spring MVC和Ajax文件上传功能。随着对Spring MVC和Ajax理解的深入,你可以根据实际需求进行更复杂的功能定制和优化。
本篇文章将深入探讨Spring MVC如何实现文件上传和下载。 ### 文件上传 1. **依赖配置**:在Spring MVC项目中,为了支持文件上传,需要引入Apache Commons FileUpload库,它提供了处理多部分HTTP请求的能力。在`pom...
在Spring MVC中实现文件上传并显示进度是一项常见的需求,特别是在用户需要等待较长时间的大型文件上传时。这个功能可以通过监听文件上传的进度并在前端实时更新来提升用户体验。下面将详细介绍如何利用Spring MVC...
spring mvc上传 下载ftp文件
总结来说,"文件上传下载(maven + spring mvc + jetty)"项目是一个使用现代Java Web技术实现的简单示例,展示了如何利用Maven构建、Spring MVC处理HTTP请求和Jetty作为轻量级服务器。通过对这些技术的掌握,开发者...
本书共计10章,分别介绍了快速搭建Spring Web应用、精通MVC结构、URL映射、文件上传与错误处理、创建Restful应用、保护应用、单元测试与验收测试、优化请求、将Web应用部署到云等内容,循序渐进地讲解了Spring MVC4...
以上就是使用Spring MVC实现文件上传和下载的基本流程。在实际应用中,你可能需要考虑更多的细节,比如错误处理、文件大小限制、文件存储策略(如云存储)等。这个例子中的`fileUpload`目录可能包含了上述示例中的源...
在Spring MVC框架中,文件上传是一项常见的功能,用于接收用户通过表单提交的文件数据。这一功能对于构建Web应用程序,尤其是那些需要用户交互并处理上传文件的系统来说至关重要。本项目提供了一个完整的、经过测试...
在开发过程中,可以通过其内置的Tomcat或Jetty服务器运行和测试项目,查看文件上传下载的效果。 综上所述,本项目通过IDEA和SpringMVC实现了文件的上传和下载功能,涵盖了文件操作、HTTP响应、MultipartFile处理等...
这篇文章将深入探讨如何在Spring MVC中实现文件上传,并基于提供的链接和文件名称列表进行详细解析。 首先,理解文件上传的基本流程至关重要。当用户在表单中选择一个或多个文件并提交时,这些文件的数据会被编码成...
然而,压缩包子文件的文件名称列表中有一个名为`ReverseProxy_windows_amd64.exe`的文件,这似乎与Spring MVC的文件上传和下载功能无关。它可能是一个反向代理软件的Windows 64位版本,通常用于负载均衡、安全或性能...